I just found that if I use new Date('2015-1-1'), the time is no timezone effect, but If I use new Date('2015-01-01') the time has timezone effect in Node.js.
I output 4 Date():
console.log(new Date('2015-1-1'));
console.log(new Date('2015-01-1'));
console.log(new Date('2015-1-01'));
console.log(new Date('2015-01-01'));
the output is
Thu Jan 01 2015 00:00:00 GMT+0800 (CST)
Thu Jan 01 2015 00:00:00 GMT+0800 (CST)
Thu Jan 01 2015 00:00:00 GMT+0800 (CST)
Thu Jan 01 2015 08:00:00 GMT+0800 (CST)
you can see the last time is 08:00:00 because I'm in +8 timezone.
I think the output depends on the digit of the month or date number. When it's 10, 11 or 12 the output is always 08:00:00
I'm wondering why and if there is a better way to handle this except manually check the bit of month and date number?
Up to and including ECMA-262 ed 3, parsing of date strings was entirely implementation dependent. With ES5, ISO 8601 format strings without a timezone were to be parsed as UTC, however parsing any other type of date string is still implementation dependent.
With ECMAScript 2015, such strings without a timezone are to be parsed as local (i.e. with an offset based on system settings).
So it would seem that your Node.js implementation does not recognise the first 3 strings as ISO 8601 and so parses them according to some other internal logic that treats them as UTC.
The last string is seen as ISO 8601 compliant and so is parsed as local.
If you wish to parse all such strings as local, you can use a simple function like:
/* #param {string} s - date string in format yyyy-[m]m-[d]d
** #returns {Date} - a Date object for the specified date in a
** timezone based on system settings.
** Assumes that the string is a valid date.
*/
function parseISOLocal (s) {
var b = s.split(/\D/);
return new Date(b[0], b[1]-1, b[2]);
}
document.write(parseISOLocal('2015-1-1'))
Probably a bug, the best that you can do is to use a library like Moment that seems free from this:
moment('2015-1-1').toString()
moment('2015-1-01').toString()
moment('2015-01-1').toString()
moment('2015-01-01').toString()
prints:
"Thu Jan 01 2015 00:00:00 GMT+0100"
"Thu Jan 01 2015 00:00:00 GMT+0100"
"Thu Jan 01 2015 00:00:00 GMT+0100"
"Thu Jan 01 2015 00:00:00 GMT+0100"
Related
I have a Date format like this "Fri Apr 20 2020 00:00:00 GMT+0530 (India Standard Time)"
I want to convert that above format to this format 2020-04-20T00:00:00.000Z
Actually I tried this JSON.stringify(new Date("Fri Apr 20 2020 00:00:00 GMT+0530 (India Standard Time)")) while using this am getting the output one day before 2020-04-19T18:30:00.000Z
so please anyone help me to convert this date format "Fri Apr 20 2020 00:00:00 GMT+0530 (India Standard Time)" like this 2020-04-20T00:00:00.000Z
Thanks in Advance.
Your date seems to be a standard string representation of new Date(), you can get the desired format by using new Date().toISOString()
console.log(new Date().toString())
console.log(new Date().toISOString())
// To create it from string
const dateStr = "Fri Apr 20 2020 00:00:00 GMT+0530 (India Standard Time)"
console.log(new Date(dateStr).toISOString())
Anurag Srivastava's answer shows how you should parse the string and format it in the required format (given that the string is in one of the two formats supported by ECMA-262 and considering Why does Date.parse give incorrect results?).
Note that "Fri Apr 20 2020 00:00:00 GMT+0530 (India Standard Time)" is the same instant in time as "2020-04-19T18:30:00.000Z". The first string is offset from UTC by 5 hr 30 min, so the equivalent UTC time is 5 hr 30 min earlier, which means the date is the previous day.
You haven't given a reason why you want to treat it as UTC and not consider the offset, so I don't think you should.
However, if you do have a good reason to parse it as UTC and ignore the supplied offset, then you can either:
Modify the input string to set the offset as +0 and parse it using the built–in parser
Parse the string yourself and treat it as UTC
let s = "Fri Apr 20 2020 00:00:00 GMT+0530 (India Standard Time)";
// #1 Modify the input string, setting the offset to +0
let d = new Date(s.replace(/GMT.*$/,'GMT+0000')).toISOString();
console.log(d.toISOString());
// #2 Bespoke parser
function parseAsUTC(s) {
let months = ['jan','feb','mar','apr','may','jun',
'jul','aug','sep','oct','nov','dec'];
let b = s.split(/\W/);
return new Date(Date.UTC(b[3], months.indexOf(b[1].toLowerCase()),
b[2], b[4], b[5], b[6]));
}
console.log(parseAsUTC(s).toISOString());
I'm working with a date that looks like this:
Mon Feb 04 2019 15:57:02 GMT-0700 (Mountain Standard Time)
and I'm trying to convert it to this:
2019-02-04T15:57:02.000Z
but for some reason my code always adds 7 hours and ends up being like this:
"2019-02-05T22:57:02.000Z"
Can anyone tell me what I'm doing wrong? Thanks a lot in advance!
Here's my code:
new Date(myTime as string).toISOString();
I'd use Moment.js, which is a decent date parsing and formatting library. To get what you're looking for, you'd use a statement like:
console.log(moment
.parseZone(
"Mon Feb 04 2019 15:57:02 GMT-0700 (Mountain Standard Time)",
"ddd MMM DD YYYY HH:mm:ss 'GMT'ZZ") // the format of the string presented
.local()
.format('YYYY-MM-DDTHH:mm:ss')); // the format of the output
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
I've broken the single line out into parts so it's a bit easier to read. A few notes:
parseZone allows you to parse the "-0700" from the string.
local converts the date from the parsed time zone to the current time zone
format formats the date.
The format topic has a list of the formatting tokens used.
The Parse > String + Format topic lists the parsing tokens (which are the same as the formatting tokens for the most part).
Note that the output does not have a "Z" at the end; this is important because without the "Z", it is a local date. With the "Z" you are are actually specifying a date and time that is 7 hours earlier than the one you've been given.
I'm not sure how to get this as a one-liner, but this is one way:
var time = new Date('Mon Feb 04 2019 15:57:02 GMT-0700 (Mountain Standard Time)')
new Date(time.setHours(time.getHours() + 7)).toISOString()
"2019-02-05T12:57:02.000Z"
Your code is not adding hours to the input date. What is happening is that your date string is using a particular timezone GMT-0700 (Mountain Standard Time) and the time zone used in new Date().toISOString() is UTC GMT+0000 (UTC). So when in the Mountain Standard Time timezone is Mon Feb 04 2019 15:57:02, in the UTC timezone is actually 2019-02-05T22:57:02.000Z. There are your seven hours from GMT-0700 to GMT+0000.
EDITED
If you don't really care about time zones and want to obtain 2019-02-04T15:57:02.000Z from Mon Feb 04 2019 15:57:02 GMT-0700 (Mountain Standard Time) you could just strip everything after GMT to let new Date() think it is an UTC date.
var timeString = 'Mon Feb 04 2019 15:57:02 GMT-0700 (Mountain Standard Time)';
new Date(timeString.substr(0, timeString.indexOf('GMT') + 3));
2019-02-04T15:57:02.000Z
Why do I get such differing results with similarly formatted date strings when creating a new date?
CHROME (43.0.2357.134 m) console:
new Date('2014-12-25')
Wed Dec 24 2014 17:00:00 GMT-0700 (Mountain Standard Time)
[Chrome assumes Z with 00:00 (utc) and returns that local time]
new Date('2014-1-25')
Sat Jan 25 2014 00:00:00 GMT-0700 (Mountain Standard Time)
[What?! exact same format (I thought) but returns 25 instead of 24....see next...]
new Date('2014-01-25')
Fri Jan 24 2014 17:00:00 GMT-0700 (Mountain Standard Time)
[...oh, the leading 0 makes it use the logic it used in the first example]
new Date('2014/12/25')
Thu Dec 25 2014 00:00:00 GMT-0700 (Mountain Standard Time)
[using / instead of - results in what I believe most would expect(?): a local time
on the same date specified]
FIREFOX (39.0) console:
new Date('2014-12-25')
Date 2014-12-25T00:00:00.000Z
[different from Chrome]
new Date('2014-1-25')
Invalid Date
[not recognized in Firefox, unlike Chrome]
new Date('2014-01-25')
Date 2014-01-25T00:00:00.000Z
[different from Chrome]
new Date('2014/12/25')
Date 2014-12-25T07:00:00.000Z
The lesson seems to be: IF you're going to use strings in the Date constructor, make sure it's formatted correctly (per ECMAScript standard):
YYYY-MM-DDTHH:mm:ss.sssZ
CHROME:
new Date('2014-12-25T00:00:00.000-07:00')
Thu Dec 25 2014 00:00:00 GMT-0700 (Mountain Standard Time)
FIREFOX:
new Date('2014-12-25T00:00:00.000-07:00')
Date 2014-12-25T07:00:00.000Z
The ECMAScript standard says in 15.9.3.2
If Type(v) is String, then
Parse v as a date, in exactly the same manner as for the parse method (15.9.4.2);
And in 15.9.4.2 it says:
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.
...which says to me, if you don't provide that exact format, Chrome and Firefox and everyone else can interpret the date string how they deem right. (note: there is some leeway on the format, for example, the value of an absent sss field is “000”. see section 15.9.1.15 for more details)
Would someone explain why formatting the same dateString differently gives a different date?
> new Date("04/08/1984")
<· Sun Apr 08 1984 00:00:00 GMT-0600 (Mountain Daylight Time)
> new Date("1984-04-08")
<· Sat Apr 07 1984 18:00:00 GMT-0600 (Mountain Daylight Time)
When you create a new Date object passing a dateString parameter to the constructor, it gets parsed using the Date.parse() method. Now, quoting from the MDN documentation (emphasis mine):
Differences in assumed time zone
Given a date string of "March 7, 2014" (or "03/07/2014"), parse() assumes a local time zone, but given an ISO format such as "2014-03-07" it will assume a time zone of UTC. Therefore Date objects produced using those strings will represent different moments in time unless the system is set with a local time zone of UTC.
Therefore, since that your are giving the second string in the ISO format, and your local time zone is UTC+6, you're getting a date which is six hour behind yours, because it gets calculated as UTC+0. In fact:
Apr 07 1984 18:00:00 = Apr 08 1984 00:00:00 - 06:00:00
Mystery solved!
Your problem is that you are adding 0 before the numbers in "1984-04-08". Try the following:
new Date("1984-4-8")
document.write(new Date("04/08/1984"));
document.write("<br>");
document.write(new Date("1984-4-8"));
I need to convert a String to a Date object.
The date string is delivered in the following format:
"2015-01-28T00:00:00"
When I create a new Date, I get the previous date:
Entered: new Date("2015-01-28T00:00:00")
Result: Tue Jan 27 2015 17:00:00 GMT-0700 (Mountain Standard Time)
Does anyone know why this is occurring?
When you enter the following:
new Date("2015-01-28T00:00:00");
// Result: Tue Jan 27 2015 17:00:00 GMT-0700 (Mountain Standard Time)
the browser assumes that you are giving a date in GMT Time zone. So it will automatically convert the given date to your local date.
It's always a good idea to inform the browser of the timezone you are working on in order to prevent future problems:
new Date("2015-01-28T00:00:00-07:00");
// Result: Tue Jan 28 2015 00:00:00 GMT-0700 (Mountain Standard Time)
Actually, you aren't getting the previous date . . . you are getting that date, offset by the timezone difference.
Tue Jan 27 2015 17:00:00(Mountain Time) + 7 hours (time zone difference) = 2015-01-28T00:00:00 (GMT)
Or, in English, when it is 12:00 Midnight in Greenwich, England, it is 5:00 PM on the previous day in Denver, Colorado. ;)
It's the right date/time, just in a different timezone.