-1

I have a date like the following:

2016-04-13T09:57:21-04

I am trying to cast this to a javascript date:

event.timestamp = new Date(event.timestamp);

where event.timestamp is a string representation of the date. The problem is that this is set as converted to undefined. I am almost certain that my datetime is a valid ISO format. What am I doing wrong here?

Edit

Some have noted that the datetime is not valid, and I agree that javascript does not consider it so, but I generate the datetime from a Scala API call

using jodatime:

DateTime.now()

So this will generate a valid datetime (at least for scala). The -04 is the offset. I am not arguing that the date time is or is not valid in Javascript, because that is obvious. I am curious if there is a way to make it valid for javascript, because the jodatime date library seems pretty standard in Java and Scala and I am assuming there is a way to make it work with JavaScript.

Edit 2 Thriggle's answer is correct, but you cal also use Moment to get the date in a correct format:

moment(event.timestamp, "YYYY-MM-DD HH:mm Z").toDate();

moment can read a datetime in the format I have (2016-04-13T09:57:21-04)

Soatl
  • 10,224
  • 28
  • 95
  • 153
  • The date is invalid. Try new Date("2016-04-13T09:57:21-04"); and see for yourself. The problem is `-04` did you want to set the timezone? – Ibu Apr 13 '16 at 18:21
  • What is '-04' at the end of date? See this link - http://stackoverflow.com/questions/21826161/invalid-date-for-a-new-dateyyyy-mm-ddthhmmss-instanciation?rq=1 – sam Apr 13 '16 at 18:23
  • The -04 is the offset – Soatl Apr 13 '16 at 18:25
  • 1
    Note that even with moment.js you are still not parsing the string correctly, it's being treated as local (perhaps you are in timezone UTC-0400 so don't notice that). – RobG Apr 13 '16 at 22:33

2 Answers2

4

A date time string should be a simplification of the ISO 8601 extended format: YYYY-MM-DDTHH:mm:ss.sssZ

From the ECMAScript 2015 spec:

Z is the time zone offset specified as “Z” (for UTC) or either “+” or “-” followed by a time expression HH:mm

Therefore, your value should be 2016-04-13T09:57:21-04:00

Edit: As RobG astutely points out in the comments, ECMAScript 2015 only specifies that Date Time strings follow the ISO 8601 format; the IETF-compliant RFC 2822 timestamp is not part of the specification, though at the time of this post it is included in the MDN documentation.

Community
  • 1
  • 1
Thriggle
  • 7,009
  • 2
  • 26
  • 37
  • Thats not what the Scala app is giving me. Do I need to convert every datetime I will get in Scala to a different string to work with javascript? – Soatl Apr 13 '16 at 18:30
  • @PepperedLemons Unless there's a way to get the Scala application to give you the full ISO date string with the minutes included, you'll need to convert the string to a valid value before plugging it directly into JavaScript. – Thriggle Apr 13 '16 at 18:37
  • Fair enough. I can get around it with Moment. Thanks for the help – Soatl Apr 13 '16 at 18:41
  • @PepperedLemons You're welcome! It might be worth posting a new question to see if there's a way to get the full ISO string from a date in Scala/Java, timezone offset minutes included. – Thriggle Apr 13 '16 at 18:47
  • 1
    @Thriggle [Already asked and answered](http://stackoverflow.com/q/13545735/642706), regarding getting current date-time as an ISO 8601 string in Java. – Basil Bourque Apr 13 '16 at 20:39
  • 1
    @Thriggle The date-time handling in JavaScript is quite limited and weak as with nearly every programming platform. The Joda-Time library in Java was the first successful attempt at handling date-time in a sophisticated way. Later ported to .Net as NodaTime. Joda-Time has now been supplanted by the java.time framework built into Java 8 and later, with backports to Java 6 & 7 and to Android. – Basil Bourque Apr 13 '16 at 20:44
1

It is strongly recommended that you do not use the Date constructor or Date.parse to parse strings. The behaviour is largely implementation dependent and inconsistent. You should use a parser from a library or if you only have one or two formats to support, write your own parser (3 or 4 lines of code with validation).

In the case of using moment.js:

moment(event.timestamp, "YYYY-MM-DD HH:mm Z").toDate();

with a string of

"2016-04-13T09:57:21-04"

the format is incorrectly specified (the seconds are missing) so it is not being parsed correctly (the seconds are set to zero). Also, the time zone is specified as GMT, which it isn't, but since the offset isn't included in the format the string is being parsed as local.

So regardless of the user time zone, all users will see exactly the same date and time, but with their host time zone offset (so a different moment in time for each different offset).

According to the moment.js documentation, it should parse the string correctly given:

moment('2016-04-13T09:57:21-04', "YYYY-MM-DD HH:mm:ssZZ").toDate();

however it doesn't. The only way to get moment.js to parse it correctly is either:

moment('2016-04-13T09:57:21-0400', "YYYY-MM-DD HH:mm:ssZZ").toDate());

or

moment('2016-04-13T09:57:21-0400').toDate());

i.e. to add "00" to the timezone offset.

The first method where the format is passed is much preferred, otherwise you are depending on moment.js just trying different formats until one returns a valid date or giving it to Date.parse.

RobG
  • 142,382
  • 31
  • 172
  • 209