Convert to Timestamp and Back Again
Equally a software programmer, you tin't run away from date manipulation. Well-nigh every app a programmer 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 whatsoever developer nigh their experience treatment dates and time zones and they will probably share some war stories. Treatment date and fourth dimension fields is certainly not rocket scientific discipline but tin oftentimes exist ho-hum and fault-prone.
At that place are hundreds of articles on the topic out at that place, still, well-nigh are either as well bookish, focusing on nitty-gritty details, or they are also patchy, providing short snippets of lawmaking without much explanation accompanying them. This in-depth guide to DateTime manipulation should aid you empathize the programming concepts and best practices relevant to time and engagement without having to browse through a sea of information on this topic.
In this article, I'm going to aid you think conspicuously almost date and time fields and advise some best practices that can help y'all avoid engagement/time hell. Here nosotros will explore some of the cardinal concepts that are necessary for manipulating date and time values correctly, formats that are user-friendly for storing DateTime values and transferring them over APIs, and more.
For starters, the right answer for production code is almost e'er to utilise a proper library rather than rolling your ain. The potential difficulties with DateTime calculation discussed in this article are only the tip of the iceberg, simply they're however helpful to know about, with or without a library.
DateTime Libraries Assist If You Understand Them Correctly
Date libraries assist in many ways to make your life easier. They greatly simplify date parsing, date arithmetic and logical operations, and engagement formatting. You can find a reliable date library for both the front cease and the dorsum end to do well-nigh of the heavy lifting for you.
Withal, we oft employ date libraries without thinking nigh how date/time really works. Appointment/time is a complex concept. The bugs that come due to its incorrect understanding can be extremely difficult to sympathize and fix, even with the aid of date libraries. Equally a programmer, you demand to understand the nuts and be able to appreciate the problems that date libraries solve to make the most out of them.
Also, date/fourth dimension libraries tin can just have you so far. All date libraries piece of work past giving you admission to convenient data structures to stand for a DateTime. If you are sending and receiving data through a Rest API, you lot will eventually need to catechumen the engagement to a string and vice versa because JSON doesn't have a native data structure to represent DateTime. The concepts I have outlined hither volition help you lot to avoid some of the common issues that might come upwards when doing these appointment-to-string and cord-to-date transformations.
Note: Even though I take used JavaScript as the programming language discussed in this commodity, these are general concepts that use, to a large extent, to virtually all programming languages and their date libraries. And so even if yous've never written a line of JavaScript before, feel gratis to continue reading every bit I hardly presume any prior noesis 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 sentry.
Give or have a few minutes, if I ask my friend to encounter me at a nearby cafe at 3:00 PM, I can expect to run across her there at roughly that time. Similarly, there wouldn't be whatever confusion if instead I said, for instance, "permit's meet in one and a one-half hours." We routinely talk about fourth dimension this way with people living in the same city or fourth dimension zone.
Let's recall of a different scenario: I want to tell a friend living in Uppsala, Sweden that I want to talk to him at 5 PM. I ship him a message, "Hey Anton, permit's talk at 5 PM." I immediately go the response, "Your time or my fourth dimension?"
Anton tells me that he lives in the Fundamental European fourth dimension zone which is UTC+01:00. I live in UTC+05:45. This means that when information technology is 5 PM where I live, it is 5 PM - 05:45 = 11:xv AM UTC, which translates to 11:15 AM UTC + 01:00 = 12:15 PM in Uppsala, perfect for both of us.
Also, exist enlightened of the difference between time zone (Key European Time) and time zone get-go (UTC+05:45). Countries tin decide to modify their time zone offsets for Daylight Savings Time for political reasons as well. Almost every year there's a change to the rules in at least 1 state, meaning whatsoever lawmaking with these rules baked in must exist kept up-to-date—information technology'southward worth because what your codebase depends on for this for each tier of your app.
That's another good reason we'll recommend that just the front end deals with fourth dimension zones in most cases. When it doesn't, what happens when the rules your database engine uses don't friction match those of your front or back end?
This trouble of managing ii different versions of the time, relative to the user and relative to a universally accustomed standard, is difficult, even more and so in the world of programming where precision is cardinal and even one 2nd can make a huge divergence. The first stride towards solving these issues is to store DateTime in UTC.
Standardizing the Format
Standardizing the time is wonderful considering I only demand to store the UTC time and as long as I know the time zone of the user, I can always convert to their fourth dimension. Conversely, if I know a user's local fourth dimension and know their time zone, I can convert that to UTC.
Only 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 xxx/7, depending on where you live). For the fourth dimension, y'all could write "9:thirty PM" or "2130".
Scientists all over the world came together to tackle this problem and decided on a format to describe fourth dimension that programmers really similar because information technology's short and precise. Nosotros similar 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
Earlier we start with best practices, nosotros will learn about date manipulation using JavaScript to get a grasp of the syntax and general concepts. Although nosotros use JavaScript, you can adapt this information to your favorite programming language easily.
We volition use date arithmetic to solve common appointment-related problems that well-nigh developers come up across.
My goal is to make you lot comfortable creating a date object from a cord and extracting components out of ane. This is something that a date library can help you with, but it's always ameliorate to understand how it is done behind the scenes.
Once we've gotten our easily muddied with appointment/fourth dimension, information technology is and so easier to think about the problems we face, extract the all-time practices, and motility ahead. If yous want to skip to the best practices, feel gratuitous to exercise so, just I would highly recommend you to at least skim through the appointment-arithmetic section below.
The JavaScript Engagement Object
Programming languages contain useful constructs to make our lives easier. The JavaScript Engagement
object is one such thing. It offers convenient methods to become the current date and time, store a engagement in a variable, perform engagement arithmetic, and format the engagement based on the user'southward 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 Luxon, engagement-fns, or dayjs. (Whatsoever you apply, avoid the once-popular Moment.js—often simply called moment
, equally it appears in code—since it's now deprecated.)
But for educational purposes, we will utilize the methods that the Date() object provides to learn how JavaScript handles DateTime.
Getting Current Engagement
const currentDate = new Appointment();
If you don't pass anything to the Date constructor, the date object returned contains the current date and time.
Y'all can then format it to extract just the date office as follows:
const currentDate = new Engagement(); const currentDayOfMonth = currentDate.getDate(); const currentMonth = currentDate.getMonth(); // Be careful! January is 0, non ane const currentYear = currentDate.getFullYear(); const dateString = currentDayOfMonth + "-" + (currentMonth + 1) + "-" + currentYear; // "27-eleven-2020"
Annotation: The "January is 0" pitfall is common only not universal. It's worth double-checking the documentation of any language (or configuration format: e.one thousand., cron is notably 1-based) before y'all start using it.
Getting the Current Time Postage
If you instead want to get the current fourth dimension stamp, y'all can create a new Date object and use the getTime() method.
const currentDate = new Date(); const timestamp = currentDate.getTime();
In JavaScript, a time stamp is the number of milliseconds that have passed since Jan ane, 1970.
If you don't intend to support <IE8, you can use Date.now()
to straight become the time postage stamp without having to create a new Date object.
Parsing a Date
Converting a string to a JavaScript appointment object is done in different ways.
The Engagement object's constructor accepts a wide variety of date formats:
const date1 = new Date("Wed, 27 July 2022 thirteen:30:00"); const date2 = new Date("Wed, 27 July 2022 07:45:00 UTC"); const date3 = new Date("27 July 2022 13:30:00 UTC+05:45");
Note that you do non need to include the twenty-four hour period of week because JS tin make up one's mind the day of the calendar week for any appointment.
You can as well pass in the twelvemonth, month, mean solar day, hours, minutes, and seconds as split up arguments:
const appointment = new Date(2016, 6, 27, 13, 30, 0);
Of grade, you lot tin always use ISO date format:
const date = new Date("2016-07-27T07:45:00Z");
However, you can run into trouble when you practice not provide the time zone explicitly!
const date1 = new Date("25 July 2016"); const date2 = new Date("July 25, 2016");
Either of these will give yous 25 July 2022 00:00:00 local time.
If you use the ISO format, even if yous give only the engagement and not the time and time zone, it will automatically accept the time zone as UTC.
This means that:
new Appointment("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 Appointment
Fortunately, modern JavaScript has some convenient internationalization functions congenital into the standard Intl
namespace that make engagement formatting a straightforward operation.
For this we'll need 2 objects: a Date
and an Intl.DateTimeFormat
, initialized with our output preferences. Supposing we'd like to use the American (Thou/D/YYYY) format, this would look like:
const firstValentineOfTheDecade = new Appointment(2020, 1, 14); // 1 for February const enUSFormatter = new Intl.DateTimeFormat('en-US'); panel.log(enUSFormatter.format(firstValentineOfTheDecade)); // 2/14/2020
If instead we wanted the Dutch (D/M/YYYY) format, we would just laissez passer a dissimilar culture code to the DateTimeFormat
constructor:
const nlBEFormatter = new Intl.DateTimeFormat('nl-BE'); console.log(nlBEFormatter.format(firstValentineOfTheDecade)); // xiv/2/2020
Or a longer form of the American format, with the month proper name spelled out:
const longEnUSFormatter = new Intl.DateTimeFormat('en-US', { year: 'numeric', month: 'long', twenty-four hour period: 'numeric', }); panel.log(longEnUSFormatter.format(firstValentineOfTheDecade)); // February 14, 2020
Now, if we wanted a proper ordinal format on the solar day of the month—that is, "14th" instead of just "xiv"—this unfortunately needs a bit of a workaround, because day
's only valid values as of this writing are "numeric"
or "ii-digit"
. Borrowing Flavio Copes' version of Mathias Bynens' lawmaking to leverage some other function of Intl
for this, we tin can customize the day of the month output via formatToParts()
:
const pluralRules = new Intl.PluralRules('en-Usa', { type: 'ordinal' }) const suffixes = { 'one': 'st', 'ii': 'nd', 'few': 'rd', 'other': 'thursday' } const convertToOrdinal = (number) => `${number}${suffixes[pluralRules.select(number)]}` // At this point: // convertToOrdinal("1") === "1st" // convertToOrdinal("2") === "2nd" // etc. const extractValueAndCustomizeDayOfMonth = (part) => { if (part.type === "day") { return convertToOrdinal(role.value); } render part.value; }; panel.log( longEnUSFormatter.formatToParts(firstValentineOfTheDecade) .map(extractValueAndCustomizeDayOfMonth) .join("") ); // February 14th, 2020
Unfortunately, formatToParts
isn't supported by Net Explorer (IE) at all equally of this writing, only all other desktop, mobile, and back-finish (i.eastward. Node.js) technologies practise have back up. For those who need to support IE and absolutely need ordinals, the sidenote below (or meliorate, a proper appointment library) provides an answer.
If you need to support older browsers similar IE before version 11, date formatting in JavaScript is tougher because there were no standard date-formatting functions like strftime
in Python or PHP.
In PHP for example, the function strftime("Today is %b %d %Y %X", mktime(5,10,0,12,30,99))
gives you lot Today is Dec xxx 1999 05:10:00
.
Yous can use a different combination of messages preceded by %
to go the date in different formats. (Conscientious, not every language assigns the same meaning to each letter of the alphabet—particularly, 'M' and 'thou' may exist swapped for minutes and months.)
If y'all are sure of the format you desire to use, it is best to extract private $.25 using the JavaScript functions we covered above and create a cord yourself.
var currentDate = new Date(); var engagement = currentDate.getDate(); var month = currentDate.getMonth(); var year = currentDate.getFullYear();
We tin can go the date in MM/DD/YYYY format as
var monthDateYear = (month+i) + "/" + date + "/" + year;
The problem with this solution is that it can give an inconsistent length to the dates because some months and days of the month are single-digit and others double-digit. This can be problematic, for example, if you are displaying the appointment in a table column, because the dates don't line upwardly.
We can address this by using a "pad" function that adds a leading 0.
function pad(n) { return n<x ? '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 desire DD-MM-YYYY instead, the process is similar:
var ddmmyyyy = pad(date) + "-" + pad(month + i) + "-" + year;
Let's up the ante and try to print the date in "Month Engagement, Year" format. We will demand a mapping of month indexes to names:
var monthNames = [ "January", "Feb", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ]; var dateWithFullMonthName = monthNames[calendar month] + " " + pad(appointment) + ", " + year;
Some people like to display the date every bit 1st January, 2013. No problem, all we need is a helper office ordinal
that returns 1st for 1, twelfth for 12, and 103rd for 103, etc., and the remainder is simple:
var ordinalDate = ordinal(date) + " " + monthNames[month] + ", " + twelvemonth;
It is easy to determine the day of week from the date object, and then let's add together that in:
var daysOfWeek = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; ordinalDateWithDayOfWeek = daysOfWeek[currentDate.getDay()] + ", " + ordinalDate;
The bigger point here is, in one case yous've got the numbers extracted from the date, the formatting is more often than not related to strings.
Irresolute the Appointment Format
In one case you know how to parse a engagement and format it, irresolute a date from ane format to another is just a affair of combining the ii.
For case, if you have a engagement in the format Jul 21, 2013 and wanted to change the format to 21-07-2013, it can be accomplished like this:
const myDate = new Appointment("Jul 21, 2013"); const dayOfMonth = myDate.getDate(); const month = myDate.getMonth(); const year = myDate.getFullYear(); function pad(n) { render due north<10 ? '0'+north : n } const ddmmyyyy = pad(dayOfMonth) + "-" + pad(calendar month + one) + "-" + year; // "21-07-2013"
Using JavaScript Engagement Object's Localization Functions
The date formatting methods nosotros discussed to a higher place should piece of work in near applications, but if you really want to localize the formatting of the appointment, I suggest you apply the Engagement
object'due south toLocaleDateString()
method:
const today = new Date().toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric', });
…gives us something like 26 Jul 2016
.
Changing the locale to 'en-United states of america' gives "Jul 26, 2016" instead. Detect how the formatting changed, merely the display options were notwithstanding kept the same—a very useful feature. As shown in the previous section, the newer Intl.DateTimeFormat
-based technique works very similarly to this, just lets you reuse a formatter object so that you merely need to set options once.
With toLocaleDateString()
, it is a good habit to always laissez passer the formatting options, even if the output looks fine on your figurer. This tin can protect the UI from breaking in unexpected locales with actually long month names or looking bad-mannered considering of short ones.
If I wanted the full month "July" instead, all I exercise is change the month parameter in the options to "long". JavaScript handles everything for me. For en-US, I now get July 26, 2016.
Note: If you want the browser to automatically utilise the user'south locale, yous tin laissez passer "undefined" as the first parameter.
If y'all want to prove the numeric version of the engagement and don't want to fuss with MM/DD/YYYY vs. DD/MM/YYYY for dissimilar locales, I advise the following elementary solution:
const today = new Appointment().toLocaleDateString(undefined, { day: 'numeric', 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:
const today = new Appointment().toLocaleDateString(undefined, { twenty-four hours: '2-digit', month: '2-digit', year: 'numeric', });
This outputs 07/26/2016
. Just what we wanted!
You can also use some other related functions to localize the way both time and date are displayed:
Code | Output | Description |
---|---|---|
| "4:21:38 AM" | Brandish localized version of merely fourth dimension |
| "04:21:38 AM" | Display localized time based on options provided |
| "7/22/2016, 4:21:38 AM" | Brandish date and time for user'due south locale |
| "seven/22/2016, 04:21 AM" | Display localized date and fourth dimension based on options provided |
Calculating Relative Dates and Times
Here's an case of calculation 20 days to a JavaScript Appointment (i.east., figuring out the engagement 20 days afterwards a known date):
const myDate = new Appointment("July 20, 2022 15:00:00"); const nextDayOfMonth = myDate.getDate() + 20; myDate.setDate(nextDayOfMonth); const newDate = myDate.toLocaleString();
The original date object now represents a date 20 days after July 20 and newDate
contains a localized string representing that date. On my browser, newDate
contains "eight/ix/2016, 3:00:00 PM".
To calculate relative time stamps with a more precise deviation than whole days, you can use Date.getTime()
and Date.setTime()
to work with integers representing the number of milliseconds since a sure epoch—namely, Jan ane, 1970. For example, if you want to know when it'due south 17 hours after correct now:
const msSinceEpoch = (new Date()).getTime(); const seventeenHoursLater = new Date(msSinceEpoch + 17 * 60 * 60 * 1000);
Comparing Dates
Every bit with everything else related to date, comparing dates has its own gotchas.
First, nosotros need to create date objects. Fortunately, <, >, <=, and >= all work. And then comparison July 19, 2022 and July eighteen, 2022 is equally piece of cake every bit:
const date1 = new Date("July nineteen, 2014"); const date2 = new Date("July 28, 2014"); if(date1 > date2) { console.log("Start date is more recent"); } else { console.log("Second appointment is more recent"); }
Checking for equality is trickier, since two date objects representing the same date are even so two different date objects and will non exist equal. Comparison date strings is a bad idea because, for instance, "July 20, 2014" and "20 July 2014" represent the aforementioned date but have different cord representations. The snippet below illustrates the first betoken:
const date1 = new Date("June 10, 2003"); const date2 = new Date(date1); const equalOrNot = date1 == date2 ? "equal" : "not equal"; panel.log(equalOrNot);
This will output not equal
.
This item case can be fixed past comparing the integer equivalents of the dates (their time stamps) 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. Then I feel that the example is important from an academic point of view simply. Besides, 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'southward look at a more practical case. You're trying to compare whether the birthday the user has entered is the same equally the lucky date you are getting from an API.
const userEnteredString = "12/xx/1989"; // MM/DD/YYYY format const dateStringFromAPI = "1989-12-20T00:00:00Z"; const dateFromUserEnteredString = new Date(userEnteredString) const dateFromAPIString = new Engagement(dateStringFromAPI); if (dateFromUserEnteredString.getTime() == dateFromAPIString.getTime()) { transferOneMillionDollarsToUserAccount(); } else { doNothing(); }
Both represented the same date but unfortunately your user will not get the 1000000 dollars.
Here's the trouble: JavaScript always assumes the time zone to be the ane that the browser provides it unless explicitly specified otherwise.
This means, for me, new Appointment ("12/20/1989")
will create a appointment 1989-12-20T00:00:00+5:45 or 1989-12-19T18:15:00Z which is non the same equally 1989-12-20T00:00:00Z in terms of fourth dimension stamp.
It's not possible to change just the time zone of an existing date object, so our target is now to create a new date object merely with UTC instead of local fourth dimension zone.
We will ignore the user's time zone and use UTC while creating the date object. There are ii means to do it:
- Create an ISO formatted appointment string from the user input engagement 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.
const userEnteredDate = "12/20/1989"; const parts = userEnteredDate.split("/"); const userEnteredDateISO = parts[2] + "-" + parts[0] + "-" + parts[1]; const userEnteredDateObj = new Date(userEnteredDateISO + "T00:00:00Z"); const dateFromAPI = new Appointment("1989-12-20T00:00:00Z"); const result = userEnteredDateObj.getTime() == dateFromAPI.getTime(); // true
This also works if y'all don't specify the fourth dimension since that will default to midnight (i.e., 00:00:00Z):
const userEnteredDate = new Engagement("1989-12-20"); const dateFromAPI = new Date("1989-12-20T00:00:00Z"); const result = userEnteredDate.getTime() == dateFromAPI.getTime(); // true
Think: If the date constructor is passed a string in correct ISO appointment format of YYYY-MM-DD, information technology assumes UTC automatically.
- JavaScript provides a neat Date.UTC() function that you can use to get the UTC time stamp of a date. We extract the components from the date and pass them to the role.
const userEnteredDate = new Date("12/20/1989"); const userEnteredDateTimeStamp = Engagement.UTC(userEnteredDate.getFullYear(), userEnteredDate.getMonth(), userEnteredDate.getDate(), 0, 0, 0); const dateFromAPI = new Date("1989-12-20T00:00:00Z"); const outcome = userEnteredDateTimeStamp == dateFromAPI.getTime(); // true ...
Finding the Difference Between 2 Dates
A common scenario you will come across is to find the difference betwixt two dates.
Nosotros discuss ii employ cases:
Finding the Number of Days Betwixt Ii Dates
Convert both dates to UTC time stamp, find the divergence in milliseconds and find the equivalent days.
const dateFromAPI = "2016-02-10T00:00:00Z"; const now = new Appointment(); const datefromAPITimeStamp = (new Appointment(dateFromAPI)).getTime(); const nowTimeStamp = now.getTime(); const microSecondsDiff = Math.abs(datefromAPITimeStamp - nowTimeStamp); // Math.round is used instead of Math.floor to business relationship for certain DST cases // Number of milliseconds per day = // 24 hrs/day * hour/hr * 60 seconds/minute * thou ms/second const daysDiff = Math.circular(microSecondsDiff / (chiliad * 60 * threescore * 24)); console.log(daysDiff);
Finding User's Historic period from Their Date of Birth
const birthDateFromAPI = "12/x/1989";
Notation: We have a not-standard format. Read the API doc to determine if this ways 12 October or 10 Dec. Change to ISO format accordingly.
const parts = birthDateFromAPI.split("/"); const birthDateISO = parts[2] + "-" + parts[0] + "-" + parts[i]; const birthDate = new Date(birthDateISO); const today = new Date(); allow age = today.getFullYear() - birthDate.getFullYear(); if(today.getMonth() < birthDate.getMonth()) { historic period--; } if(today.getMonth() == birthDate.getMonth() && today.getDate() < birthDate.getDate()) { historic period--; }
I know in that location are more curtailed ways to write this code but I similar to write it this style because of the sheer clarity of the logic.
Suggestions to Avoid Date Hell
At present 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 yous 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 Engagement
constructor tin can accept the date in a number of unlike ways.
To remove whatever confusion, I always suggest creating a date using new Date(year, month, twenty-four hour period, hours, minutes, seconds, milliseconds)
format fifty-fifty if you already take the date in a valid parsable format. If all programmers in your team follow this simple rule, it will be extremely piece of cake to maintain the code in the long run since it is every bit explicit equally you tin can be with the Date
constructor.
The cool part is that y'all can use the variations that allow you lot to omit any of the last four parameters if they are zip; i.due east., new Date(2012, 10, 12)
is the same as new Appointment(2012, 10, 12, 0, 0, 0, 0)
because the unspecified parameters default to null.
For example, if you are using a appointment and time picker that gives y'all the date 2012-ten-12 and time 12:30, yous can extract the parts and create a new Date object every bit follows:
const dateFromPicker = "2012-10-12"; const timeFromPicker = "12:thirty"; const dateParts = dateFromPicker.split up("-"); const timeParts = timeFromPicker.split(":"); const localDate = new Appointment(dateParts[0], dateParts[1]-1, dateParts[two], timeParts[0], timeParts[ane]);
Try to avoid creating a date from a string unless it is in ISO date format. Use the Date(year, calendar month, date, hours, minutes, seconds, microseconds) method instead.
Getting Only the Appointment
If you are getting only the date, a user's birthdate for instance, it is all-time to convert the format to valid ISO appointment format to eliminate any time zone information that tin can crusade the date to shift forrard or backward when converted to UTC. For example:
const dateFromPicker = "12/20/2012"; const dateParts = dateFromPicker.separate("/"); const ISODate = dateParts[2] + "-" + dateParts[0] + "-" + dateParts[1]; const birthDate = new Date(ISODate).toISOString();
In example you forgot, if you create a Appointment
object with the input in valid ISO engagement format (YYYY-MM-DD), it will default to UTC instead of defaulting to the browser's time zone.
Storing the Date
Always store the DateTime in UTC. E'er send an ISO engagement string or a time postage stamp to the back finish.
Generations of computer programmers have realized this simple truth after biting experiences trying to show the correct local time to the user. Storing the local fourth dimension in the back end 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 ship a DateTime string like "July 20, 1989 12:10 PM" to the back end. Even if y'all send the time zone as well, y'all are increasing the effort for other programmers to understand your intentions and parse and shop the date correctly.
Utilize the toISOString()
or toJSON()
methods of the Appointment object to catechumen the local DateTime to UTC.
const dateFromUI = "12-13-2012"; const timeFromUI = "10:20"; const dateParts = dateFromUI.split("-"); const timeParts = timeFromUI.divide(":"); const engagement = new Date(dateParts[ii], dateParts[0]-ane, dateParts[1], timeParts[0], timeParts[1]); const dateISO = date.toISOString(); $.mail service("http://example.com/", {date: dateISO}, ...)
Displaying the Date and Fourth dimension
- Get the fourth dimension stamp or the ISO formatted date from a Balance API.
- Create a
Date
object. - Utilize the
toLocaleString()
ortoLocaleDateString()
andtoLocaleTimeString()
methods or a date library to display the local time.
const dateFromAPI = "2016-01-02T12:xxx:00Z"; const localDate = new Date(dateFromAPI); const localDateString = localDate.toLocaleDateString(undefined, { day: 'numeric', month: 'short', year: 'numeric', }); const localTimeString = localDate.toLocaleTimeString(undefined, { hour: '2-digit', infinitesimal: 'ii-digit', 2d: '2-digit', });
When Should You Store the Local Time Too?
"Sometimes it'south important to know the time zone in which an event occurred, and converting to a single time zone irrevocably obliterates that information.
"If y'all're doing a marketing promotion and want to know which customers placed orders around lunchtime, an order that appears to have been placed at apex GMT isn't very helpful when it was really placed over breakfast in New York."
If you come across this kind of situation, information technology would exist wiser to relieve the local time likewise. As usual, we would like to create the appointment in ISO format, but we have to discover the time zone offset beginning.
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 information technology to (+-)hh:mm format because it makes it more than obvious that it is a time zone offset.
const now = new Date(); const tz = now.gettime zoneOffset();
For my time zone +05:45, I get -345, this is not only the opposite sign, but a number similar -345 might exist completely perplexing to a back-end developer. So we convert this to +05:45.
const sign = tz > 0 ? "-" : "+"; const hours = pad(Math.floor(Math.abs(tz)/60)); const minutes = pad(Math.abs(tz)%lx); const tzOffset = sign + hours + ":" + minutes;
Now we get the residual of the values and create a valid ISO cord that represents the local DateTime.
const localDateTime = now.getFullYear() + "-" + pad(now.getMonth()+1) + "-" + pad(now.getDate()) + "T" + pad(at present.getHours()) + ":" + pad(now.getMinutes()) + ":" + pad(now.getSeconds());
If yous want, you can wrap the UTC and local dates in an object.
const eventDate = { utc: at present.toISOString(), local: localDateTime, tzOffset: tzOffset, }
At present, in the dorsum end, if you wanted to find out if the event occurred earlier noon local time, y'all can parse the engagement and just utilize the getHours()
function.
const localDateString = eventDate.local; const localDate = new Engagement(localDateString); if(localDate.getHours() < 12) { console.log("Effect happened before noon local fourth dimension"); }
We didn't employ the tzOffset
here, only we all the same store it considering we might need it in the future for debugging purposes. You could actually just send the time zone offset and UTC fourth dimension only. But I like to store the local fourth dimension too considering you will eventually accept to store the appointment in a database and having the local fourth dimension stored separately allows you to directly query based on a field rather than having to perform calculations to get the local date.
Sometimes, even with the local time zone stored, you'll desire to display dates in a detail time zone. For example, times for events might make more sense in the current user's time zone if they're virtual, or in the time zone where they will physically take identify, if they're not. In whatsoever case, information technology's worth looking beforehand at established solutions for formatting with explicit fourth dimension zone names.
Server and Database Configuration
Ever configure your servers and databases to use UTC time zone. (Note that UTC and GMT are not the same affair—GMT, for example, might imply a switch to BST during the summer, whereas UTC never volition.)
Nosotros have already seen how much of a pain fourth dimension zone conversions can be, specially when they are unintended. E'er sending UTC DateTime and configuring your servers to be in UTC fourth dimension zone can make your life easier. Your dorsum-terminate lawmaking will be much simpler and cleaner as it doesn't have to do any time zone conversions. DateTime data coming in from servers across the world can be compared and sorted effortlessly.
Lawmaking in the back terminate should be able to assume the time zone of the server to be UTC (but should still accept a check in place to be sure). A unproblematic configuration check saves having to recall virtually and code for conversions every fourth dimension new DateTime code is written.
It's Time for Better Date Treatment
Date manipulation is a difficult trouble. The concepts backside the practical examples in this article apply beyond JavaScript, and are but the showtime when it comes to properly treatment DateTime data and calculations. Plus, every helper library will come up with its own set of nuances—which is even true of the eventual official standard support{target="_blank"} for these types of operations.
The lesser line is: Apply ISO on the dorsum end, and leave the front to format things properly for the user. Professional programmers will be aware of some of the nuances, and will (all the more decidedly) use well-supported DateTime libraries on both the back end and the front end end. Born functions on the database side are another story, but hopefully this article gives enough groundwork to make wiser decisions in that context, too.
Source: https://www.toptal.com/software/definitive-guide-to-datetime-manipulation
0 Response to "Convert to Timestamp and Back Again"
Enviar um comentário