how to convert date in UTC format using moment? - javascript

using date picker I am getting this value "Fri Jan 12 1900 05:21:10 GMT+0521 (India Standard Time)" I want to get it's value in UTC or UTC in milliseconds or long value.
here is my code
app.controller('MainCtrl', function($scope, moment) {
$scope.UTC ='';
$scope.IST = 'Fri Jan 12 1900 05:21:10 GMT+0521 (India Standard Time)';
});

According to the Moment docs:
moment.utc(yourDate).format()
By default, moment parses and displays in local time.
If you want to parse or display a moment in UTC, you can use moment.utc() instead of moment().
This brings us to an interesting feature of Moment.js. UTC mode.
While in UTC mode, all display methods will display in UTC time instead of local time.

Related

.NET date, Moment.js, UTC and Timezone shifting

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()

moment.js unable to convert utc date to local date

I have the following date in utc format which I want to convert and display as local date time.
// utc
date = 'Thu Oct 27 2016 07:00:00 GMT+0100 (GMT Standard Time)';
// convert to local
moment.utc(date).local().format("ddd MMM DD YYYY HH:mm:ss");
Expected results using the above should be:
Thu Oct 27 2016 08:00:00
But actual results are being displayed as follows i.e. the time is not changing?
Thu Oct 27 2016 07:00:00
A few things:
Your input is a string, in a nonstandard format. You probably got it by taking a Date object and calling the .toString() function, but that doesn't mean it's suitable for parsing by moment. If you look in the debug console, you'll find a warning message, because you passed in something moment doesn't understand natively and so it is passing it back to the Date constructor. See the user guide, which explains that you must pass a format specifier when you have custom input.
Your input contains a time zone offset of +0100. That means the 7:00 time is at UTC+1, which is equivalent to 6:00 UTC. This is the value the moment has when you first parse it with moment.utc(yourInput)
You then convert 6:00 UTC back to local time when you call the local() function. That's the 7:00 UTC+1 you are seeing.
How to resolve this depends on what you are actually wanting to do. You said you expected 8:00 UTC, but that doesn't make sense from the input you gave because 7:00 (+1) == 6:00 (+0).
If what you meant is that you wanted to assert that the original time value was indeed UTC, and not UTC+1, even though it's in your input, then provide a format string that only contains the parts you care about. Moment's default loose parsing mode will ignore anything extraneous.
date = 'Thu Oct 27 2016 07:00:00 GMT+0100 (GMT Standard Time)';
moment.utc(date, 'ddd MMM DD YYYY HH:mm:ss').local().format("ddd MMM DD YYYY HH:mm:ss");
In other words, your input date is only Thu Oct 27 2016 07:00:00 here, and the rest is ignored. You are asserting that it's in UTC by passing it in to moment.utc, and then when you convert it to local it will end up at 8:00.
However, though that's what you asked for, my guess is that date is actually a JavaScript Date object, whose string output of .toString() is what you are showing here. In that case, the Date object is already representing a specific point in time, which is 6:00 UTC. So it doesn't matter whether you do moment.utc(date).local() or just moment(date). Both will leave you with that same moment in time, represented with the local time zone.
You may want to go back to your input and figure out how you got it to include GMT+0100 when you are thinking it's actually a UTC value. Consider that if you actually had 8:00 UTC, your input would say 09:00 GMT+0100.
You may want to use Moment TimeZone with MomentJS (http://momentjs.com/timezone/)
date = moment.tz("Thu Oct 27 2016 07:00:00", "GMT Standard Time");
date.clone().local().format('ddd MMM DD YYYY HH:mm:ss');
EDIT:
Removing the utc part fixes it for me without Moment TimeZone:
date = 'Thu Oct 27 2016 07:00:00 GMT+0100 (GMT Standard Time)';
moment(date).local().format('ddd MMM DD YYYY HH:mm:ss');

Javascript new Date decreases date by a day

I have a scenario where I am using AngularJS to read date. Interestingly it decreases my date value by one.
Why is this happening?
new Date("2016-01-06T00:00:00")
give me result as
Tue Jan 05 2016 16:00:00 GMT-0800 (Pacific Standard Time)
This is because when you use the new Date() in the JavaScript, it converts and prints the date in browsers timezone.
So if you print:
new Date("2016-01-06T00:00:00-0800")
You will get the actual output you want, because of the -0800 difference between your time zone (determined by the browser) and the UTC time.
The UTC time zone is used to interpret arguments in ISO 8601 format that do not contain time zone information (note that ECMAScript 2015 specifies that date time strings without a time zone are to be treated as local, not UTC).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse
Since your date string appears to lack one, JS assumed it's UTC time. The result you see is the same moment in time, offset to your timezone. All you need to do is provide timezone data to the string you're parsing.
It is because the date is taking your browser's timezone in to account, which in your case is in PST. It does the same to me, in EST:
test = new Date("2016-01-06T00:00:00")
Tue Jan 05 2016 19:00:00 GMT-0500 (EST)
You can still obtain the time in UTC by using any of the .getUTC* functions, like so:
test.getUTCDate();
6

Why does moment.js return this date wrong?

I'm simply trying to take an input string and convert it to a date object.
moment.utc('2000-01-01T00:00:00.000Z').toDate()
But it returns this...
Fri Dec 31 1999 19:00:00 GMT-0500 (EST)
Thanks
That is a valid JavaScript Date Object. You can test this by opening a console in Chrome or Firefox, then entering the following:
// Mon Nov 24 2014 09:54:00 GMT-0800 (PST) (looks the same as your example)
console.log( new Date() );
If you want to format the value coming out of moment.js, you can use its format method and a mask.
// Example: November 24th 2014, 09:58:12am
var fdate = moment().format('MMMM Do YYYY, h:mm:ss a');
Moment.js doesn't modify the prototype, it simply wraps it.
If you want to convert a string to a date object using moment.js, you can just call it as such:
moment(your_date); // Unless in UTC mode this will display as local time
In your instance you're using the UTC mode.
2000-01-01T00:00:00.000Z is the GMT date/time.
Using moment.utc("2000-01-01T00:00:00.000Z").toDate() returns this date/time according to your timzone settings.
See : http://www.digitoffee.com/programming/get-local-time-utc-using-moment-js/94/
Hope it helps.

Inconsistencies when creating new date objects

I am creating new date objects in javascript and seeing some inconsistencies depending on whether I use the dateString parameter vs the year/month/day integer parameters.
Here's an example:
var dt1 = new Date(1979,3,5);
var dt2 = new Date('1979-04-05');
jsFiddle with example
dt1 is assigned the value: Thu Apr 05 1979 00:00:00 GMT-0500 (Central Daylight Time)
dt2 is assigned the value: Wed Apr 04 1979 19:00:00 GMT-0500 (Central Daylight Time)
Can someone explain this behavior? The second example (dt2) happens to be the format that Chrome is returning a selected date from input[type=date] elements which is why I'm trying to figure this out.
It looks like the form '1979-04-05' is interpreted as a UTC date (and then that UTC date is converted to local time when displayed). The form new Date(1979,3,5); is interpreted as local time. You can use Date.UTC to force UTC time for the 3-argument form (see docs).
Date parsing (and timezone handling in particular) is generally not uniform across browsers, and it's better not to depend on it - use UTC whenever possible, or use a separate library like Date.js or moment.js.

Categories