2

I am creating a browser-based single-page app which will be retrieving information as JSON from an API that I control. The API will often return large, complex object graphs (objects within objects, etc). Many of the objects contain "date-only fields" (i.e. fields for which only the date is relevant) - that is, if a field is set to "April 1, 2015" it should always appear to the user as April 1, regardless of the user's timezone, daylight savings time, etc. Of course, the API server's timezone should have no effect on the displayed dates (and may be assumed to be fixed forever).

In the server-side API code, I can easily identify these "date-only fields" and have full flexibility to pre-process them in any way before sending them to the client.

On the client, these dates will be used in a variety of ways (displayed in textboxes and labels, passed to AngularJS 'date' filter, passed to 3rd-party date-picker controls, etc). As far as I can tell, the lowest common denominator here is the Date() constructor - if the browser's JavaScript Date() constructor will correctly interpret the date, everything else will work fine.

My first thought, therefore, was to pre-process these date-only fields, to get them into a format that the Date() constructor will interpret correctly. It turns out that this is not trivial to find such a format (see my related question here: JavaScript date-only format guaranteed to be interpreted as local time in modern browsers )

My other thought was to post-process the API response on the client side (essentially, to manually parse all the string dates coming back from the API using e.g. moment.js), but I'd like to avoid the client-side perf impact of combing through a huge object graph and finding all dates.

I am guessing this is not a new or particularly unique problem. Are there other solutions that I'm overlooking? How do I communicate date-only fields from the server to browser clients while keeping the date timezone-agnostic?

Community
  • 1
  • 1
Eugene Osovetsky
  • 6,443
  • 2
  • 38
  • 59

2 Answers2

0

In the JSON, the best advice is to stick with ISO8601 standards. For a date without a time, that would be YYYY-MM-DD, such as:

{
    "fooDate" : "2015-12-15"
}

There are many reasons for this, but in general you should send data over the wire in a standards-compliant format such that the intent is clear. That some parsers (whether JavaScript, browser, or otherwise) might interpret it wrong is something to adjust for in that environment, not in the serialization.

So, if you're receiving this in the browser, you can either string-replace hyphens with slashes (per my answer to your other question and shown here also), or parse with a library like moment.js, or split the string by hyphens and built the date from parts (being careful to subtract 1 from the month if you're sending into the Date constructor).

Another point to consider, your back-end platform might not use the date-only form by default. For example, if you use DateTime in .NET to store a date-only value, it is treated as a date-at-midnight. So the serialization might end up including time, which you don't want in your scenario. For .NET developers, use LocalDate from NodaTime, or wait for System.Date from CoreFXLab to get to production-ready status.

Other platforms may have similar issues, but the point is that if time isn't meaningful in your data, then it should not be sent. Don't send "2015-12-15T00:00:00" when you actually mean "2015-12-15". They are two different concepts.

Community
  • 1
  • 1
Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
0

We have a similar application where we have something called an "Inspection Date" that is just supposed to be a date with no time. Our application runs across multiple countries and time zones and we wanted to show the same date to all users.

When using a date without the time, most browsers and server systems will assume the time to be 00:00:00. On the server, our application stores all times in UTC and users always see local times in their browsers.

The issue we had was that some users would see the previous date as the Inspection Date as they were in the western hemisphere.

Think about it - a simple date, lets say 18th December 2015, is actually not complete information until you state the location of that date as well. It is right now 18th in Japan, but still 17th in the United States.

We then realized that we could simply ignore the time zone by converting the date to a string (right on the server) and displaying it to the users. But then, what does it mean to a user in the United States when I tell him that an inspection happened on the 18th (in Japan), which would be the future for him? As far as he is concerned, the inspection happened on the 17th.

A string solution wouldn't work for us. We settled with the next best option: Assign a time of 12:00pm to the date based on the time zone it was carried out in. This gave us the best approximation and everybody was happy. Users close to the time zone where the inspection happened saw the correct date and users on the opposite side saw the correct date too (as per them). :)

navigator
  • 1,678
  • 16
  • 29