Our Blog

Latest news and updates from BinaryOps.io

Dates and Times with the BinaryOps.io API

TL;DR

Send all dates to the BinaryOps API in UTC with an ISO Date format.

  • Date only: “2015-02-16″ (If you’re creating this as a JavaScript Date object, make sure it’s in UTC!)
  • Date with time: “2015-02-16T01:03:27.294Z” (new Date().toISOString())

We’ll store and send them all back in UTC so that you can display them in timezones appropriate for your users.

…back to the article for those who want to know more:

Working with dates in anything but the simplest applications can quickly become difficult, especially when you have multiple users across multiple time zones.

Greenwich UTC
New York UTC-5:00
Chicago UTC-6:00
Los Angeles UTC-8:00

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.

E.g. “2015-02-16T01:03:27.294Z”

What about dates that don’t have time components?

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();

The result is a UTC date where the time components are all zero. When sent to the server, it will be stored in UTC and served back to the client exactly as it was sent. The only remaining piece is to display the date back to the user in the same UTC date format. Strings representing dates in this manner can easily be parsed by passing directly into the JavaScript Date() constructor or if you’re using Moment.js on your client, via the moment.utc() function.

E.g. var parsedBirthday = new Date(“2015-02-16T00:00:00.000Z”).toUTCString();

Default Values

There are two date-specific keywords that can be provided to the API when providing default values or sending Insert or Update data:

  • NOW – Will get replaced with the current date in UTC, including the time.
  • TODAY – Will get the current UTC date, where the time components have been zeroed out.

Any other non-date values that do not match the ISO Date format will be considered an error and cause the request to fail.

Examples

Here’s an example created with jsFiddle that demonstrates Javascript date handling with timezones.

Value Method Remark
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

Tags :  dates  api