Need format my date
When I try do following:
var d = new Date('15.01.2019');
console.log(d);
I get 'Invalid Date' message
If there is other date, for example '01.15.2019' all is correct
How can I solve this problem?
The constructor new Date(dateString) uses the Date.parse() method for parsing the date string. According to documentation of this method, you should use an ISO 8601 compliant date, or a simplification of ISO 8601, which in your case would be YEAR-MONTH-DAY, for example, 2015-01-15.
Other formats may work but are not reliable, as per the documentation:
"Other formats are accepted, but results are implementation-dependent."
It means that using date strings that are not ISO 8601 compliant or simplifications may result in different behaviour across different JavaScript engines and web browsers. It may also vary with the user set's locale.
Use an ISO 8601 simplified string and you will be fine.
Related
I tried with two methods to generate Date first by passing whole date string and second with year, month, day combination. But I am getting different outputs while the same date is being provided. The Day is not right. It should be 30 June in the first too.
const oldDate = new Date('2020-06-30');
const newDate = new Date('2020', '05', '30');
console.log(oldDate.toString(), newDate.toString());
When you instantiate a Date by passing a string, it's supposed to be a full ISO 8601 string which specifies the time zone. As you dont specify it, it takes GMT+0, and you seem to be located at GMT-7. You should write this instead:
console.log(new Date('2020-06-30T00:00:00-07:00').toString());
The Date constructor that accepts multiple arguments expects them to be numbers, and accepts the month number as a 0-based value (0 = January). The values are expected to be in local time.
The Date constructor accepting a single string argument parses the string according to the specified rules (which apply to your example) and, possibly, unspecified fallback rules the JavaScript engine implementer chose to add (in your case, though, the fallback isn't necessary). When there's no timezone indicator on the string, Date-only forms such as yours are parsed in UTC (date/time forms are parsed in local time).
(The Date constructor accepting a single number expects that number to be milliseconds-since-The-Epoch [Jan 1st, 1970 at midnight, UTC].)
Below format is considered as GMT time and it tries to convert to your local timezone. That's why you notice 7 hours subtracted.
new Date('2020-06-30')
whereas,
Below format is considered as local timezone and no further conversion happen.
new Date('2020', '05', '30');
According to MDN docs:
dateString
A string value representing a date, specified in a format recognized by the Date.parse() method. (These formats are IETF-compliant RFC 2822 timestamps, and also strings in a version of ISO8601.)
Note: Parsing of date strings with the Date constructor (and Date.parse(), which works the same way) is strongly discouraged due to browser differences and inconsistencies.
Support for RFC 2822 format strings is by convention only.
Support for ISO 8601 formats differs in that date-only strings (e.g. "1970-01-01") are treated as UTC, not local.
Therefore, when you create date via new Date("2020-06-30") it creates date object in 0 timezone and adjusts time to show it equal to your time zone.
I am trying to parse the String date format(yyyyMMddThhmmssZ) to Date.
const date = Date.parse("20171201T120000Z");
console.log(date );
Result is ...
NaN
Could you teach me the smartest way?
Ideally, you should try to standardize the date string in a way that works best for your needs. As the MDN states, parsing a date from a string is problematic in general.
Date.parse()
Note: Parsing of strings with Date.parse is strongly discouraged due to browser differences and inconsistencies.
Although your date format is valid ISO 8601 as illustrated in the comments by #duskwuff, it is not supported by Date.parse.
It seems the version specified here by ECMAScript is supported, YYYY-MM-DDTHH:mm:ss.sssZ, but not a format like 20180131T011614Z as you are using. It seems Date.parse only supports a simplification of the ISO 8601 format.
A library like moment.js is helpful as it can parse a wide range of date formats automatically (including your valid ISO 8601 date) or you can even specify your date format explicitly if you wanted.
moment('20171201T120000Z', 'YYYYMMDDTHHmmssZ').toString()
"Fri Dec 01 2017 06:00:00 GMT-0600"
moment('20171201T120000Z').toString()
"Fri Dec 01 2017 06:00:00 GMT-0600"
Though, for your example, you could parse out the date without moment.js
let dateString = '20171201T120000Z'
let [_, year, month, day, hour, min, sec] = dateString.match(/(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})/)
// month is 0-based so subtract 1
new Date(year, month - 1, day, hour, min, sec)
Could you teach me the smartest way?
I would say the "smartest way" can vary wildly based on your circumstances.
Do you control the source of these date strings?
Are the date strings coming from another system?
Are users entering these date strings?
As long as you use some standard (even if it's not supported directly by Date.parse), then I would say the parsing can be done with whatever method works best for you. A library like moment, manually parsing the elements of the date, translating your date to epoch or a format recognized by Date.parse, or whatever you prefer.
If I use new Date('2015-01-01'), will that give me a point in time equivalent to 2015-01-01T00:00:00Z?
From documentation:
constructors: ... dateString 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).
From documentation on Date.parse():
If a time zone is not specified and the string is in an ISO format
recognized by ES5, UTC is assumed
However, depending on this behaviour could be risky, as, from the same document:
note that ECMAScript ed 6 draft specifies that date time strings without a time zone are to be treated as local, not UTC
Here are my dates, to me there is no different whatsoever. Yet moment can't handle them all:
console.info(details.date);
console.info(moment(details.date).format());
console.info('________________________________________');
result.date = moment(details.date, "DD-MM-YYYY H:m").format();
//Console
________________________________________
16/10/10 15:00
Invalid date
________________________________________
09/10/10 15:00
2010-09-10T15:00:00+01:00
How can I make my dates safe.
It appears Moment is using the American Date convention, despite it not being documented in there moment(string) interface.
A simple example is here
According to the documentation for moment(string), if a format is not provided when parsing a string it will first try to match one of the ISO 8601 formats specified in ECMA-262. Failing that, it will simply pass the string to new Date(string), which is the same as using Date.parse.
So the result is entirely implementation dependent. However, most browsers will treat nn/nn/nn as a US style date with two digit year, i.e. mm/dd/yy. But that is not guaranteed and may change from browser to browser.
The fix is to always pass the format when parsing strings.
In the second example, the format specified doesn't match the string supplied. It seems it falls back to Date.parse in this case also.
Your date format string uses hyphons ("-") and actual date uses slashes ("/"), so Moment.Js is unable to parse it. Works fine in following example
$("body").text(moment("16/10/10 15:00", "DD/MM/YY H:m").format())
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"></script>
How do I convert a date string coming from a database into a new Date() object?
If I do the following:
var x = new Date('2013-11-05 11:01:46:0');
alert(x);
It works in Chrome, but in Safari it gives me the string "Invalid Date".
Here's the fiddle.
The format of strings accepted by new Date(string) is implementation-dependent. If the browser correctly implements the ES5 specification, however, a strict subset of legal ISO 8601 strings should be accepted. Basically, you need to use UTC instead of local time, put a "T" instead of a space between the date and time, use a decimal point instead of a colon between integral and fractional seconds, and append a "Z" on the end of the whole thing:
2013-11-05T11:01:46.000Z
Perhaps you can get your database to output the dates in that format; otherwise, you should look into a third-party library, such as moment.js.