I tested the following code in firefox scratchpad and got interesting result?
var date=new Date("2012-05-12");
var date2 = new Date("05/12/2012");
date;
/*
Fri May 11 2012 17:00:00 GMT-0700 (Pacific Daylight Time)
*/
date2;
/*
Sat May 12 2012 00:00:00 GMT-0700 (Pacific Daylight Time)
*/
Two dates are different. Apparently this is due to the timezone issue. What I want is date2 result. How can I make js engine correctly treats the ISO date style?
I think the issue is that the string "2012-05-12" is taken to be an ISO 8601 date, while "05/12/2012" is an RFC 2822 date. In the ISO format, the lack of a timezone implies UTC. At midnight on the morning off May 12, in California (or wherever you are) it's 7 PM the previous evening.
The RFC date without a time zone, however, is parsed under the assumption that you want the timestamp for midnight in your local timezone. (Well, not necessarily your timezone; the timezone of the computer where your JavaScript runs :-)
You can see the difference if you pass those strings to Date.parse().
The RFC date format can include an explicit time zone, but the ISO format cannot. (Well, it can, but browsers don't pay attention, and apparently IE doesn't handle those at all.)
edit — here's a simple (dumb; no error checking) function that'll give you a date from that 3-part ISO form:
function isoDate( str ) {
var rv = null;
str.replace(/^(\d\d\d\d)-(\d\d)-(\d\d)$/, function(_, yr, mn, dy) {
rv = new Date(parseInt(yr, 10), parseInt(mn, 10) - 1, parseInt(dy, 10));
});
return rv;
}
By the standard, with Date(), you can parse ISO dates or dates in an implementation-dependent format, in an an implementation-dependent manner. To get anything more reliable, use a suitable library that can parse dates in some known formats.
Related
I have this problem.
I have this date with this format
var datestring = "2017-10-30T15:03:10.933044Z";
If I write my code like this
var d = new Date(datestring);
I obtaine
Mon Oct 30 2017 16:03:10 GMT+0100 (ora solare Europa occidentale)
because there is one hour of a daylight in italy now. Nevertheless, I would like to have the same hour of 'datestring' (15, and not 16).
Could you help me?
thank you very much
According to ECMA-262, if you want to treat an ISO 8601 format UTC timestamp as local, just remove the Z. However, it will now represent a different moment in time if the local timezone is not GMT+0000.
Also, using the built-in parser is not recommended (see Why does Date.parse give incorrect results?), as some browsers will still treat it as UTC (e.g. Safari 11) or perhaps invalid. You should either write your own function to parse the string, or use a library. There are plenty of good parsing and formatting libraries available.
var s = '2017-10-30T15:03:10.933044Z';
var d = new Date(s.replace(/z/i,''));
console.log(d.toString());
Your input string is in ISO-8601 format. In this format, the Z at the end means the timestamp is UTC-based.
You can obtain a more human-friendly UTC-based string representation with the .toUTCString() method.
var datestring = "2017-10-30T15:03:10.933044Z";
var d = new Date(datestring);
var s = d.toUTCString();
console.log(s) // "Mon, 30 Oct 2017 15:03:10 GMT"
If you want the string in a specific format, then consider using a library like Moment.js.
Why do I get 2 different dates with new Date() when I pass a date vs. when I pass a date and time?
example:
Date.parse('2015-03-14')
// 1426291200000
new Date(1426291200000)
// Fri Mar 13 2015 17:00:00 GMT-0700 (PDT)
Date.parse('2015-03-14 00:00:00')
// 1426316400000
new Date(1426291400000)
// Fri Mar 13 2015 17:03:20 GMT-0700 (PDT)
Sorry but I cannot comment yet. The string you pass in Date.parse() must follow the
ECMAScript 5 ISO-8601 format support
.Reference link here
format specified in ECMAScript 2015
According to that, you the format of Date with time must be: '2015-03-14T00:00:00' instead of '2015-03-14 00:00:00'.
And since the time of Date.parse('2015-03-14') is at GMT+00 but Date.parse('2015-03-14T00:00:00') is at your time zone so if you add timezone GMT+00 to the second two time will be equal:
Date.parse('2015-03-14');
Date.parse('2015-03-14T00:00:00+00:00');
//1426291200000
Why do I get 2 different dates with new Date() when I pass a date vs. when I pass a date and time?
Because parsing strings with the Date constructor (and Date.parse, they are equivalent) is largely implementation dependent and therefore strongly recommended against.
Date.parse('2015-03-14')
// 1426291200000
new Date(1426291200000)
// Fri Mar 13 2015 17:00:00 GMT-0700 (PDT)
ISO 8601 format dates are treated as UTC in browsers compliant with ES5 and later (and UTC, local or invalid by earlier implementations), however not all browsers are compliant. Also, the specified behaviour is inconsistent with ISO 8601, which specifies that dates without a time zone are to be treated as local.
Date.parse('2015-03-14 00:00:00')
// 1426316400000
new Date(1426291400000)
// Fri Mar 13 2015 17:03:20 GMT-0700 (PDT)
The string '2015-03-14 00:00:00' is not compliant with ISO 8601, therefore parsing is entirely implementation dependent and may be treated as UTC, local or invalid. If made compliant with the addition of a "T":
"2015-03-14T00:00:00"
it should be treated as local (noting the previously mentioned caveat about non–compliant implementations).
It is very strongly recommended that you always manually parse strings. Use a library, one of the many good parsers that are around or just write your own function, 2 or 3 lines should suffice.
I am trying to convert datetime value from this format Wed Mar 9 09:48:09 PST 2016 into the following format YYYY-MM-DD HH:mm:ss
I tried to use moment but it is giving me a warning.
"Deprecation warning: moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.
Arguments: [object Object]
fa/<#http://localhost:1820/Resources/Scripts/Plugins/moment.min.js:7:9493
ia#http://localhost:1820/Resources/Scripts/Plugins/moment.min.js:7:10363
Ca#http://localhost:1820/Resources/Scripts/Plugins/moment.min.js:7:15185
Ba#http://localhost:1820/Resources/Scripts/Plugins/moment.min.js:7:15024
Aa#http://localhost:1820/Resources/Scripts/Plugins/moment.min.js:7:14677
Da#http://localhost:1820/Resources/Scripts/Plugins/moment.min.js:7:15569
Ea#http://localhost:1820/Resources/Scripts/Plugins/moment.min.js:7:15610
a#http://localhost:1820/Resources/Scripts/Plugins/moment.min.js:7:41
#http://localhost:1820/Home/Test:89:29
jQuery.event.dispatch#http://localhost:1820/Resources/Scripts/Jquery/jquery.min.js:5225:16
jQuery.event.add/elemData.handle#http://localhost:1820/Resources/Scripts/Jquery/jquery.min.js:4878:6
"
according to https://github.com/moment/moment/issues/1407 I should not be trying to use moment() to do this since it is not reliable.
How can I reliably convert the Wed Mar 9 09:48:09 PST 2016 into the following format YYYY-MM-DD HH:mm:ss?
You could try using Date.toJSON() , String.prototype.replace() , trim()
var date = new Date("Wed Mar 9 09:48:09 PST 2016").toJSON()
.replace(/(T)|(\..+$)/g, function(match, p1, p2) {
return match === p1 ? " " : ""
});
console.log(date);
Since you tagged your question with moment, I'll answer using moment.
First, the deprecation is because you are parsing a date string without supplying a format specification, and the string is not one of the standard ISO 8601 formats that moment can recognize directly. Use a format specifier and it will work just fine.
var m = moment("Wed Mar 9 09:48:09 PST 2016","ddd MMM D HH:mm:ss zz YYYY");
var s = m.format("YYYY-MM-DD HH:mm:ss"); // "2016-03-09 09:48:09"
Secondly, recognize that in the above code, zz is just a placeholder. Moment does not actually interpret time zone abbreviations because there are just too many ambiguities ("CST" has 5 different meanings). If you needed to interpret this as -08:00, then you'd have to do some string replacements on your own.
Fortunately, it would appear (at least from what you asked) that you don't want any time zone conversions at all, and thus the above code will do the job.
What's going on here:
> new Date('Apr 15 2013');
Mon Apr 15 2013 00:00:00 GMT+0100 (GMT Daylight Time)
> new Date('04/15/2013');
Mon Apr 15 2013 00:00:00 GMT+0100 (GMT Daylight Time)
> new Date('2013-04-15');
Mon Apr 15 2013 01:00:00 GMT+0100 (GMT Daylight Time)
Obviously, one is being interpreted as UTC time, while the other two are being interpreted as local time. What causes the difference in parsing?
From the specification:
The String may be interpreted as a local time, a UTC time, or a time in some other time zone, depending on the contents of the String. The function first attempts to parse the format of the String according to the rules called out in Date Time String Format (15.9.1.15). If the String does not conform to that format the function may fall back to any implementation-specific heuristics or implementation-specific date formats.
Of all the formats you provided, only '2013-04-15' is officially supported, so the others seem to fall back to implementation-dependent behavior.
Your third example is the only one that is actually explained by the spec. When you call the Date constructor with a single argument, this is what happens (where v is the string passed to the constructor):
Parse v as a date, in exactly the same manner as for the parse method (15.9.4.2); let V be the time value for this date.
The parse method will attempt to parse the string (emphasis added):
The String may be interpreted as a local time, a UTC time, or a time in some other time zone, depending on the contents of the String. The function first attempts to parse the format of the String according to the rules called out in Date Time String Format (15.9.1.15).
If the String does not conform to that format the function may fall back to any implementation-specific heuristics or implementation-specific date formats.
And the "Date Time String Format" is YYYY-MM-DDTHH:mm:ss.sssZ, and also defines a shorter version of the form YYYY-MM-DD, which is what you use in your third example.
For the other examples, the parse will fail and the behaviour is implementation-defined.
The Date constructor delegates to Date.parse, and it appears that Date.parse has two variants:
Given a string representing a time, parse returns the time value. It
accepts the RFC2822 / IETF date syntax (RFC2822 Section 3.3), e.g.
"Mon, 25 Dec 1995 13:30:00 GMT". It understands the continental US
time-zone abbreviations, but for general use, use a time-zone offset,
for example, "Mon, 25 Dec 1995 13:30:00 GMT+0430" (4 hours, 30 minutes
east of the Greenwich meridian). If you do not specify a time zone,
the local time zone is assumed. GMT and UTC are considered equivalent.
Alternatively, the date/time string may be in
ISO 8601 format. Starting with JavaScript 1.8.5 (Firefox 4), a subset
of ISO 8601 is supported. For example, "2011-10-10" (just date) or
"2011-10-10T14:48:00 (date and time) can be passed and parsed.
Clearly, these behave differently with respect to local timezones
Edit: Looks like this is implementation defined
I know when constructing a Date object in JavaScript with a dateString parameter, the string must be something that parse() can recognize.
What date format can parse recognize?
For example:
var postDate = new Date("2011-03-08T23:52:38");
works in Chrome and Internet Explorer, but fails on an iPhone (returns Jan 1, 1970).
I cannot find any formal documentation on the .parse() method, or the constructor, about what the parameter should be.
The format yyyy-mm-ddThh:nn:ss doesn't work. What is the allowed format string?
The MDC documentation of Date.parse() states (quoting) :
It accepts the IETF standard (RFC
1123 Section 5.2.14 and elsewhere)
date syntax: "Mon, 25 Dec 1995 13:30:00 GMT".
OP Edit:
.NET syntax to create this datetime string:
/*
* r (RFC1123Pattern)
* ddd, dd MMM yyyy HH':'mm':'ss 'GMT'
* Mon, 15 Jun 2009 20:45:30 GMT
*/
dateTime.ToUniversalTime().ToString("r", CultureInfo.InvariantCulture); //"r" = RFC1123Pattern
Edit: The r (RFC1123 pattern) always appends "GMT", even though the time isn't GMT (it's local). You need to call .ToUniversalTime() first, in order to have the time actually be GMT.
Using the format that is produced by Date's toJSON method will work. This is the same as the toISOString method.
The date format is YYYY-MM-DDTHH:mm:ss.sssZ
Note: The time zone is always UTC as denoted by the suffix "Z".
var d = new Date();
console.log(d.toJSON());
console.log(d.toJSON() === d.toISOString());
console.log(Date.parse(d.toJSON()) === Date.parse(d.toISOString()));
You may find that the date shown isn't the same as on your clock; remember the time zone is UTC.
References:
Date.prototype.toJSON()
Date.prototype.toISOString()