I'm passing back a UTC date from the server, and I need some JS to find the difference in seconds between "now" and the date passed back from the server.
I'm currently trying moment, with something like
var lastUpdatedDate = moment(utcStringFromServer);
var currentDate = moment();
var diff = currentDate - lastUpdatedDate;
problem is, this gives a very invalid answer, because UTC is coming down from the server, and creating a new moment() makes it local. How can I do a calculation with respect to full UTC so it's agnostic of any local timing?
What you aren't quite understanding is that Dates are stored as the number of milliseconds since midnight, Jan 1, 1970 in UTC time. When determining the date/time in the local timezone of the browser, it first works out what the date/time would be in UTC time, then adds/subtracts the local timezone offset.
When you turn a Date back into a number, using +dateVar or dateVar.valueOf() or similar, it is back to the number of milliseconds since 01/01/1970T00:00:00Z.
The nice part about this is that whenever you serialise dates in UTC (either as a number, or as ISO String format), when it gets automatically converted to local time by Javascript's Date object, it is exactly the same point in time as the original value, just represented in local time.
So in your case, when you convert a local date to a number, you get a value of milliseconds in UTC that you are subtracting a value in milliseconds in UTC from. The result will be the number of milliseconds that has passed between the time from the server and the time the new Date() call is made.
Where it gets tricky is when you want a timestamp from the server to not be translated to local time, because you want to show the hours and minutes the same regardless of timezone. But that is not what you need in this case.
Try this way hope it may help:
var lastUpdatedDate = moment(utcStringFromServer);
var date = Date.UTC();
var currentDate = moment(date);
var diff = currentDate - lastUpdatedDate;
I'm assuming that utcStringFromServer is something like this:
Fri, 19 Aug 2016 04:27:27 GMT
If that's the case, you don't really need Moment.js at all. If you pass that string to Date.parse(), it'll return the number of milliseconds since Jan. 1, 1970. You can then use the .toISOString() method to get the same info about right now (converted to UTC) and parse it the same way to get milliseconds since 1970. Then, you can subtract the former from the latter and divide it by 1000 to convert back to seconds.
All in all, it would look something like this:
var lastUpdatedDate = Date.parse(utcStringFromServer);
var currentDate = Date.parse((new Date()).toISOString())
var diff = (currentDate - lastUpdatedDate) / 1000.0; // Convert from milliseconds
Related
I am attempting to show the time using milliseconds. I'm using the toLocaleTimeString since it supports the locale.
var milliseconds = 10000;
var date = new Date(milliseconds);
console.log(date.toLocaleTimeString('en',milliseconds));
// expected result - 0:0:10 AM
// actual result - 5:30:10 AM
The result is not what I'm expected. How can get the expected result using toLocaleTimeString
The normal behaviour of the .toLocaleTimeString() method is to display the time in a string representation based on the local time zone of your environment, that's why you got a different result.
And you were passing a wrong argument milliseconds to it in:
date.toLocaleTimeString('en',milliseconds);
Actually the Date.prototype.toLocaleTimeString() method takes an options object as a second argument, where you can specify several options including the timeZone which specifies the desired time zone for the output.
So call it with {"timeZone": "UTC"} to display it in UTC, like this:
date.toLocaleTimeString('en',{"timeZone": "UTC"})
Demo:
var milliseconds = 10000;
var date = new Date(milliseconds);
console.log(date.toLocaleTimeString('en',{"timeZone": "UTC"}));
// expected result - 0:0:10 AM
// actual result - 5:30:10 AM
In var date = new Date(10000);, the "10000" unit is always relative to 1970-01-01 00:00:00 in UTC timezone (i.e. add 10000ms from it). Thus, the corresponding time is equivalent to 1970-01-01 00:00:10 UTC.
date.toLocaleTimeString('en') output the time in your system timezone, thus gives the difference you found.
One way to fix is to set date variable to system timezone by adding the timezone difference in milliseconds, as the following:
var date = new Date(10000 + new Date().getTimezoneOffset()*60000); (new Date().getTimezoneOffset() is timezone difference in minutes)
I am storing a UTC date time in a SharePoint list and fetching it's value in c#, converting into milliseconds from 1 Jan 1970 and passing those milliseconds to JavaScript to get date object.
But when I create a date object, its value remains same as UTC date, I want that value to be in users local time zone and reflecting their daylight saving status.
You can use the TimezoneOffset in javascript, check the following code,
var d = new Date()
var n = d.getTimezoneOffset();
In this way you can calculate the time as you want.
Let me know if you need more details :)
When you create a new date in Javascript i assume you create it on the client side / client machine:
var d = new Date(millis);
The notion that the value remains the same in UTC no matter where you construct the Date object is correct, it's only a matter of how you display the date: in UTC or in the user's local timezone:
You can run this code to see the difference:
var local = date.toDateString() + ' ' + date.toTimeString();
var utc = date.toUTCString();
alert(local);
alert(utc);
Note that the value of millis is the milliseconds passed since 1970-01-01 00:00:00 UTC no matter where you are in this world. Calling new Date().getTime() on 2 opposite sides of the globe should return the same number of milliseconds.
So, I need to convert this kind of Date in ISO format:
"05-Mar-13 17:00:00.000000"
But when I do something like this:
var Time = (new Date("05-Mar-13 17:00:00.000000")).toISOString().replace('Z', Milliseconds);
I've got in variable Time another hour:
"2013-03-05T16:00:00.000000"
So It changes on another hour.
What should I do to avoid this changing of hours?
The ISO format is supposed to convert the time to UTC.
Your browser supposes that the time you are passing the Date constructor is based on your local time, supposedly one hour behind UTC.
To counter this, you can use
new Date().getTimezoneOffset();
which will return the time offset in minutes. In your case it will return -60.
A complete example:
function getTime() {
var date = new Date("05-Mar-13 17:00:00.000000")
date.setMinutes(date.getMinutes() - date.getTimezoneOffset());
return date.toISOString();
}
Note that this can set time minutes to a negative value, but the Date object is smart enough to convert that to a new time with positive minutes again by changing the hour.
For example I have this:
d = new Date(2013,04,20,14,56,10)
Mon May 20 2013 14:56:10 GMT+0800 (SGT)
dt = d.getTime() /1000
1369032970
Now, timezoneOffset value is
d.getTimezoneOffset()*60
-28800
So if I reduce it, I get
dt -= d.getTimezoneOffset()*60
1369061770
My question is, is 1369032970 my local timestamp, and 1369061770 UTC timestamp?
Can I safely say that any current timestamp reduced by the timezoneOffset is the UTC timestamp?
The result from getTime is in milliseconds since 1/1/1970 UTC. The local time zone plays no part in it. So if your question was how to get the UTC timestamp, simply use the result from getTime without any modification.
The idea of a "local timestamp" isn't very useful. One might apply an offset to the UTC timestamp before rendering it to a human-readable date string - but in Javascript, that's already done for you behind the scenes. You really don't want to pass a numeric timestamp to anyone else unless it is strictly UTC, because the meaning of what is "local" would be lost.
Also, when you call getTimezoneOffset, you are getting back the specific offset at the moment represented by the date - in minutes. Also, the sign is the opposite of what we normally see for time zone offsets. For example, I live in Arizona where the offset is UTC-07:00 year-round. But a call to getTimezoneOffset returns a positive value of 420. If you were to apply it a timestamp, you would do the following:
dt -= dt.getTimezoneOffset() * 60 * 1000;
You almost had it, but forgot to convert from seconds to milliseconds. But like I said, this value is meaningless. If you created a new Date object from it, it would display with the offset applied twice - once by your own code, and again by the Javascript internals.
I'm having the hardest time trying to convert this date from an API to UTC milliseconds. As of right now I'm displaying the dates but it's showing 7 hours ahead and going on to the next day which I don't even have data for. Here is the example format:
8/31/2012 9:00:00 AM
I currently have this code
var formattedDate = new Date(data[i].Time);
formattedDate = formattedDate.getTime();
which seems like it's returning the correct value type but the date is wrong. I've also tried
getUTCMilliseconds() and returns 0.
EDIT: jsfiddle example : http://jsfiddle.net/b2NK6/
So you want the raw timestamp in UTC time, instead of local time?
Compare:
(new Date(Date.UTC(2012, 7, 31, 9, 0, 0, 0))).getTime(); /* month 7 is August */
with
(new Date(Date.parse("8/31/2012 9:00:00 AM"))).getTime();
When you parse the string (the second example) it applies your local timezone information when it creates the date object. If you are in timezone -0700, then the date that is created will actually correspond to 4:00pm UTC.
But if you create the date object by explicitly saying that you are specifying the UTC value, it will give you 9:00am UTC, which corresponds to 2:00am in timezone -0700.
Edited to give clearer and more correct code example.
var dateString = "8/31/2012 9:00:00 AM"; // assuming this is expressed in local time
var millisecondsSinceTheEpoch = (new Date(dateString)).valueOf(); // 1346418000000
var isoString = (new Date(millisecondsSinceTheEpoch)).toISOString(); // 2012-08-31T13:00:00.000Z
// Note: example return values from a computer on U.S. Eastern Daylight Time (-4:00).
From W3Schools:
The valueOf() method returns the primitive value of a Date object.
Note: The primitive value is returned as the number of millisecond[s] since midnight January 1, 1970 UTC.
Also see W3Schools for a comprehensive overview of the Date object.
HighStocks expects to get its dates aligned to UTC-midnight date boundary.
Assuming your chart only deals with dates (without the time component) here is a trick you can use:
Do originalDate.getTime() to get the number of milliseconds since midnight UTC 1/1/1970 , e.g. 1362286800000.
Divide the number of milliseconds by (1000*60*60*24) to get the number of days since midnight UTC 1/1/1970 e.g. 15767.208333333334.
Do Math.round() to round the number to the nearest UTC midnight, e.g. 15767.
Multiply the number by (1000*60*60*24) to get it back into the milliseconds scale e.g. 1362268800000.
Here is the final formula:
var utcMidnight=new Date(Math.round(anyZoneMidnight.getTime()/86400000)*86400000)