I have a timestamp given by
timestamp = 2015-02-22T10:00:00.000Z
Why is it converted to GMT when I do this
var dt = new Date(timestamp);
console.log('dt = ' + dt); // prints Sun Feb 22 2015 05:00:00 GMT-0500 (EST)
I don't want it to convert my date to GMT. How do I prevent javascript from converting my dates?
When you try to execute dt = ' + dt, Javascript tries to convert the dt object to a string so it can be added to another string. It does that by calling the dt.toString() method and the format you are seeing is the default string conversion for a date object.
FYI, this default format that looks like this:
Fri Mar 06 2015 19:24:42 GMT-0800 (Pacific Standard Time)
is NOT GMT time. The time value shown is local time. It is showing you that local time shown is -0800 hours from GMT, but the time itself is expressed in local time.
It's not uncommon to want to just truncate off the last part of this and display:
Fri Mar 06 2015 19:24:42
That can be done like this:
console.log('dt = ' + dt.toString().replace(/\sGMT.*$/, ""));
Working demo: http://jsfiddle.net/jfriend00/hg5m0r1r/
If you want something different to show, then you should construct the string representation you want yourself rather than letting the system automatically call .toString(). You can look at the Date object methods available and decide what you want to display. A Date object internally is a number of ms since the epoch time so any string representation is a conversion of some kind. You have to tell it what conversion you want.
You can see a list of the many date methods here.
Related
I've got a UTC date through an Ajax call, e.g. "/Date(1517216466000+0100)/",
which is when printing to the console: Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time).
What I need to do, is to let the user change the timezones: I can easily do it with e.g. moment(myDate).tz("Japan").
Then I need to save the date in it's UTC format, which I am not able to do.
I've been experimenting with moment.utc(), but for the input above, it returns 1 hour less.
How to deal with this situation? In summary:
1. Get a UTC time from a webservice
2. Let the user change the timezones
3. Save the modified date in UTC (without the timezone)
Working demo: https://stackblitz.com/edit/angular-kqrct7?file=app%2Fapp.component.html
EDIT for clarification:
Let's just have a look at the hours. What I get the date from the WCF, is 10 o'clock. The browser interprets it as 10 o'clock BUT in GMT+1 so when I convert it to UTC, it becomes 9 o'clock.
I want it to be 10 o'clock as UTC. Then, if I modify the timezone and e.g. the minutes of this date, I want to be able to get the UTC value of this date.
EDIT2: Made my question simplier for clarification
I've got a UTC date, which I get from a webservice like: "/Date(1517216466000+0100)/" which is: Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time) when printed to console.
I add a timezone to it with moment(this.inputDate).tz("Europe/Berlin").format(), but it stays 10:01:06, I guess because of my browsers GMT+1.
I want the ORIGINAL string to be used as a UTC date AND it should remain 10:01:06, not 09:01:06 as you can see above (2nd moment example), so with the timezone "Europe/Berlin" would be 11:01:6
In the .NET JSON formatted date "/Date(1517216466000+0100)/" the timezone offset can be ignored. It represents "2018-01-29T09:01:06.000Z", where the source system was at a timezone offset of +0100. So if you don't care about the source timezone, just ignore it.
It is also an identical moment in time to Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time), just with a different offset.
UTC is not a format, it's a time standard. If you want to use ISO 8601 format:
Extract the first numeric value
Convert to Number
Pass to the Date constructor
Call the toISOString method on the resulting Date
var s = '/Date(-1517216466000+0100)/';
console.log(new Date(+s.replace(/^[^\d-]+(-?\d+).*$/,'$1')).toISOString());
You can also parse and format it using moment.js, which according to the documentation can handle the .NET JSON format without needing to specify the format. So you can either do that or extract the time value and parse it with the "x" format token:
var s = '/Date(1517216466000+0100)/';
// Let moment.js guess the format
console.log(moment(s).utc());
// Extract time value and supply format
console.log(moment(s.replace(/^[^\d-]+(-?\d+).*$/,'$1'), 'x').utc());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
"/Date(1517216466000+0100)/" is a non-standard way to serialise a date/time. Take a look at ISO8601 which defines several standard ways to represent dates and times.
That being said let's take a look at what this gets evaluated as...
moment("/Date(1517216466000+0100)/").toDate()
gives Mon Jan 29 2018 09:01:06 GMT+0000 (GMT Standard Time) for me (in the UK)
taking just the timestamp value 1517216466000
new Date(1517216466000)
also gives Mon Jan 29 2018 09:01:06 GMT+0000 (GMT Standard Time)
this means that the +0100 is being ignored.
You're not actually modifying the time so why would you expect it to save back as anything other than Mon Jan 29 2018 09:01:06
UPDATE
But the "original" string represents Mon Jan 29 2018 09:01:06 UTC the +0100 is ignored and it's just coincidence that your offset to UTC is also +0100. An off.
Offset and timezone are 2 different things. A timezone encompasses offset to UTC as well as when/if daylight savings comes in to force. Just because it says +0100 doesn't necessarily mean (W. Europe Standard Time) as it could just as easily be (West Africa Time) which is also UTC+0100 but doesn't observe daylight savings at all.
The time you have "/Date(1517216466000+0100)/" doesn't convey enough information to say which timezone it is and JS/moment just uses the timestamp 1517216466000 and as such uses UTC. When you console.log() this the browser writes it to screen as local time Mon Jan 29 2018 10:01:06 GMT+0100 (W. Europe Standard Time) but this is only a representation of the underlying datetime.
By telling moment to use a specific time zone, it's only changing how the date/time gets displayed and doesn't actually change the time it represents.
If you use a date picker to change the date/time then you'll have to serialise the value to send to the backend in an appropriate way that the .Net app you cannot change will understand and conveys what you intend.
Example
Get date from server as var serverTime = "/Date(1517216466000+0100)/"
convert this to a JS Date using moment var time = new moment(serverTime)
Let user specify TimeZone i.e. Japan Standard Time (UTC+9) time = time.tz("Japan")
time still represents Mon Jan 29 2018 09:01:06 UTC but when displayed on screen with time.format() gives "2018-01-29T18:01:06+09:00"
You stated "I want it to be 10 o'clock as UTC". Unfortunately the value you've is NOT 10 O'clock UTC and will never be 10 O'clock UTC because it isn't. It is 9 O'clock UTC
You could parse the value you get from the server yourself but the time from the server IS 9am UTC. If you change it to 10 am UTC then you would see that as Mon Jan 29 2018 11:01:06 GMT+0100 (W. Europe Standard Time) - 11 O'clock local time.
Thanks everyone for your detailed answers, they helped me a lot in understanding my problem! However, the right solution was the following:
10 o'clock was a UTC time in the database and it got interpreted as 9 o'clock UTC in Moment.js because C# handled it as a local time. So, before sending the date to the client, I had to indicate that its a UTC:
var utcToClient = DateTime.SpecifyKind(downtime.DownTimeStartUTC, DateTimeKind.Utc)
Then, in Moment I could create a UTC with:
var jsUtc = moment.utc(downtime.DownTimeStartUTC)
Changing the timezones was a breeze with:
jsUtc.tz(userSelectedTimezone)
And saving the date in the database, I used this in C#:
var utcFromClient = Record.DownTimeStartUTC.ToUniversalTime()
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()
I use the datepicker to pick a date and send it to the server.
When I log the JS value I get the correct result:
Tue Mar 22 2016 00:00:00 GMT+0100 (Mitteleuropäische Zeit)
but in the ajax request it is
2016-03-21T23:00:00.000Z
I don't modify the values, just giving the object to angulars http function.
Does Angular need some configuration to handle it?
You can try the following piece of code
dateObj.setMinutes((dateObj.getMinutes() + dateObj.getTimezoneOffset()));
No need of localization, use this code just before doing any service call. It will pass you the exact date what you selected in the datepicker.
It will work in all timezone (+) and (-),
Example: 2016-03-21 00:00:00 GMT+0100, the above said code covert it as 2016-03-21 01:00:00 GMT+0000. While on Service it converts it as 2016-03-21 00:00:00.
I think it will solve your problem.
Those two strings represent the same time. One is in UTC, i.e. GMT +0, which you can see from the Z ending. The other is in a different timezone, specifically GMT +1 hour.
If you had javascript date objects for both strings, and turned them into integers, i.e. seconds passed since Jan 1, 1970, UTC, you'd find them identical. They represent the same instant but in two different geographic locations.
var d1 = new Date('Tue Mar 22 2016 00:00:00 GMT+0100');
var d2 = new Date('2016-03-21T23:00:00.000Z');
Number(d1); // 1458601200000
Number(d2); // 1458601200000
Generally this is a good thing. Dealing in timezones gets very confusing. I find it best for a server to always deal in UTC.
https://github.com/angular/material/pull/9410
Check out the 1.1.1+ version. This will solve your issue.
<md-datepicker ng-model="date" ng-model-options="{ timezone: 'utc' }"></md-datepicker>
If suppose am selecting a date like Tue Aug 06 2019 00:00:00 GMT+0530 (India Standard Time), am getting 2019-08-05T18:30:00.000Z. ( which in my case previous date with respect to the selected date)
I made use of toLocalDateString() to do the job.
// this.date = 2019-08-05T18:30:00.000Z
const converted = new Date(this.date).toLocaleDateString();
console.log(converted); // 8/6/2019 (MM/DD/YYYY) format
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.
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