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.
Related
This question already has answers here:
What are valid Date Time Strings in JavaScript?
(2 answers)
Closed 3 years ago.
I have two dates both in a valid ISO-8601 format and I'm trying to convert them to a Date object.
console.log(new Date('2019-08-03T18:17:28.119Z'));
console.log(new Date('2019-05-09T08:25:22+0000'));
Output1: Sat Aug 03 2019 20:17:28 GMT+0200 (CEST)
Output2: Invalid Date
How come JavaScript doesn't recognize the second date as a valid ISO-8601 format?
How can I create a Date object out of that format?
ECMA-262 requires that anything that doesn't conform to its version of ISO 8601 is implementation dependent. Formats that are close but not precise are likely to result in an invalid date in at least some browsers. Others may be more tolerant.
In this case, the offset "+0000" should be "+00:00". Similarly, replacing the "T" with a space may result in an invalid date, or not, depending on the implementation.
// Invalid date maybe
console.log(new Date('2019-05-09T08:25:22+0000').toString());
// valid
console.log(new Date('2019-05-09T08:25:22+00:00').toString());
To parse the problematic format, either add the missing colon before parsing, or (preferably) either write your own parse function (not difficult) or use a library (there are many good ones to chose from).
Also see Why does Date.parse give incorrect results?
I have the string "18/04/19 5:17 PM EDT" which represents a date.
I'm using moment and the add-on moment-timezone and I need to convert this sting into a timestamp.
I'm trying something as:
var date = moment("18/04/19 5:17 PM EDT").format('DD/MM/YY h:m a z');
alert(date);
But this is not working and saying "invalid date".
Please note that moment(String):
When creating a moment from a string, we first check if the string matches known ISO 8601 formats, we then check if the string matches the RFC 2822 Date time format before dropping to the fall back of new Date(string) if a known format is not found.
Warning: Browser support for parsing strings is inconsistent. Because there is no specification on which formats should be supported, what works in some browsers will not work in other browsers.
For consistent results parsing anything other than ISO 8601 strings, you should use String + Format.
so you are getting Invalid Date because your input is neither in ISO 8601 nor RFC 2822 recognized format, then you have to provide format parameter when parsing it.
moment(String, String) does not accept 'z' token, so you have to use moment-timezone to parse your input using zone, see Parsing in Zone docs:
The moment.tz constructor takes all the same arguments as the moment constructor, but uses the last argument as a time zone identifier.
You can use format() and other methods listed in the Displaying section of the docs (e.g. valueOf()) to display the value of a moment object.
Here a live sample:
var date = moment.tz("18/04/19 5:17 PM EDT", 'DD/MM/YY h:m A', 'America/New_York');
console.log(date.valueOf()); // 1555622220000
console.log(date.format()); // 2019-04-18T17:17:00-04:00
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data-2012-2022.min.js"></script>
As a side note, remeber that time zone abbreviations are ambiguous, see here for additional info.
(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.
The return value for (new Date()).toDateString() is "Mon Oct 08 2012". However I can't find ANY documentation anywhere for what the abbreviations for the rest of the days of the week and months are. Are they all just 3 character abbreviations? I'm trying to write a regex.
+1million points for someone who can find the documentation, or even the source code?
Three letter abbreviations with the first letter upper case.
Months: Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
Days: Sun, Mon, Tue, Wed, Thu, Fri, Sat
However, you may want to look into Date.Parse() instead of using a regular expression to parse the date string, depending on what you're doing anyway.
EDIT: Beware that that Date.Parse() is fairly browser dependent. Check out Why does Date.parse give incorrect results?
It's just the standard English language abbreviation for days and months. Just the first 3 letters and the first one capitalized.
From the MDN:
Date instances refer to a specific point in time. Calling toString
will return the date formatted in a human readable form in American
English
It's not hard to find:
W3Schools: http://www.w3schools.com/jsref/jsref_todatestring.asp
Mozilla Developer Network: link
Microsoft Developer Network: link
As you can see, all of them converge, its the week day, the month name, both with 3 characters, day of month and full year.
The specification does not define the output of the string:
The contents of the String are implementation-dependent, but are intended to represent the "date" portion of the Date in the current time zone in a convenient, human-readable form.
This might change in the future, but for now, each browser/environment can produce a different output.
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.