As a software developer, you can’t run away from date manipulation. Almost every app a developer builds will have some component where date/time needs to be obtained from the user, stored in a database, and displayed back to the user.

Ask any programmer about their experience handling dates and timezones and they will probably share some war stories. Handling date and time fields is certainly not rocket science, but can often be tedious and error-prone.

There are hundreds of articles on the topic out there, however, most are either too academic focusing on nitty-gritty details, or they are too patchy providing short snippets of code without much explanation accompanying them. This in-depth guide to DateTime manipulation should help you understand the programming concepts and best practices relevant to time and date without having to browse through a sea of information on this topic.

Date manipulation libraries are only as good as your understanding of the fundamental concepts of time and date.

Date manipulation libraries are only as good as your understanding of the fundamental concepts of time and date.

In this article, I’m going to help you think clearly about date and time fields and suggest some best practices that can help you avoid date time hell. Here we will explore some of the key concepts that are necessary for manipulating date and time values correctly, formats that are convenient for storing DateTime values and transferring them over APIs, and more.

DateTime Libraries Help If You Understand Them Correctly

Date libraries help in many ways to make your life easier. They greatly simplify date parsing, date arithmetic and logical operations, and date formatting. You can find a reliable date library for both the front-end and the back-end to do most of the heavy lifting for you.

However, we often use date libraries without thinking about how date/time actually works. Date/time is a complex concept. The bugs that come up due to its incorrect understanding can be extremely difficult to understand and fix, even with the help of date libraries. As a programmer, you need to understand the basics and be able to appreciate the problems that date libraries solve to make the most out of them.

Also, date/time libraries can only take you so far. All date libraries work by giving you access to convenient data structures to represent a DateTime. If you are sending and receiving data through a REST API, you will eventually need to convert the date to a string and vice versa because JSON doesn’t have a native data structure to represent DateTime. The concepts I have outlined here will help you to avoid some of the common issues that might come up when doing these date-to-string and string-to-date transformations.

Note: Even though I have used JavaScript as the programming language discussed in this article, these are general concepts that apply to virtually all programming languages and their date libraries. So even if you’ve never written a line of JavaScript before, feel free to continue reading as I hardly assume any prior knowledge of JavaScript in the article.

Standardizing the Time

A DateTime is a very specific point in time. Let’s think about this. As I scribble this article, the clock on my laptop shows July 21 1:29 PM. This is what we call “local time”, the time that I see on wall clocks around me and on my wrist watch.

Give or take a few minutes, if I ask my friend that to meet me at a nearby cafe at 3:00PM, I can expect to see her there at roughly that time. Similarly, there wouldn’t be any confusion if instead I said, for example, “let’s meet in one and a half hours”. We routinely talk about time this way with people living in the same city or time zone.

Let’s think of a different scenario - I want to tell a friend living in Sweden that I want to talk to him at 5PM. I send him a message “Hey Anton, let’s talk at 5 PM”. I immediately get the response “Your time or my time?”

Anton tells me that he lives in the Central European Time Zone which is UTC+01:00. I live in UTC+5:45. This means that when it is 5pm where I live, it is 11:15UTC that translates to 12:15 in Uppsala, perfect for both of us.

Also, be aware of the difference between timezone (Central European Time) and time zone offset (UTC+05:45). Countries can decide to change their timezone offsets for Daylight Savings Time and for political reasons as well.

This problem of managing two different versions of the time, relative to the user and relative to a universally accepted standard is difficult, even more so in the world of programming where precision is key and even one second can make a huge difference. The first step towards solving these issues is to storing DateTime in UTC.

Standardizing the Format

Standardizing the time is wonderful because I only need to store the UTC time and as long as I know the timezone of the user, I can always convert to their time. Conversely, if I know a user’s local time and know their timezone, I can convert that to UTC.

But dates and times can be specified in many different formats. For the date, you could write “Jul 30th” or “30 July” or “7/30” (or 30/7, depending on where you live). For the time, you could write “9:30 pm” or “2130”.

Scientists all over the world came together to tackle this problem and decided on a format to describe time that we programmers really like because it’s short, it’s precise and it works. We like to call it ISO date format, which is a simplified version of the ISO-8601 extended format and it looks like this.

For 00:00 or UTC, we use “Z” instead, which means Zulu time, another name for UTC.

Date Manipulation and Arithmetic in JavaScript

Before we start with best practices, we will learn about date manipulation using JavaScript to get a grasp of the syntax and general concepts. Although we use JavaScript, you can adapt this information to your favorite programming language easily.

We will use date arithmetic to solve common date related problems that most developers come across.

My goal is to make you comfortable creating a date object from a string and extracting components out of one. This is something that a date library can help you with, but it’s always better to understand how it is done behind the scenes.

Once we’ve gotten our hands dirty with date/time, it is then easier to think about the problems we face, extract the best practices, and move ahead. If you want to skip to the best practices, feel free to do so, but I would highly recommend you to at least skim through the date arithmetic section below.

The JavaScript Date Object

Programming languages contain useful constructs to make our lives easier. The JavaScript Date object is one such thing. It offers convenient methods to get the current date and time, store a date in a variable, perform date arithmetic and format the date based on the user’s locale.

Due to differences between browser implementations and incorrect handling of DayLight Savings Time(DST), depending on the Date object for mission-critical applications is not recommended and you should probably be using a DateTime library like moment.

But for educational purposes, we will use the methods that the Date() object provides to learn how JavaScript handles DateTime.

Getting Current Date

var currentDate = new Date();

If you don’t pass anything to the Date constructor, the date object returned contains the current date and time.

You can then format it to extract only the date part as follows:

var currentDate = new Date();

var date = currentDate.getDate();
var month = currentDate.getMonth(); //Be careful! January is 0 not 1
var year = currentDate.getFullYear();

var dateString = date + "-" +(month + 1) + "-" + year;

Getting the Current Timestamp

If you instead want to get the current timestamp, you can create a new Date object and use the getTime() method.

var date = new Date();
var timestamp = date.getTime();
In JavaScript, a timestamp is the number of milliseconds that have passed since January 1, 1970.

If you don’t intend to support <IE8, you can use to directly get the timestamp without having to create a new Date object.

Parsing a Date

Converting a string to a JavaScript date object is done in different ways.

The Date object’s constructor accepts a wide variety of date formats:

var date = new Date("Wed, 27 July 2016 13:30:00");
var date = new Date("Wed, 27 July 2016 07:45:00 GMT");
var date = new Date("27 July 2016 13:30:00 GMT+05:45");

Note that you do not need to include the day of week because JS can determine the day of the week for any date.

You can also pass in the year, month, day, hours, minutes and seconds as separate arguments:

var date = new Date(2016, 6, 27, 13, 30, 0);

Of course, you can always use ISO date format:

var date = new Date("2016-07-27T07:45:00Z");

However, you can run into trouble when you do not provide the timezone explicitly!

var date = new Date("25 July 2016") // or
var date = new Date("July 25, 2016")

gives you 25 July 2016 00:00:00 local time.

If you use the ISO format, even if you give only the date and not the time and timezone, it will automatically accept the timezone as UTC.

This means that:

new Date("25 July 2016").getTime() !== new Date("2016-07-25").getTime()
new Date("2016-07-25").getTime() === new Date("2016-07-25T00:00:00Z").getTime()

Formatting a Date

Date formatting is tougher in Javascript because it doesn’t have standard date formatting functions like strftime in Python or PHP.

In PHP, the functionstrftime("Today is %b %d %Y %X", mktime(5,10,0,12,30,99)) gives you Today is Dec 30 1999 05:10:00.

You can use a different combination of letters preceded by ‘%’ to get the date in different formats.

If you are sure of the format you want to use, it is best to extract individual bits using the JavaScript functions we learnt above and create a string yourself.

var currentDate = new Date();
var date = currentDate.getDate();
var month = currentDate.getMonth(); 
var year = currentDate.getFullYear();

We can get the date in Month/Date/Year format as

var monthDateYear  = (month+1) + "/" + date + "/" + year;

The problem with this solution is that it can give an inconsistent length to the dates because some months and dates are single-digit and others double-digit. This can be problematic, for example, if you are displaying the date in a table column because the dates don’t line up.

We can address this by using a “pad” function that adds a leading 0.

function pad(n) {
    return n<10 ? '0'+n : n;

Now, we get the correct date in MM/DD/YYYY format using:

var mmddyyyy = pad(month + 1) + "/" + pad(date) + "/" + year;

If we want DD-MM-YYYY instead, the process is similar:

var ddmmyyyy = pad(date) + "-" + pad(month + 1) + "-" + year;

Let us up the ante and try to print the date in “Month Date, Year” format. We will need a mapping of month indexes to names:

var monthNames = [
  "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"

var dateWithFullMonthName = monthNames[month] + " " + pad(date) + ", " + year;

Some people like to display the date as 1st January, 2013. No problem, all we need is a helper function ordinal that returns 1st for 1, 12th for 12 and 103rd for 103 etc., and the rest is simple:

var ordinalDate = ordinal(date) + " " + monthNames[month] + ", " + year;

It is easy to determine the day of week from the date object, so let’s add that in:

var daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

ordinalDateWithDayOfWeek = daysOfWeek[currentDate.getDay()] + ", " + ordinalDate;

The bigger point here is, once you’ve got the numbers extracted from the date, the formatting is mostly related to strings.

Changing the Date Format

Once you know how to parse a date and format it, changing a date from one format to another is just a matter of combining the two.

For example, if you have a date in the format Jul 21, 2013 and wanted to change the format to 21-07-2013, it can be achieved like this:

var myDate = new Date("Jul 21, 2013");
var date = myDate.getDate();
var month = myDate.getMonth();
var year = myDate.getFullYear();

function pad(n) {
	return n<10 ? '0'+n : n

var ddmmyyyy = pad(date) + "-" + pad(month + 1) + "-" + year;

Using JavaScript Date Object’s Localization Functions

The date formatting methods we discussed above should work in most applications, but if you really want to localize the formatting of the date, I suggest you use the Date object’s toLocaleDateString() method.

var today = new Date().toLocaleDateString('en-GB', {  
	day : 'numeric',
	month : 'short',
	year : 'numeric'

gives us something like “26 Jul 2016”.

Changing the locale to ‘en-US’ gives “Jul 26, 2016” instead. Notice how the formatting changed, but the display options were still kept the same. Pretty awesome, huh?

It is a good habit to always pass the formatting options, even if the output looks fine on your computer. This can protect the UI from breaking in unexpected locales with really long month names or looking awkward because of short ones.

If I wanted the full month “July” instead, all I do is change the month parameter in the options to “long”. Javascript handles everything for me. For en-US, I now get July 26, 2016.

If you want the browser to automatically use the user’s locale, you can pass “undefined” as the first parameter.

If you want to show the numeric version of the date and don’t want to fuss with MM/DD/YYYY vs. DD/MM/YYYY for different locales, I suggest the following simple solution:

var today = new Date().toLocaleDateString(undefined, {
    month: 'numeric',
    year: 'numeric'

On my computer, this outputs “7/26/2016”. If you want to make sure that month and date have two digits, just change the options.

var today = new Date().toLocaleDateString(undefined, {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric'

This outputs “07/26/2016”. Sweet!

You can also use some other related functions to localize the way both time and date are displayed:

"4:21:38 AM" Display localized version of only time
now.toLocaleTimeString(undefined, {
    hour: '2-digit',
    minute: '2-digit',
    second: '2-digit'
"04:21:38 AM" Display localized time based on options provided
"7/22/2016, 4:21:38 AM" Display date and time for user’s locale
now.toLocaleString(undefined, {
	day: 'numeric',
	month: 'numeric',
	year: 'numeric',
	hour: '2-digit',
	minute: '2-digit',
"7/22/2016, 04:21 AM" Display localized date and time based on options provided

Calculating Relative Dates

Here’s an example of adding 20 days to a JavaScript Date (i.e., figuring out the date 20 days after a known date):

var date = new Date("July 20, 2016 15:00:00");
var nextDate = date.getDate() + 20;
var newDate = date.toLocaleString();

The original date object now represents a date 20 days after July 20th and newDate contains a localized string representing that date. On my browser, newDate contains “8/9/2016, 3:00:00 PM”.

Comparing Dates

As with everything else related to date, comparing dates has its own gotchas.

First, we need to create date objects. Fortunately, <, >, <=, and >= all work. So comparing July 19, 2014 and July 18, 2014 is as easy as:

var date1 = new Date("July 19, 2014");
var date2 = new Date("July 28, 2014");

if(date1 > date2) {
	console.log("First date is more recent");
} else {
	console.log("Second date is more recent");

Checking for equality is trickier, since two date objects representing the same date are still two different date objects and will not be equal. Comparing date strings is a bad idea because, for example, “July 20, 2014” and “20 July 2014” represent the same date but have different string representations. The snippet below illustrates the first point:

var date1 = new Date("June 10, 2003");
var date2 = new Date(date1);

var result = date1 == date2 ? "equal" : "not equal";

The variable result will have the value “not equal”.

This particular case can be fixed by comparing the integer equivalents of the dates (their timestamps) as follows:

date1.getTime() == date2.getTime()

I’ve seen this example in lots of places, but I don’t like it because you don’t create a date object from another date object usually. So I feel that the example is important from an academic point of view only. Also, this requires both Date objects to be referring to the exact same second, whereas you might only want to know if they refer to the same day or hour or minute.

Let’s look at a more practical example. You’re trying to compare whether the birthday the user has entered is the same as the lucky date you are getting from an API.

var userEnteredDateString = "12/20/1989"; // MM/DD/YY format
var dateStringFromAPI = "1989-12-20T00:00:00Z";

var userEnteredDate = new Date(userEnteredDateString)
var dateFromAPI = new Date(dateStringFromAPI);

var result = (userEnteredDate.getTime() == dateFromAPI.getTime());

if(result === true) {
} else {

Both represented the same date but unfortunately your user will not get the million dollars.

Here’s the problem: JavaScript always assumes the timezone to be the one that the browser provides it unless explicitly specified otherwise.

This means, for me, new Date(“12/20/1989”) will create a date 1989-12-20T00:00:00+5:45 or 1989-12-19T18:15:00Z which is not the same as 1989-12-20T00:00:00Z in terms of timestamp.

It’s not possible to change just the timezone of an existing date object, so our target is now to create a new date object but with UTC instead of local timezone.

We will ignore the user’s timezone and use UTC while creating the date object. There are two ways to do it:

  1. Create an ISO formatted date string from the user input date and use it to create a date object. Using a valid ISO date format to create a date object while making the intent of UTC vs local very clear.
var userEnteredDate = "12/20/1989";
var parts = userEnteredDate.split("/");

var userEnteredDateISO = parts[2] + "-" + parts[0] + "-" + parts[1];

var userEnteredDateObj = new Date(userEnteredDateISO + "T00:00:00Z");
var dateFromAPI = new Date("1989-12-20T00:00:00Z");

var result = userEnteredDateObj.getTime() == dateFromAPI.getTime();

This also works if you don’t specify the time since that will default to midnight (i.e., 00:00:00Z):

var userEnteredDate = new Date("1989-12-20");
var dateFromAPI = new Date("1989-12-20T00:00:00Z");
var result = userEnteredDate.getTime() == dateFromAPI.getTime();

Remember: If the date constructor is passed a string in correct ISO date format of YYYY-MM-DD, it assumes UTC automatically.

  1. JavaScript provides a neat Date.UTC() function that you can use to get the UTC timestamp of a date. We extract the components from the date and pass them to the function.
var userEnteredDate = new Date("12/20/1989");
var userEnteredDateTimeStamp = Date.UTC(userEnteredDate.getFullYear(), userEnteredDate.getMonth(), userEnteredDate.getDate(), 0, 0, 0);

var dateFromAPI = new Date("1989-12-20T00:00:00Z");
var result = userEnteredDateTimeStamp == dateFromAPI.getTime();

Finding the Difference Between Two Dates

A common scenario you will come across is to find the difference between two dates.

We discuss two use cases:

Finding the Number of Days Between Two Dates

Convert both dates to UTC timestamp, find the difference in microseconds and find the equivalent days.

var dateFromAPI = "2016-02-10T00:00:00Z";

var now = new Date();
var datefromAPITimeStamp = (new Date(dateFromAPI)).getTime();
var nowTimeStamp = now.getTime();

var microSecondsDiff = Math.abs(datefromAPITimeStamp - nowTimeStamp );
// Number of milliseconds per day =
//   24 hrs/day * 60 minutes/hour * 60 seconds/minute * 1000 msecs/second
var daysDiff = Math.floor(microSecondsDiff/(1000 * 60 * 60  * 24));


Finding User’s Age from Their Date of Birth

var birthDateFromAPI = "12/10/1989";

Note: We have a non-standard format. Read the API doc to determine if this means 12 Oct or 10 Dec. Change to ISO format accordingly.

var parts = birthDateFromAPI.split("/");
var birthDateISO = parts[2] + "-" + parts[0] + "-" + parts[1];

var birthDate =  new Date(birthDateISO);
var today = new Date();

var age = today.getFullYear() - birthDate.getFullYear();

if(today.getMonth() < birthDate.getMonth()) {

if(today.getMonth() == birthDate.getMonth() && today.getDate() < birthDate.getDate()) {

I know there are more concise ways to write this code but I like to write it this way because of the sheer clarity of the logic.

Suggestions to Avoid Date Hell

Now that we are comfortable with date arithmetic, we are in a position to understand the best practices to follow and the reasons for following them.

Getting DateTime from User

If you are getting the date and time from the user, you are most probably looking for their local DateTime. We saw in the date arithmetic section that the Date constructor can accept the date in a number of different ways.

To remove any confusion, I always suggest creating a date using new Date(year, month, day, hours, minutes, seconds, milliseconds) format even if you already have the date in a valid parsable format. If all programmers in your team follow this simple rule, it will be extremely easy to maintain the code in the long run since it is as explicit as you can be with the Date constructor.

The cool part is that you can use the variations that allow you to omit any of the last four parameters if they are zero; i.e., new Date(2012, 10, 12) is the same as new Date(2012, 10, 12, 0, 0, 0, 0) because the unspecified parameters default to zero.

For example, if you are using a date and time picker that gives you the date 2012-10-12 and time 12:30, you can extract the parts and create a new Date object as follows:

var dateFromPicker = "2012-10-12";
var timeFromPicker = "12:30";

var dateParts = dateFromPicker.split("-");
var timeParts = timeFromPicker.split(":");
var localDate = new Date(dateParts[0], dateParts[1]-1, dateParts[2], timeParts[0], timeParts[1]);
Try to avoid creating a date from a string unless it is in ISO date format. Use the Date(year, month, date, hours, minutes, seconds, microseconds) method instead.

Getting Only the Date

If you are getting only the date, a user’s birthdate for instance, it is best to convert the format to valid ISO date format to eliminate any timezone information that can cause the date to shift forward or backward when converted to UTC. For example:

var dateFromPicker = "12/20/2012";
var dateParts = dateFromPicker.split("/");
var ISODate = dateParts[2] + "-" + dateParts[0] + "-" + dateParts[1];
var birthDate = new Date(ISODate).toISOString();

In case you forgot, if you create a Date object with the input invalid ISO date format (YYYY-MM-DD), it will default to UTC instead of defaulting to the browser’s timezone.

Storing the Date

Always store the DateTime in UTC. Always send an ISO date string or a timestamp to the back-end.

Generations of computer programmers have realized this simple truth after bitter experiences trying to show the correct local time to the user. Storing the local time in the backend is a bad idea, it’s better to let the browser handle the conversion to local time in the front-end.

Also, it should be apparent that you should never send a DateTime string like “July 20, 1989 12:10pm” to the backend. Even if you send the timezone as well, you are increasing the effort for other programmers to understand your intentions and parse and store the date correctly.

Use the toISOString() or toJSON() methods of the Date object to convert the local DateTime to UTC.

var dateFromUI = "12-13-2012";
var timeFromUI = "10:20";
var dateParts = dateFromUI.split("-");
var timeParts = timefromUI.split(":");

var date = new Date(dateParts[2], dateParts[0]-1, dateParts[1], timeParts[0], timeParts[1]);

var dateISO = date.toISOString();

$.post("", {date: dateISO}, ...)

Displaying the Date and Time

  1. Get the timestamp or the ISO formatted date from a REST API.
  2. Create a Date Object.
  3. Use the toLocaleString() or toLocaleDateString() and toLocaleTimeString() methods or a date library like moment.js to display the local time.
var dateFromAPI = "2016-01-02T12:30:00Z";

var localDate = new Date(dateFromAPI);
var localDateString = localDate.toLocaleDateString(undefined, {  
	day : 'numeric',
	month : 'short',
	year : 'numeric'

var localTimeString = localDate.toLocaleTimeString(undefined, {
	hour: '2-digit',
	minute: '2-digit',
	second: '2-digit'

When Should You Store the Local Time Too?

“Sometimes it’s important to know the time zone in which an event occurred, and converting to a single time zone irrevocably obliterates that information.

If you’re doing a marketing promotion and want to know which customers placed orders around lunchtime, an order that appears to have been placed at noon GMT isn’t very helpful when it was actually placed over breakfast in New York.”

If you come across this kind of a situation, it would be wiser to save the local time as well. As usual, we would like to create the date in ISO format, but we have to find the timezone offset first.

The Date object’s getTimeZoneOffset() function tells us the number of minutes that when added to a given local time gives the equivalent UTC time. I suggest converting it to (+-)hh:mm format because it makes it more obvious that it is a timezone offset.

var now = new Date();
var tz = now.getTimezoneOffset();

For my timezone +05:45, I get -345, this is not only the opposite sign, but a number like -345 might be completely perplexing to a back-end developer. So we convert this to +05:45.

var sign = tz > 0 ? "-" : "+";

var hours = pad(Math.floor(Math.abs(tz)/60));
var minutes = pad(Math.abs(tz)%60);

var tzOffset = sign + hours + ":" + minutes;

Now we get the rest of the values and create a valid ISO string that represents the local DateTime.

var localDateTime = now.getFullYear() +
   				 "-" +
   				 pad(now.getMonth()+1) +
   				 "-" +
   				 pad(now.getDate()) +
   				 "T" +
   				 pad(now.getHours()) +
   				 ":" +
   				 pad(now.getMinutes()) +
   				 ":" +

If you want, you can wrap the utc and local dates in an object.

var eventDate = {
 	utc: now.toISOString(),
 	local: localDateTime,
 	tzOffset: tzOffset

Now, in the backend, if you wanted to find out if the event occurred before noon local time, you can parse the date and simply use the getHours() function.

var localDateString = eventDate.local;
var localDate = new Date(localDateString);

if(localDate.getHours() < 12) {
   console.log("Event happened before noon local time");

We didn’t use the tzOffset here, but we still store it because we might need it in the future for debugging purposes. You could actually just send the timezone offset and UTC time only. But I like to store the local time too because you will eventually have to store the date in a database and having the local time stored separately allows you to directly query based on a field rather than having to perform calculations to get the local date.

Server and Database Configuration

Always configure your servers and databases to use GMT/UTC timezone.

We have already seen how much of a pain timezone conversions can be, especially when they are unintended. Always sending UTC DateTime and configuring your servers to be in UTC timezone can make your life easier. Your backend code will be much simpler and cleaner as it doesn’t have to do any timezone conversions. DateTime data coming in from servers across the world can be compared and sorted effortlessly.

Most of the code in the back-end should be able to assume the timezone of the server to be UTC (but should still have a check in place to be sure).


Date manipulation is a hard problem, especially for beginners who don’t understand the fundamental concepts properly. Most of the existing material on the web is either too academic (going into excruciating details about quirks with timezones and DST that aren’t useful for most programmers) or too patchy (use this code and it will work).

In this article, I have tried to provide a comprehensive guide to how DateTime works and manipulating DateTime in code - explaining the concepts using practical examples, without assuming any previous knowledge about either DateTime or JavaScript. I hope you find this helpful.

If you have any questions or feedback, let me know in the comments and I’d be glad to reply.

About the author

Punit Jajodia, Nepal
member since February 17, 2016
Punit is an entrepreneur and software developer from Kathmandu, Nepal. Versatility is his biggest strength, as he has worked on a variety of projects from real-time 3D simulations on the browser and big data analytics to Windows application development. He has also recently ventured into training on the MEAN stack. He joined Toptal a few months ago and sees enormous possibilities for growth in South Asia where there are thousands of programmers working for freelancing websites like upwork and freelancer. Punit has been organizing meetups in his hometown for the last two years and loves to spread the word about the wonderful opportunities that Toptal provides to designers and developers. [click to continue...]
Hiring? Meet the Top 10 Freelance Software Developers for Hire in February 2017


It's good article about Date. Everyone who has encountered problems with conversion of dates, understand the complexities and subtleties. But in real projects it takes a lot of code. You can of course write your own class extending Date. But there are ready libraries that are perfected and tested over the years on many projects. I have not yet met projects, which would not use moment.js. I think it is also a strong side JS - the wealth of good libraries. What are the difficulties the author experienced when working with DateTime libraries?
Ashish Agrawal
Punit! you are absolutely right, every programmer has faced or has been facing this date issue in his/her programming career. Your article is really very good enough for the programmer who has no idea about the date conversions and manipulation. Brilliant work on this article.
Great article. Kudos! 1 small correction "Convert both dates to UTC timestamp, find the difference in microseconds and find the equivalent days." Actually you are finding difference in milliseconds. I felt that, actual soul of the article(Backend should have ISO formatted datetime and frontend should take care of converting the ISO format to user friendly local datetime) got lost into too many code snippets. EDIT: "Always configure your servers and databases to use GMT/UTC timezone." I think this is not needed. Because server will always going to receive ISO formatted date.
Punit Jajodia
Thank you for the encouraging words Ashish :)
Punit Jajodia
I am not suggesting the readers to extend the JavaScript Date object or create their own library. I use moment.js myself. But as I mentioned in the article, we often use date libraries without thinking about how date/time actually works. Most often, the bugs that we come across aren't because of any inherent weaknesses in the libraries themselves, but because of our lack of understanding of the basics. So I didn't experience any difficulties with the DateTime libraries themselves, but when creating the overall application, there were so many interfaces between Date "object" and Date "string" where I often got confused * retrieving the date from the user * sending the Date as a string to the backend * storing it in a database * retrieving it from the database * sending it back to the frontend * displaying it in the user's locale. One particular problem I faced was when I had to create an application that tracked a user's calorie intake. If the user is travelling, then managing what "time" the user ate a meal turned out to be a complex matter. As I struggled through the patchy pieces of code on the internet, I realized there was a need for an article that showed the bigger picture.
Anit Shrestha Manandhar
Nice read! Thanks Punit.
Andy Hubert
Small, but important, typo. You wrote "...if you create a Date object with the input invalid [NO SPACE] ISO date format..." but meant "...if you create a Date object with the input in valid [WITH SPACE] ISO date format..."
there are a few problems with the examples here.. TL;DR; date time in JavaScript is hard. I won't go over everything but a couple notes: doing any kind of arithmetic is error prone. The way you calculate `daysDiff` will be wrong if there is a DST transition in between the dates.. The correct way to implement it is to use the total days in month for each month in between or simply discard the time information and use the UTC date to compute the difference.. everyone gets it wrong (see my comment here: There is also a bug on Firefox for things like `date.setDate(date.getDate() + 3)` related to DST: (Safari and Chrome had the same issue but got fixed a couple years ago) `getTimeZoneOffset` is a foot-gun; it will return different value depending if current day is on daylight savings time or not. - proper way is to actually have the timezone as a user setting and not use offsets to calculate it at all (use some backend library/language that have an up-to-date timezone/DST transition table). - timezones in the font-end is hard (see: and So if you want to avoid issues, you're better of using just the UTC date methods in JavaScript; if you don't need the time information I would even consider storing it just as a plain `{day: 4, month: 10, year: 2016}` and not use `new Date()`.
Thanks for nice article, Punit. Working with datetime always causes problem (for me. I think, I am not exception). Your article makes this process not so painful :)
Khaled Monsoor
nice read. But, there're some issues. for example, output of your first line of code `var date = new Date("July 32, 2016 15:00:00 GMT");` is wrong, at least on latest Chrome & Firefox. While it definitely don't throw an exception, but it sets the `date` to `Invalid Date`.
I think what he means by configuring the server in UTC is that otherwise, if you were to create a new date you would have to explicitly tell your backend language (ie: php) that its a UTC. Same for the database, all automatically generated datetimes would be in something that is not UTC, which is a problem.
Punit Jajodia
Thanks for pointing it out. I've fixed it. :)
Punit Jajodia
I am happy the article is useful. Don't forget to use it as an educational content and use a library like moment.js whenever possible.
Punit Jajodia
Thanks for sharing the link to the issue with date difference calculation. It will be an extra reference to the readers. Date Arithmetic is complex, even more so when DST transitions are involved. When writing the article, I had to deliberately keep DST out of the loop to keep the article from being too long. You'll obviously need the help of a library to make sure that your DateTime calculations work with reasonable accuracy. The methods and the code snippets I have are supposed to be more educational than industry-standard code. If you've noticed, I haven't actually used the the value I get from getTimeZoneOffset() in the example that needs the local time and kept it only as a meta-data to be used for debugging. Again, an article the same length as this one could be written just about this. If you are storing the timezone as a user setting, then the UTC date methods in JavaScript should suffice and new Date() can be avoided altogether.
Great article indeed. I faced a lot challenges trying to handle dates in an online point of sale project. It involved a lot of date functions and date arithmetic which I somehow miraculously managed to overcome. After reading this article there are a number of basic concepts I picked that will help me in future projects
Michael Haephrati
I wrote an article about that
David Bruchmann
There are many limitations concerning dates related to the tools and formats you're using. The most well-known limitation is the timestamp, starting at 1.1.1970. In many applications records have this date if the user never enters a date. The more time passes, the more the situation gets unclear and the more it's probable that the zero-value leads to confusion and is interpreted wrong. If someone is born on that day at 0:00 its probable that his birth-date-time will be interpreted as empty / not entered. There are still more limitations, depending on the years: 1900, 1000, 0, etc. If you have to deal with historic dates this is a big issue, as you've to program even Date-Objects new for some programming-languages and databases. So if you use libraries for those problems, look if the used date-objects are supporting the used dateTimes, else you directly can look for another lib. Concerning the limitations, the whole date-time issue is the biggest bug in the whole IT-landscape, no matter about programming language or kind of database.
Frédéric Camblor
Nice article. There is (at least) one important use case you didn't covered in this article : when you have to deal with "time only" (and not time attached to a date). Typical use case : let's say you would like to implement an agenda, and want to modelize the "I have a meeting every monday at 10:00 AM". How would you store this in DB ? First thing is to know that when I say "at 10:00 AM", it means "at 10:00 AM of my timezone as of today". An important question to consider would be : "if the timezone offset changes over the year, should I keep the 10:00 AM no matter the timezone offset of my timezone, or should it be shifted alongside my timezone offset change." An example may be clearer : I live in France. Our current timezone offset as of today (January, 30th 2017) it +01:00 since we're on winter time. Summer time change is planned to trigger on March 26th 2017 at 01:00 UTC, meaning at that time we will switch from 02:00+01:00 to 03:00+02:00. When I will create my agenda item "at 10:00 AM", it will create a meeting at 10:00+01:00 for every upcoming weeks. However, once I will switch to summer time, what will happen ? I will have 2 options : - Put an agenda item at 10:00+02:00 : there, my team mates in France will continue to attend the meeting at the same hour in day, no matter if we're on summer or winter time. However, if I work with team mates in other countries than France, with a different (or simply no) winter/summer time swtich, their hour in day will be shifted. - Put an agenda item at 11:00+02:00 (=keeping the initial 09:00Z timezone offset). Here my team mates in France will be surprised on March 27th as it will break their habits. However, my teammates in US won't be impacted of this change on March 27th. For this typical use case scenario where we only work with time (and happened date alongside the time dimension), I would provide different storing implementation depending on the 2 options above : - For the first option, where we're working with "timezoned times", I would store the time ("10:00:00") with no timezone offset attached + the Timezone ("Europe/Paris") : that way, given a date (let's say 2017-03-27) I will be able to calculate that for timezone "Europe/Paris", "10:00" will be "10:00+02:00" on 2017-03-27. - For the second option, I will consider to store the time as an "UTC Time", eg storing "09:00Z" (putting the UTC timezone alongside the time, in order to remember that it is an UTC time I'm working on). That way, on 2017-03-27, I will add this UTC time to the date, then convert it to the target timezone (in my case, I will end with "11:00+02:00") Regards,
comments powered by Disqus
The #1 Blog for Engineers
Get the latest content first.
No spam. Just great engineering posts.
The #1 Blog for Engineers
Get the latest content first.
Thank you for subscribing!
You can edit your subscription preferences here.
Trending articles
Relevant Technologies
About the author
Punit Jajodia
JavaScript Developer
Punit is an entrepreneur and software developer from Kathmandu, Nepal. Versatility is his biggest strength, as he has worked on a variety of projects from real-time 3D simulations on the browser and big data analytics to Windows application development. He has also recently ventured into training on the MEAN stack. He joined Toptal a few months ago and sees enormous possibilities for growth in South Asia where there are thousands of programmers working for freelancing websites like upwork and freelancer. Punit has been organizing meetups in his hometown for the last two years and loves to spread the word about the wonderful opportunities that Toptal provides to designers and developers.