Troubleshoot converting string date to date object. - javascript

I get from data base this date string:
var MeasureDateStr = "2016-07-19T16:29:31";
On client I create datetime javascript object from MeasureDate value:
var measureDate = new Date(MeasureDateStr);
After the measureDate object is created the content is:
var measureDate = Tue Jul 19 2016 19:29:31 GMT+0300 (Jerusalem Daylight Time);
As you can see I have different time (+3 hours) relatively to original date string.
My question is why I get diffrent time in measureDate and how to fix the problem?

You get user local time because you don't have anything to tell browser in which timezone to look at.
If you want to have UTC time, just add Z at the end of time string:
var MeasureDateStr = "2016-07-19T16:29:31Z";
Also this may help:
How to ISO 8601 format a Date with Timezone Offset in JavaScript?

Are you sure?
The string you are reporting is a local time string.
If I run your example, I get a Tue Jul 19 2016 16:29:31 GMT+0200 (ora solare Europa occidentale), so the local time is preserved, while a time zone is attached.
If you add a Z, or a time zone indication (like 2016-07-19T16:29:31+03:00), you can specify exactly the behaviour you want.
Please note that when you log the date, you will always get a local format, even if the date was specified with another time zone:
var MeasureDateStr = "2016-07-19T16:29:31+03:00";
var measureDate = new Date(MeasureDateStr);
console.log(measureDate);
I get Tue Jul 19 2016 15:29:31 GMT+0200 (ora solare Europa occidentale) because I'm on GMT+2. But the time is converted accordingly.

It's because your browsers timezone is set to GMT+3. And since you do not specify a timezone in your datestring it will add 3 hours automatically.
EDIT:
var d = '2016-07-19T16:29:31';
var offset = new Date().getTimezoneOffset() * 60 * 1000; // get Timezone offset in milliseconds.
d = new Date(Date.parse(d) + offset) // Remove the timezone offset.
console.log(typeof d); // object
console.log(d); // Tue Jul 19 2016 16:29:31 GMT+0200 (CEST)
Old answer:
new Date('2016-07-19T16:29:31').toUTCString()

Related

YYYY-MM-DD formatted date is taking previous date when we are in eastern time zone [duplicate]

In my Java Script app I have the date stored in a format like so:
2011-09-24
Now when I try using the above value to create a new Date object (so I can retrieve the date in a different format), the date always comes back one day off. See below:
var date = new Date("2011-09-24");
console.log(date);
logs:
Fri Sep 23 2011 20:00:00 GMT-0400 (Eastern Daylight Time)
There are several crazy things that happen with a JS DATE object that convert strings, for example consider the following date you provided
Note: The following examples may or may not be ONE DAY OFF depending on YOUR timezone and current time.
new Date("2011-09-24"); // Year-Month-Day
// => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF.
However, if we rearrange the string format to Month-Day-Year...
new Date("09-24-2011");
// => Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.
Another strange one
new Date("2011-09-24");
// => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF AS BEFORE.
new Date("2011/09/24"); // change from "-" to "/".
// => Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.
We could easily change hyphens in your date "2011-09-24" when making a new date
new Date("2011-09-24".replace(/-/g, '\/')); // => "2011/09/24".
// => Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.
What if we had a date string like "2011-09-24T00:00:00"
new Date("2011-09-24T00:00:00");
// => Fri Sep 23 2011 17:00:00 GMT-0700 (MST) - ONE DAY OFF.
Now change hyphen to forward slash as before; what happens?
new Date("2011/09/24T00:00:00");
// => Invalid Date.
I typically have to manage the date format 2011-09-24T00:00:00 so this is what I do.
new Date("2011-09-24T00:00:00".replace(/-/g, '\/').replace(/T.+/, ''));
// => Sat Sep 24 2011 00:00:00 GMT-0700 (MST) - CORRECT DATE.
UPDATE
If you provide separate arguments to the Date constructor you can get other useful outputs as described below
Note: arguments can be of type Number or String. I'll show examples with mixed values.
Get the first month and day of a given year
new Date(2011, 0); // Normal behavior as months in this case are zero based.
// => Sat Jan 01 2011 00:00:00 GMT-0700 (MST)
Get the last month and day of a year
new Date((2011 + 1), 0, 0); // The second zero roles back one day into the previous month's last day.
// => Sat Dec 31 2011 00:00:00 GMT-0700 (MST)
Example of Number, String arguments. Note the month is March because zero based months again.
new Date(2011, "02");
// => Tue Mar 01 2011 00:00:00 GMT-0700 (MST)
If we do the same thing but with a day of zero, we get something different.
new Date(2011, "02", 0); // Again the zero roles back from March to the last day of February.
// => Mon Feb 28 2011 00:00:00 GMT-0700 (MST)
Adding a day of zero to any year and month argument will get the last day of the previous month. If you continue with negative numbers you can continue rolling back another day
new Date(2011, "02", -1);
// => Sun Feb 27 2011 00:00:00 GMT-0700 (MST)
Notice that Eastern Daylight Time is -4 hours and that the hours on the date you're getting back are 20.
20h + 4h = 24h
which is midnight of 2011-09-24. The date was parsed in UTC (GMT) because you provided a date-only string without any time zone indicator. If you had given a date/time string w/o an indicator instead (new Date("2011-09-24T00:00:00")), it would have been parsed in your local timezone. (Historically there have been inconsistencies there, not least because the spec changed more than once, but modern browsers should be okay; or you can always include a timezone indicator.)
You're getting the right date, you just never specified the correct time zone.
If you need to access the date values, you can use getUTCDate() or any of the other getUTC*() functions:
var d,
days;
d = new Date('2011-09-24');
days = ['Sun', 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat'];
console.log(days[d.getUTCDay()]);
To normalize the date and eliminate the unwanted offset (tested here : https://jsfiddle.net/7xp1xL5m/ ):
var doo = new Date("2011-09-24");
console.log( new Date( doo.getTime() + Math.abs(doo.getTimezoneOffset()*60000) ) );
// Output: Sat Sep 24 2011 00:00:00 GMT-0400 (Eastern Daylight Time)
This also accomplishes the same and credit to #tpartee (tested here : https://jsfiddle.net/7xp1xL5m/1/ ):
var doo = new Date("2011-09-24");
console.log( new Date( doo.getTime() - doo.getTimezoneOffset() * -60000 ) );
I believe that it has to do with time-zone adjustment. The date you've created is in GMT and the default time is midnight, but your timezone is EDT, so it subtracts 4 hours. Try this to verify:
var doo = new Date("2011-09-25 EDT");
Just want to add that apparently adding a space at the end of the string will use UTC for creation.
new Date("2016-07-06")
> Tue Jul 05 2016 17:00:00 GMT-0700 (Pacific Daylight Time)
new Date("2016-07-06 ")
> Wed Jul 06 2016 00:00:00 GMT-0700 (Pacific Daylight Time)
Edit: This is not a recommended solution, just an alternative answer. Please do not use this approach since it is very unclear what is happening. There are a number of ways someone could refactor this accidentally causing a bug.
If you want to get hour 0 of some date in the local time zone, pass the individual date parts to the Date constructor.
new Date(2011,08,24); // month value is 0 based, others are 1 based.
if you need a simple solution for this see:
new Date('1993-01-20'.split('-'));
Your issue is specifically with time zone. Note part GMT-0400 - that is you're 4 hours behind GMT. If you add 4 hours to the displayed date/time, you'll get exactly midnight 2011/09/24. Use toUTCString() method instead to get GMT string:
var doo = new Date("2011-09-24");
console.log(doo.toUTCString());
This probably is not a good answer, but i just want to share my experience with this issue.
My app is globally use utc date with the format 'YYYY-MM-DD', while the datepicker plugin i use only accept js date, it's hard for me to consider both utc and js. So when i want to pass a 'YYYY-MM-DD' formatted date to my datepicker, i first convert it to 'MM/DD/YYYY' format using moment.js or whatever you like, and the date shows on datepicker is now correct. For your example
var d = new Date('2011-09-24'); // d will be 'Fri Sep 23 2011 20:00:00 GMT-0400 (EDT)' for my lacale
var d1 = new Date('09/24/2011'); // d1 will be 'Sat Sep 24 2011 00:00:00 GMT-0400 (EDT)' for my lacale
Apparently d1 is what i want. Hope this would be helpful for some people.
You can convert this date to UTC date by
new Date(Date.UTC(Year, Month, Day, Hour, Minute, Second))
And it is always recommended to use UTC (universal time zone) date instead of Date with local time, as by default dates are stored in Database with UTC. So, it is good practice to use and interpret dates in UTC format throughout entire project.
For example,
Date.getUTCYear(), getUTCMonth(), getUTCDay(), getUTCHours()
So, using UTC dates solves all the problem related to timezone issues.
This through me for a loop, +1 on zzzBov's answer. Here is a full conversion of a date that worked for me using the UTC methods:
//myMeeting.MeetingDate = '2015-01-30T00:00:00'
var myDate = new Date(myMeeting.MeetingDate);
//convert to JavaScript date format
//returns date of 'Thu Jan 29 2015 19:00:00 GMT-0500 (Eastern Standard Time)' <-- One Day Off!
myDate = new Date(myDate.getUTCFullYear(), myDate.getUTCMonth(), myDate.getUTCDate());
//returns date of 'Fri Jan 30 2015 00:00:00 GMT-0500 (Eastern Standard Time)' <-- Correct Date!
It means 2011-09-24 00:00:00 GMT, and since you're at GMT -4, it will be 20:00 the previous day.
Personally, I get 2011-09-24 02:00:00, because I'm living at GMT +2.
Though in the OP's case the timezone is EDT, there's not guarantee the user executing your script will be int he EDT timezone, so hardcoding the offset won't necessarily work. The solution I found splits the date string and uses the separate values in the Date constructor.
var dateString = "2011-09-24";
var dateParts = dateString.split("-");
var date = new Date(dateParts[0], dateParts[1] - 1, dateParts[2]);
Note that you have to account for another piece of JS weirdness: the month is zero-based.
I encountered this exact problem where my client was on Atlantic Standard Time. The date value the client retrieved was "2018-11-23" and when the code passed it into new Date("2018-11-23") the output for the client was for the previous day. I created a utility function as shown in the snippet that normalized the date, giving the client the expected date.
date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
var normalizeDate = function(date) {
date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
return date;
};
var date = new Date("2018-11-23");
document.getElementById("default").textContent = date;
document.getElementById("normalized").textContent = normalizeDate(date);
<h2>Calling new Date("2018-11-23")</h2>
<div>
<label><b>Default</b> : </label>
<span id="default"></span>
</div>
<hr>
<div>
<label><b>Normalized</b> : </label>
<span id="normalized"></span>
</div>
My solution to parse an ISO date without beeing annoyed by the timezone is to add a "T12:00:00" at the end before parsing it, because when it's noon at Greenwich, well the whole world is on the same day :
function toDate(isoDateString) {
// isoDateString is a string like "yyyy-MM-dd"
return new Date(`${isoDateString}T12:00:00`);
}
Before:
> new Date("2020-10-06")
> Date Mon Oct 05 2020 14:00:00 GMT-1000 (heure normale d’Hawaii - Aléoutiennes)
After:
> toDate("2020-10-06")
> Date Tue Oct 06 2020 12:00:00 GMT-1000 (heure normale d’Hawaii - Aléoutiennes)
if you're just looking to make sure the individual parts of the date stay the same for display purposes, *this appears to work, even when I change my timezone:
var doo = new Date("2011-09-24 00:00:00")
just add the zeros in there.
In my code I do this:
let dateForDisplayToUser =
new Date( `${YYYYMMDDdateStringSeparatedByHyphensFromAPI} 00:00:00` )
.toLocaleDateString(
'en-GB',
{ day: 'numeric', month: 'short', year: 'numeric' }
)
And I switch around my timezone on my computer and the date stays the same as the yyyy-mm-dd date string I get from the API.
But am I missing something/is this a bad idea ?
*at least in chrome. This Doesn't work in Safari ! as of this writing
As most answers are hacky, allow me to propose my very simple hack that worked for me: Set the script's timezone to UTC
process.env.TZ = 'UTC' // this has to be run before any use of dates
With this change, any timezone modifications are neutralized, so as long as you don't need the runner's actual timezone, this is probably the easiest fix.
// When the time zone offset is absent, date-only formats such as '2011-09-24'
// are interpreted as UTC time, however the date object will display the date
// relative to your machine's local time zone, thus producing a one-day-off output.
const date = new Date('2011-09-24');
console.log(date); // Fri Sep 23 2011 17:00:00 GMT-0700 (PDT)
console.log(date.toLocaleDateString('en-US')); // "9/23/2011"
// To ensure the date object displays consistently with your input, simply set
// the timeZone parameter to 'UTC' in your options argument.
console.log(date.toLocaleDateString('en-US', { timeZone: 'UTC' })); // "9/24/2011"
The best way to handle this without using more conversion methods,
var mydate='2016,3,3';
var utcDate = Date.parse(mydate);
console.log(" You're getting back are 20. 20h + 4h = 24h :: "+utcDate);
Now just add GMT in your date or you can append it.
var mydateNew='2016,3,3'+ 'GMT';
var utcDateNew = Date.parse(mydateNew);
console.log("the right time that you want:"+utcDateNew)
Live: https://jsfiddle.net/gajender/2kop9vrk/1/
I faced some issue like this. But my issue was the off set while getting date from database.
this is stroed in the database and it is in the UTC format.
2019-03-29 19:00:00.0000000 +00:00
So when i get from database and check date it is adding offset with it and send back to javascript.
It is adding +05:00 because this is my server timezone. My client is on different time zone +07:00.
2019-03-28T19:00:00+05:00 // this is what i get in javascript.
So here is my solution what i do with this issue.
var dates = price.deliveryDate.split(/-|T|:/);
var expDate = new Date(dates[0], dates[1] - 1, dates[2], dates[3], dates[4]);
var expirationDate = new Date(expDate);
So when date come from the server and have server offset so i split date and remove server offset and then convert to date. It resolves my issue.
Trying to add my 2 cents to this thread (elaborating on #paul-wintz answer).
Seems to me that when Date constructor receives a string that matches first part of ISO 8601 format (date part) it does a precise date conversion in UTC time zone with 0 time. When that date is converted to local time a date shift may occur
if midnight UTC is an earlier date in local time zone.
new Date('2020-05-07')
Wed May 06 2020 20:00:00 GMT-0400 (Eastern Daylight Time)
If the date string is in any other "looser" format (uses "/" or date/month is not padded with zero) it creates the date in local time zone, thus no date shifting issue.
new Date('2020/05/07')
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2020-5-07')
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2020-5-7')
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
new Date('2020-05-7')
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
So then one quick fix, as mentioned above, is to replace "-" with "/" in your ISO formatted Date only string.
new Date('2020-05-07'.replace('-','/'))
Thu May 07 2020 00:00:00 GMT-0400 (Eastern Daylight Time)
This solved my problem (thanks to #Sebastiao answer)
var date = new Date();
//"Thu Jun 10 2021 18:46:00 GMT+0200 (Eastern European Standard Time)"
date.toString().split(/\+|-/)[0] ; // .split(/\+|-/) is a regex for matching + or -
//"Thu Jun 10 2021 18:46:00 GMT"
var date_string_as_Y_M_D = (new Date(date)).toISOString().split('T')[0];
//2021-06-10
I just wanted to give my 2 cents on this, as this post was very helpful to figure out the issue. I don't think I've seen this solution mentioned, correct me if I'm wrong.
As it has been mentioned numerous times already here, the problem comes mainly from summer/winter time. I noticed that in January, the GMT was +1. If the time is not set, it will always be 00.00.00 (midnight), which results in going on the 23rd hour of the previous day.
If you have a dynamic date and don't care about the hour, you can set the hour using the setHours() method before using it with toISOString().
syntax:
setHours(hoursValue, minutesValue, secondsValue, msValue)
Which means that:
dynamicDate.setHours(12, 0, 0, 0)
dynamicDate.toISOString()
should hopefully work for you as even if the date is one hour ahead/behind it will still be the same day now that we're setting the hour to be noon.
More about setHours() on MDN.
You can use moment library to format the date.
https://momentjs.com/
let format1 = "YYYY-MM-DD"
let date = new Date();
console.log(moment(date).format(format1))
EDIT
The moment is now deprecated, you can use date-fns format method for formatting a date.
import { format } from 'date-fns'
format(new Date(), "yyyy-MM-dd")
You are using the ISO date string format which, according to this page, causes the date to be constructed using the UTC timezone:
Note: parsing of date strings with the Date constructor (and
Date.parse, they are equivalent) 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.
If you format the text differently, such as "Jan 01 1970", then (at least on my machine) it uses your local timezone.
Storing yyyy-mm-dd in MySql Date format you must do the following:
const newDate = new Date( yourDate.getTime() + Math.abs(yourDate.getTimezoneOffset()*60000) );
console.log(newDate.toJSON().slice(0, 10)); // yyyy-mm-dd
Following Code worked for me. First I converted to date and time string to localeDateString then apply the split function on the returned string.
const dateString = "Thu Dec 29 2022 00:00:00 GMT+0500 (Pakistan Standard Time)";
const date = new Date(dateString).toLocaleDateString().split("/");
const year = new Date(dateString).getFullYear();
const month = new Date(dateString).getMonth();
console.log(new Date(`${date[2]}-${date[0]}-${date[1]}`));
// 2022-12-29T00:00:00.000Z
// Due to timezone issue, the date is one day off.
console.log(new Date("2011-09-24"));
// => 2011-09-24T00:00:00.000Z-CORRECT DATE.
console.log(new Date("2011/09/24"));
// => 2011-09-23T19:00:00.000Z -ONE DAY OFF AS BEFORE.
Using moment you can keep Offset while converting toISOString
let date = moment("2022-03-15").toISOString();
// WRONG OUTPUT 2022-03-14T18:30:00.000Z
let date = moment("2022-03-15").toISOString(true);
// CORRECT OUTPUT 2022-03-15T00:00:00.000+05:30
The following worked for me -
var doo = new Date("2011-09-24").format("m/d/yyyy");

Convert date object to the same time in different timezone and get timestamp of it

I have a GMT+1 date object Wed Feb 01 2017 00:00:00 GMT+0100 (CET). I want to convert this object to GMT+0 with exactly the same date:
GMT: 1 Feb 2017 00:00:00 GMT;
When I parse my object it returns timestamp which is equal to Tue, 31 Jan 2017 23:00:00 GMT.
How to convert my GMT+1 date object to gets timestamp equal to the same date in GMT+0? I tried to use moment.js but I couldn't handle that.
#edit
code with explanation here
// User chooses 1st Feb 2017, but since components works with GMT +1
const userChoice = new Date(2017, 01, 01, 0, 0, 0)
// And backend works with timestamps I parse userChoice
const timestamp = moment(userChoice).valueOf()
// Which gives me timestamp equal to 31st of Dec 2016
console.log(timestamp, moment(timestamp).utc().format('DD/MM/YYYY hh:mm:ss Z'))
// But I want to have the same date as user chooses, but in a specific (GMT+0) timezone
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script>
Ok, I found out the solution. We will call date object "mod" which gives us Wed Feb 01 2017 00:00:00 GMT+0100.
const mod = new Date(1485903600000)
Now we will create variable that gives us timestamp of the exact same time (e.g. day, hours, etc.) but in UTC.
const utc = Date.UTC(mod.getFullYear(), mod.getMonth(), mod.getDate(), mod.getHours(), mod.getMinutes(), mod.getSeconds())
If we want to check if our timestamp is correct we can simply create new Date with this timestamp and console.log it.
console.log(1485907200000) // Wed Feb 01 2017 01:00:00 GMT+0100 <=> Wed Feb 01 2017 00:00:00 GMT+0000
It's not clear to me what you are trying to do. Looking at your code:
// User chooses 1st Feb 2017, but since components works with GMT +1
const userChoice = new Date(2017, 01, 01, 0, 0, 0)
That creates a Date object equivalent to midnight at the start of 1 February 2017 in the host system time zone.
// And backend works with timestamps I parse userChoice
const timestamp = moment(userChoice).valueOf()
You aren't "parsing" userChoice, it's a Date object. You're getting the time value, which is an offset in milliseconds since 1970-01-01T00:00:00Z and is equivalent to userChoice.getTIme().
// Which gives me timestamp equal to 31st of Dec 2016
console.log(timestamp, moment(timestamp).utc().format('DD/MM/YYYY hh:mm:ss Z'))
No it doesn't. The original date is for 1 Feb, it can only be shifted by a maximum of one day either way by time zones. For hosts set to a timezone west of Greenwich, the timezone adjustment when the Date is created will mean the UTC date is 1 Feb, but for hosts to the east, the UTC date will be 31 Jan.
// But I want to have the same date as user chooses, but in a specific (GMT+0) timezone
To create a Date for a specific UTC date, then use UTC methods. Alternatively, if you have a Date object, you can adjust it by the host offset:
// Create date for 1 Feb, 2017 based on host offset
var d = new Date(2017, 1, 1);
// Create UTC Date for same date
var u = new Date(Date.UTC(2017,1,1));
console.log('Local: ' + d.toISOString());
console.log('UTC : ' + u.toISOString());
// Adjust d for timezone offset
d.setMinutes(d.getMinutes() - d.getTimezoneOffset())
console.log('Adjusted: ' + d.toISOString());
If that doesn't help, please update the question.
A date object can not be converted to different time-zone as it only keeps the number of milliseconds that passed since Jan 1, 1970 and it is the same for all places around the world.
However the date object may be interpreted in different time zone (also known as a local time) based on the time-zone offset value.
You do not need to even know the fixed value of the time-zone offset;
let the computer take care of it for you, as it will also include summer daylight saving time changes between different places and at the right time.
All you need to know is the time-zone description that could be looked-up at iana.org website.
let now = new Date(),
current = Intl.DateTimeFormat().resolvedOptions().timeZone,
zones = [current , 'Europe/London', 'Asia/Tokyo'];
zones.forEach((z)=>{
console.log("Time in "+ z + " is " +
now.toLocaleString("en-ES",{timeZone: z}))
});

Javascript Date issues returning 1 day less than set date - timezone

Date formatting issues with Javscript Date().
Background: I'm modifying Jquery UI datepicker and am having trouble with months and dates returning incorrect values.
$('#datefield').datepicker({
beforeShowDay: function(date) {
// issues experienced here - isolation test code below
// Mon Aug 01 2016 00:00:00 GMT+1000 (AUS Eastern Standard Time)
// DateMonth: 8 - ISO: 20160731
}
})
Based JS Date() construction on http://www.w3schools.com/jsref/jsref_obj_date.asp
Sample code:
var d1 = new Date();
var d1Month = d1.getMonth()+1;
var d1ISO = d1.toISOString().slice(0,10).replace(/-/g,"");
console.log(d1);
console.log('1Month: '+d1Month+' ISO: '+d1ISO);
var d2 = new Date(2016,06,31);
var d2Month = d2.getMonth()+1;
var d2ISO = d2.toISOString().slice(0,10).replace(/-/g,"");
console.log(d2);
console.log('2Month: '+d2Month+' ISO: '+d2ISO);
var d3 = new Date('2016-07-31');
var d3Month = d3.getMonth()+1;
var d3ISO = d3.toISOString().slice(0,10).replace(/-/g,"");
console.log(d3);
console.log('3Month: '+d3Month+' ISO: '+d3ISO);
var d4 = new Date(2016, 07, 01);
var d4Month = d4.getMonth()+1;
var d4ISO = d4.toISOString().slice(0,10).replace(/-/g,"");
console.log(d4);
console.log('4Month: '+d4Month+' ISO: '+d4ISO);
Output (console):
Wed Aug 24 2016 11:30:51 GMT+1000 (AUS Eastern Standard Time)
1Month: 8 ISO: 20160824
*Sun Jul 31 2016 00:00:00 GMT+1000 (AUS Eastern Standard Time)
2Month: 7 ISO: 20160730
Sun Jul 31 2016 10:00:00 GMT+1000 (AUS Eastern Standard Time)
3Month: 7 ISO: 20160731
*Mon Aug 01 2016 00:00:00 GMT+1000 (AUS Eastern Standard Time)
4Month: 8 ISO: 20160731
Why does 'd2' return 20160730 when the object returns 31st July?
Why does 'd4' return 20160731 when the date set is 1st August?
Why does d3 work correctly?
My Assumption is that that the ISO date somehow subtracts the GMT+10 and gets the previous day.
I'm Aware of this step (protoype a function) to try and format Get String in YYYYMMDD format from JS date object?
but its still a mystery to me why the above produces different results...
return [this.getFullYear(), !mm[1] && '0', mm, !dd[1] && '0', dd].join('');
Why does 'd2' return 20160730 when the object returns 31st July?
Because when you do:
var d2 = new Date(2016,06,31);
you create a Date equivalent to 31 July, 2016 at 00:00:00 in your host system's current time zone. When you do:
console.log(d2);
your current system settings are used to generate a string in your host system's time zone (apparently GMT+10:00) and will show the equivalent of 2016-07-31T00:00:00+10:00.
But when you do:
console.log('2Month: '+d2Month+' ISO: '+d2ISO);
the date is in time zone GMT, or 10 hours earlier so if the time is before 10:00, then the date will be the previous day (GMT) and you'll see:
2016-07-30T14:00:00Z
but because you sliced the time part off the string, you only see the date part.
It "works" for d3 because when you do:
var d3 = new Date('2016-07-31');
the date string is treated as UTC*, so you're creating a date for 2016-07-31T00:00:00Z which is equivalent to 2016-07-31T10:00:00+10:00, i.e. the UTC date is the same as your local date. Note that the output of:
console.log(d3);
is at 10:00:00 (because the built–in toString considers your system time zone, so adds 10 hours to the displayed date), which is your time zone offset.
In all of the above, the actual time value of the Date object is UTC. The host system time zone offset is used for creating the time value initially, for the get and set methods for year, month, day, hour, etc. (since daylight saving changes the time zone) and when generating human readable date strings.
* Note that this is contrary to ISO 8601, which specifies that dates without a time component should be treated as local. But ECMA-262 treats them as UTC. There are certain versions of browsers where '2016-07-31' will be treated as invalid, others where it will be treated as local, while the latest will treat it as UTC. That is why it is strongly recommended to always manually parse date strings (use your own function or a library with a parser) so you control how it's parsed and how the time zone is applied.

Javascript New Date Changing Hour Value

I am receiving times in the an AJAX request and am converting them using the new Date() function.
I receive 2013-06-18T12:00:15Z
However, somehow I get the following after new Date():
Tue Jun 18 2013 08:00:15 GMT-0400 (EDT)
Why is it not:
Tue Jun 18 2013 12:00
See the following demo:
http://www.w3schools.com/js/tryit.asp?filename=tryjs_date_convert
This is a time zone problem. You must be in the EDT timezone (GMT-0400). To correctly parse the date you should tell the parser in which timezone your date is correct.
For you parse your date like this :
new Date('2013-06-18 12:00:15 GMT-0400')
"GMT-0400" means GMT time minus 4 hours
Or if you don't wish to reformat your string, you can use the date.getUTC* functions to get the time as you parsed it.
The full list is available at Mozilla's documentation.
I agree with Vaim Caen's answer that this is a timezone issue, but not with parsing - the date is being parsed fine, but into your local timezone, while you're expecting it to be parsed into UTC date.
This answer shows how to convert from your current timezone to UTC - applying this to the TryIt demo gives:
var msec = Date.parse("2013-06-18T12:00:15Z");
// or: var msec = Date.parse("Tue Jun 18 2013 08:00:15 GMT-0400 (EDT)");
var d = new Date(msec);
d.setTime( d.getTime() + d.getTimezoneOffset()*60*1000 );
document.getElementById("demo").innerHTML = d;
Edit: If you all you're interested in is displaying the date (no further manipulations) then you can use:
d.toUTCString()
which will show the date in GMT (for me it actually shows "GMT" so most likely not of use!)
The alternative is to add a function to the prototype to show the date in whatever format you want and use the date.getUTC* methods.

Javascript Date(): How to convert the local date to GMT

I'm sending the server time object with zero date, the sent date is:
Thu Jan 01 1970 01:02:01 GMT+0200
How can I convert it to GMT+0000? I need to tell the server about some task duration, so I want it to be just 01:02:01 as a duration. But the sent date is local and the server understands it as 03:02:01! How can I zero the GMT index?
Thanks
Getting the GMT time out of a JavaScript Date object is simple enough -
Date.prototype.toUTCString()
The toUTCString() method converts a date to a string, using the UTC time zone.
For example:
var test = new Date('Thu Jan 01 1970 01:02:01 GMT+0200').toUTCString();
console.log(test);
Note that this correctly outputs Wed, 31 Dec 1969 23:02:01 GMT, which although it not what you are looking for, is converting the provided Date to GMT.
To get what you want out of your input, a regular expression is useful. Caveats:
assumes duration will never be more than 23 hours, 59 minutes, and 59 seconds. If it is this will break.
var test = 'Thu Jan 01 1970 01:02:01 GMT+0200';
var durationMatcher = /\d\d:\d\d:\d\d/;
console.log(test.match(durationMatcher));
If you can, consider working in some values that works for you with one number - number of milliseconds for example.
function convertToGmt(pdate)
{
var newDate = new Date(pdate);
return (newDate.getUTCHours()<10?"0"+newDate.getUTCHours():newDate.getUTCHours())+":"+(newDate.getUTCMinutes()<10?"0"+newDate.getUTCMinutes():newDate.getUTCMinutes())+":"+(newDate.getUTCSeconds()<10?"0"+newDate.getUTCSeconds():newDate.getUTCSeconds());
}
Now use this function and call it by passing you date.
Notice that getUTCHours() returns correct hour in UTC.
Working Fiddle

Categories