(new Date('2012-12-01')).getMonth() is 10 instead of 11 (getMonth is 0-indexed). I've tested on Firefox, Chrome, and Node.js. Why does this happen?
You are experiencing a timezone issue. Your JS engine interprets the string as UTC, since it was no further specified. From the specification of Date.parse (which is used by new Date):
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.
In your timezone, the datetime is Nov 30 2012 19:00:00 GMT-0500 - in November. Use .getUTCMonth() and you would get December. However, never trust Date.parse, every browser does it differently. So if you are not in a restricted environments like Node.js, you always should parse your string (e.g. with regex) and feed it to new Date(Date.UTC(year, month, date, …)).
For Firefox's case, at least, RFC2822 states that date specifications must be separated by Folding White Space. Try (new Date('2012 12 01')).getMonth(); Usage of - as a separator does not appear to be defined.
The error is arising from prefixing the day 01 with 0. Not sure WHY this is, but if you remove the zero before the 1, it gives you the right month (11).
Also, it starts giving the wrong month at October if that means anything.
Short term fix, use 1 instead of 01.
Related
I am trying to parse a date in JavaScript, but the particular format is giving me fits. I have exported data from my credit card company and the format of the date field is not compatible with Date.parse or moment().isValid().
E.g.
Date.parse("01/01/2016 Fri") // NaN
moment("01/01/2016 Fri") // false
I'm not sure if I should do something with a RegEx .test() or .matches() because this is being used for a CSV import utility where dates may be in different formats. I was surprised the utility functions above didn't work.
Look in the Moment docs to see how to parse a date in any format. The first argument is the date string, the second is the format string. Alphanumeric characters are ignored, so you don't need to worry about slashes vs. dashes.
moment("01/01/2016 Fri", "MM-DD-YYYY ddd)
Check out the Mozilla MDN on Date.parse():
The parse() method takes a date string (such as "Dec 25, 1995") and
returns the number of milliseconds since January 1, 1970, 00:00:00
UTC. This function is useful for setting date values based on string
values, for example in conjunction with the setTime() method and the
Date object.
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 +0430" (4 hours, 30 minutes
east of the Greenwich meridian).
From this, it looks like your problem is that you're giving the date in the improper format:
It
accepts the RFC2822 / IETF date syntax (RFC2822 Section 3.3), e.g.
"Mon, 25 Dec 1995 13:30:00 GMT".
Check this out:
Invalid values in date strings not recognized as ISO format as defined by ECMA-262 may or may not result in NaN, depending on the browser and values provided, e.g.:
// Non-ISO string with invalid date values
new Date('23/25/2014');
TL;DR - you're passing the values in a format that is not recognized, which is why it's returning NaN.
Try this source for Regexes for dates: Regexlib.com. The site is a little out of date, but the info is great. It has tons of different Regexes for different date formats.
With ISO 8601 string, I'm using Moment js and currently doing moment("2014-05-08T00:20:40Z").format("HH:mm:ss") to simply get string time of "00:20:40", bu
Your ISO date is a UTC date. That's what the Z at the end means. So you are 7 time zones west of UTC.
The time you start with is 20 minutes after midnight on the 8th. If you ran your code in Paris, France, you'd get the right answer (ignoring "summer time" adjustment). However, since you're 7 time zones west, you get 5:20 in the afternoon, and you're still in the previous calendar day.
By one way of looking at things, there's nothing to "fix". The local time version based on where you are represents the same point in time as the original ISO UTC time. Everything is working properly; the default representation of date values is in local time. The Date primitive object in JavaScript has APIs to access the components in UTC terms if you want to go that way.
You can use .toISOString() if you want to get the original ISO string back:
moment("2014-05-08T00:20:40Z").toISOString()
Or, you can include a time zone tag in your format string:
moment("2014-05-08T00:20:40Z").format("HH:mm:ss zz")
(Note that the "z" in the format string doesn't mean the same thing as the "Z" in the ISO time. It's just the formatting special character, from the first letter of the word "zone". In the ISO string, it's the first letter of the word "zero", and it means that the time is at zero offset from UTC time. Some people call it "Zulu Time" because of that "Z".)
On W3Schools, they showed entering a short date format with "/" as follows,
new Date("03/25/2015"). I tried replacing the "/" with "-" as follows,
new Date("03-25-2015") and that worked too. However, in reading through the website, I couldn't find that being mentioned as a valid alternative.
Is it? Even though it worked, is there any reason I should not use it and use the forward slash instead?
If you try using new Date("03-25-2015") in Firefox, you'll get an "invalid date" message. So essentially, using dashes does not work across all browsers. It's better to stick with forward slashes (/).
The same goes with periods between the dates new Date("03.25.2015") is invalid in Firefox but not in Chrome.
According to the ES5 spec, when the Date constructor is passed a string, it will use the same logic as Date.parse:
Let v be ToPrimitive(value).
If Type(v) is String, then
a. 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.
Date.parse uses the Date Time String Format first, implementation-specific heuristics second:
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.
The Date Time String Format is YYYY-MM-DDTHH:mm:ss.sssZ. YYYY, YYYY-MM and YYYY-MM-DD are also valid.
As Mottie notes, new Date("03-25-2015") fails in Firefox. However, this is only partly due to the hyphens. If you move the year to the front (new Date("2015-03-25")) the date string will conform to the Date Time String it succeeds.
From MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
One of the ways to create a new Date object is by new Date(dateString);. dateString is described as:
String value representing a date. The string should be in a format recognized by
the Date.parse() method (IETF-compliant RFC 2822 timestamps and also a
version of ISO8601).
Note: parsing of date strings with the Date constructor (and Date.parse, they are equivalent) is strongly discouraged due to
browser differences and inconsistencies.
This method of creating a new Date object uses the Date.parse() method to parse the dateString string.
From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse
Date.parse() is defined:
The Date.parse() method parses a string representation of a date, and
returns the number of milliseconds since January 1, 1970, 00:00:00 UTC
or NaN if the string is unrecognised or, in some cases, contains
illegal date values (e.g. 2015-02-31).
ECMAScript 5 ISO-8601 format support
The date time string may be in ISO 8601 format. For example, "2011-10-10" (just date) or
"2011-10-10T14:48:00" (date and time) can be passed and parsed. Where
the string is ISO 8601 date only, the UTC time zone is used to
interpret arguments. If the string is date and time in ISO 8601
format, it will be treated as local.
Therefore, the syntax you used, i.e. new Date("03-25-2015"), is valid syntax, but discouraged due to browser differences and inconsistencies.
When you have questions like this, you should usually go straight to the canonical source to find out. In this case, the canonical source for JavaScript is the EMCAScript specification.
The relevant section is:
http://www.ecma-international.org/ecma-262/6.0/#sec-date.parse
It states:
Date.parse ( string )
[...]
The function first attempts to parse the format of the String according to the rules (including extended years) called out in Date Time String Format (20.3.1.16). If the String does not conform to that format the function may fall back to any implementation-specific heuristics or implementation-specific date formats.
In other words, the only formats guaranteed to be supported across all implementations are listed in Date Time String Format (20.3.1.16). Any formats other than those may or may not work depending on the implementation, and therefore should not be used.
To simplify section 20.3.1.16, the only valid format for dates is YYYY-MM-DD. Not surprisingly, W3Schools used an invalid format in their example.
An alternative source for JavaScript documentation is Mozilla Developer Network (MDN). It is not the canonical source, but is much higher quality than W3Schools and includes direct links to the canonical sources at the bottom of articles.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
I just found a date format in a javascript document that I have never seen before. It looks like this:
'1978-11-23T00:00:01.000Z'
Can someone explain what that 'T' and 'Z' mean?
Can someone explain what that 'T' and 'Z' mean?
The T is the delimiter between the date and time. The Z is a timezone, specifically timezone "Zulu" (GMT+00:00, e.g., Greenwich mean time). As of the latest specification (ES5), JavaScript has a standard date/time format which is derived from a simplified version of ISO 8601 (although it handles the absence of a timezone differently from the ISO standard). (Prior to ES5, there was no standard string form for dates in JavaScript at all, amazingly.)
How to interpret this date format?
If you're using an engine that implements this part of ES5, you can just pass that string into the Date(value) constructor:
var dt = new Date('1978-11-23T00:00:01.000Z');
If you're using an engine that doesn't yet implement this part of the standard (IE8 or earlier, for instance), you'll have to use a regular expression to break out the individual parts of the string, convert them to numbers, and feed them into the Date(year, month, date, hours, minutes, seconds, ms) constructor, or use an add-on library to parse it for you.
Why Date.parse("2011-11-15") considers current time zone in Web browser, and Date.parse("2011/11/15") does not? Why the results are different?
The first form is being considered as an ISO date in UTC, according to section 15.9.1.15 of ECMA-262. The second form is being considered in an implementation-specific way, as per section 15.9.4.2:
The parse function applies the ToString operator to its argument and interprets the resulting String as a date
and time; it returns a Number, the UTC time value corresponding to the date and time. 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
So I suspect "2011/11/15" is being converted to the local midnight of November 15th, whereas "2011-11-15" is being converted to UTC midnight of November 15th.
from date.parse documentation
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. Timezones in ISO dates are not yet
supported, so e.g. "2011-10-10T14:48:00+0200" (with timezone) does not
give the intended result yet.