Send all dates to the BinaryOps API in UTC with an ISO Date format.
We’ll store and send them all back in UTC so that you can display them in timezones appropriate for your users.
Working with dates in anything but the simplest applications can quickly become difficult, especially when you have multiple users across multiple time zones.
Consider an application that schedules conference calls that’s being used from New York, Chicago & Los Angeles. If the timezone differences aren’t handled correctly, meetings get missed and people stop using it. In order to handle time properly within multiple timezones, we need to convert all dates into a common timezone which is GMT (or UTC). There are semantic differences between the two, but for our purposes they are interchangeable, I’ll use UTC ’cause it’s the terminology commonly used when setting up servers etc. UTC is considered the baseline, or the ‘zero-offset’ timezone.
For applications to have a consistent reference point for dates and times, they should all get converted and stored as UTC. That way, when a user pulls up conference call details, they can view the date and time in their local timezone and be on-time for that very important meeting. In order to store and present dates properly, it’s important to understand what happens to them at which point, and how they should get converted along the way.
When we create a new Date object in our browser, it’s automatically created in our local timezone. When I type “new Date()” in my browser console, it replies with a String representation of the current date and time.
new Date() Sun Feb 15 2015 16:19:33 GMT-0800 (PST)
When we need to send that same Date object to our server, we need it to arrive in UTC, so how can we do that? I’ve seen it done a number of ways, but it doesn’t need to be this hard and both of these proposed solutions are BROKEN.
var now = new Date(); var utc = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds(), now.getUTCMilliseconds());
As a developer, that one makes me sad.
var now = new Date(); var utc = new Date(now.getTime() + now.getTimezoneOffset() * 60000);
That one turns my stomach a little…
In both of those cases, the new Object stored in a variable named ‘utc’ but has the local timezone attached. The much simpler and correct way to do it, is to use:
var utc = new Date().toISOString();
This time we have the current time (with a local timezone) properly adjusted and identified as UTC. If you’re sending data to the server as JSON, it’s even easier. The built-in Date.prototype.toJSON() function automagically converts all your dates to UTC using the above .toISOString() function. As well, client-side frameworks may have similar functions (Knockout has it’s own .toJSON() function) that does the same thing.
When you’re sending dates to the BinaryOps API, you need to send it in the UTC timezone using the ISO Date format.
If you’re not concerned with the time component of a given date, you can simply send the date portion to the API. The BinaryOps API will assume that the date is a UTC/ISO formatted date and append “T00:00:00.000Z” to the end.
E.g. “2015-02-16″ becomes “2015-02-16T00:00:00.000Z” and is stored as such.
If you’re storing dates without a time component, such as a birth date or anniversary, you might think that the time zone is irrelevant, but you still need to consider it. Let me explain. If you’re in Paris and create your birthdate as “new Date(1995, 2, 10)”, it would get converted from CET (Central European Time) to UTC and stored on the server as “1995-02-09T23:00:00″, the day prior! Given that a birthday is finite and not subject to time zones, it has to be handled a little differently. Here’s one way to create a UTC date without a time component, by using the static Date.UTC() method:
var birthday = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate())).toISOString();
E.g. var parsedBirthday = new Date(“2015-02-16T00:00:00.000Z”).toUTCString();
There are two date-specific keywords that can be provided to the API when providing default values or sending Insert or Update data:
Any other non-date values that do not match the ISO Date format will be considered an error and cause the request to fail.
|Sun Feb 15 2015 22:07:08 GMT-0800 (PST)||var now = new Date()||The current time|
|Mon Feb 16 2015 06:07:08 GMT-0800 (PST)||new Date(now.getTime() + now.getTimezoneOffset() * 60000)||Still in the local timezone!|
|Mon Feb 16 2015 06:07:08 GMT-0800 (PST)||new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds())||Still in the local timezone!|
|Mon, 16 Feb 2015 06:07:08 GMT||new Date().toGMTtring()||Deprecated in favor of toUTCString()|
|Mon, 16 Feb 2015 06:07:08 GMT||new Date().toUTCString()||Human readable format|
|2015-02-16T06:07:08.631Z||new Date().toJSON()||Same as .toISOString()|
|2015-02-16T06:07:08.631Z||new Date().toISOString()||The current time as a String|
|2015-02-16T00:00:00.000Z||new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate())).toISOString()||A UTC date with no time component!|
|Mon, 16 Feb 2015 00:00:00 GMT||new Date(“2015-02-16T00:00:00.000Z”).toUTCString()||Parsing a UTC/ISO formatted date|