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.
Related
We escape of using moment now and use date-fns instead. In some places we still use moment on front.
Example of code on server
//date in yyyy/mm/dd format in query params
startOfDay = StartOfDay(new Date(date));
return startOfDay
And when I display this date on front, she changes to local timezone(-4 hours). If i use date-fns-tz and convert to Canada timezone, I will get date with -4 hours and after display -4 hours more. How to resole this issue? I need to add 4 hours to date for my current timeZone. My utcOffset = 4.
Although I am not sure what function your are currently using from date-fns-ts, what has worked for me is to use utcToZonedTime(). This function gets
a date/time in the local time of any time zone from UTC time
import { utcToZonedTime } from 'date-fns-tz'
const now = new Date() // UTC
const nowCustomTimeZone = utcToZonedTime(now, 'Europe/Amsterdam')
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
on my UI, I try to display a date based on a specific timezone. In this example, I will use Americas/New_York as the timezone. This is how I did it.
$scope.getStartTime = function(){
var date = new Date();
return moment(date).tz("Americas/New_York").format('YYYY-MM-DD HH:mm:ss');
};
Afterwards, I want to send this data and send it to my server. In my server however, I want it so that it is always serialized into UTC time instead of in the New York Timezone (EST).
For example, if the time was 12:00 P.M. in New York, then the time would be serialized to 4:00 P.M. in UTC time before it was sent to the backend. This was my attempt:
var date = getStartTime();
....
// Display the date in the UI
....
$scope.revertStartTime(date);
$scope.revertStartTime = function(startTime) {
console.log("Start time: ", startTime);
console.log("Moment: ", moment(startTime).format());
console.log("Converted to utc time: ", moment().utc(startTime).format());
return moment.utc(startTime).format("YYYY-MM-DD'T'HH:mm:ss.SSSZ");
}
I tried to revert the start time by using the moment().utc() function and hoped that the date would change to a UTC based date but unfortunately it keeps turning my date into the localized date instead of UTC date and I'm not sure why. Any help would be appreciated. Thanks!
Edit:
Tried to follow the below method and here is what I did:
$scope.getStartTime = function(){
var date = new Date();
var startTime = new moment(date).tz($rootScope.userinfo.timeZone).format('YYYY-MM-DD HH:mm:ss');
$rootScope.offset = moment().utcOffset(startTime);
console.log("offset: ", $rootScope.offset);
return startTime;
};
$scope.revertStartTime = function(startTime) {
console.log("User Selected Time: ", moment().utcOffset(startTime).format('YYYY-MM-DD HH:mm:ss'));
return moment().utcOffset(startTime).format('YYYY-MM-DD HH:mm:ss');
}
But all I get is an error saying that revertStartTime returns an Invalid Date.
A few things:
Hoping it's a typo, but just to point out, the zone ID is America/New_York, not Americas/New_York.
You can pass a value as moment.utc(foo), or moment(foo).utc(), but not moment().utc(foo). The difference is that one interprets the input as UTC and stays in UTC mode, while they other just switches to UTC mode. You can also think of this as "converting to UTC", but really the underlying timestamp value doesn't change.
Yes, you can switch to UTC mode and call format, but you can also just call .toISOString() regardless of what mode you're in. That's already in the ISO format you're looking for.
Note that if you start with a unique point in time, and you end with converting to UTC, no amount of switching time zones or offsets in the middle will change the result. In other words, these are all equivalent:
moment().toISOString()
moment.utc().toISOString()
moment(new Date()).toISOString()
moment.utc(new Date()).toISOString()
moment(new Date()).utc().toISOString()
moment().tz('America/New_York').toISOString()
moment.tz('America/New_York').toISOString()
moment().utcOffset(1234).toISOString()
moment.utc().format('YYYY-MM-DD[T]HH:mm:ss.SSS[Z]')
moment().utc().format('YYYY-MM-DD[T]HH:mm:ss.SSS[Z]')
Only the last two even need to be in UTC mode, because the format function would produce different output if in local mode or in a particular time zone.
In order to accomplish this you'd want to use .utcOffset(). It is the preferred method as of Moment 2.9.0. This function uses the real offset from UTC, not the reverse offset (e.g., -240 for New York during DST). Offset strings like "+0400" work the same as before:
// always "2013-05-23 00:55"
moment(1369266934311).utcOffset(60).format('YYYY-MM-DD HH:mm')
moment(1369266934311).utcOffset('+0100').format('YYYY-MM-DD HH:mm')
The older .zone() as a setter was deprecated in Moment.js 2.9.0. It accepted a string containing a timezone identifier (e.g., "-0400" or "-04:00" for -4 hours) or a number representing minutes behind UTC (e.g., 240 for New York during DST).
// always "2013-05-23 00:55"
moment(1369266934311).zone(-60).format('YYYY-MM-DD HH:mm')
moment(1369266934311).zone('+0100').format('YYYY-MM-DD HH:mm')
To work with named timezones instead of numeric offsets, include Moment Timezone and use .tz() instead:
// determines the correct offset for America/Phoenix at the given moment
// always "2013-05-22 16:55"
moment(1369266934311).tz('America/Phoenix').format('YYYY-MM-DD HH:mm')
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.
Hi I am trying to create a unix timestamp to represent the latest time of the current day (23:59:59) like so:
current_date = new Date();
end = new Date(current_date.getFullYear(), current_date.getMonth(), current_date.getDate(),23,59,59);
end = end.getTime() / 1000;
When I alert out the unix timestamp and convert it back into a datetime though it is an hour behind and represents 22:59:59 rather than 23:59:59.
I have to pass 24 to the date function for the hour parameter instead of 23 if I want 11pm is this right?
I am located in England so my time should be in GMT
new Date() will create the date in your timezone, whereas timestamps are in UTC. You appear to be in BST (GMT+1) hence the off-by-one error.
Instead, create a date and then use setUTCHours(23), setUTCMinutes(59) and setUTCSeconds(59) to get the correct timestamp.