i am printing a timestamp in console of chrome browser using following code,
moment("2021-01-12 00:00:00").utc().utcOffset(-new Date().getTimezoneOffset()).format('x')
this line prints the timestamp at given time and date.
if i change timezone from "windows Date and time settings" , the output of above line also changes .
how can i make output of above line constant irrespective of timezone of current browser window ?
The documentation for Date.protoype.getTime() states:
The getTime() method returns the number of milliseconds* since the Unix Epoch.
* JavaScript uses milliseconds as the unit of measurement, whereas Unix Time is in seconds.
getTime() always uses UTC for time representation. For example, a client browser in one timezone, getTime() will be the same as a client browser in any other timezone.
As such the timestamp you get from a Date is always UTC with timezone information taken from the host environment (OS).
By default JavaScript (and moment) will parse dates and times assuming they are in the user's local timezone and therefore affected by changes to Windows date and time settings.
To keep it consistent you need to tell moment to parse the value as UTC.
const timestamp = moment.utc("2021-01-12 00:00:00").format("x");
console.log(timestamp); // prints 1610409600000
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
No matter which timezone you're in, you should get the value 1610409600000 logged to the console.
Related
I wanted to know if a date object created at any point of time differ based on time zones or not. I tried this by executing new Date().getTime() once for IST and immediately again by setting my PC time zone to GMT. The resultant values are:
IST - 1633334780053
GMT - 1633334788831
A difference of around 8000 milliseconds
From this it seems that datetime objects created at same moment are exactly same no matter in which time zone they are created. Please suggest if this understanding is correct or is there more to it.
You're right. Two different date time objects created at the same point of time are same no matter the time zone.
They can be formatted to their corresponding timezone representation using javascript.
One important thing to be noted is that the date time object created uses the system's date time configuration to find the correct time. If the system's date and time configurations are correct and in sync, then the date time object created in the browser will be correct and will match the system time at the time of creating that object.
This is detailed in the JavaScript specification: https://tc39.es/ecma262/#sec-date-objects.
More information is in the MDN docs Date.getTime():
The getTime() method returns the number of milliseconds* since the Unix Epoch.
*JavaScript uses milliseconds as the unit of measurement, whereas Unix Time is in seconds.
getTime() always uses UTC for time representation. For example, a client browser in one timezone, getTime() will be the same as a client browser in any other timezone.
So new Date().getTime() will always return the number of milliseconds since 1970-01-01 00:00:00 UTC, regardless of the client / machine timezone setting.
is it possible to convert a UTC date coming from a server to a specific (UK) timezone using JavaScript? This is for the case where users may have the incorrect local timezone configured.
You can specify a time zone in the options passed to toLocaleString, which will use the point-in-time represented by the Date object to create a localized string that is converted to the specified time zone.
For example:
new Date("2020-09-17T17:15:00.000Z").toLocaleString('en-GB', { timeZone: 'Europe/London' })
//=> "17/09/2020, 18:15:00"
Note the first parameter is the locale for the format, not the time zone. If you don't want a specific format, you can pass undefined instead - which will use the user's active locale settings to choose the format.
Note also that you can not get a Date object that is in that time zone. The Date object only stores a point in time (as a Unix timestamp with millisecond precision), and it always uses the computer's local time zone setting for its functions that need local time conversions (except as show above).
(The TC39 Temporal proposal is working to improve this.)
According to this date-time strings without a time zone should be interpreted as local time.
When the time zone offset is absent, date-only forms are interpreted as a UTC time and date-time forms are interpreted as local time.
Our API returns time stamps of various different time zones but we always want to display them in those different time zones (these are flight times and are always shown as local to the airport).
In most browsers I can pass this string to a Date object and it is interpreted as the user's local time zone but I don't care that it's the wrong time zone since we don't compare Dates across time zones. When I use Intl.DateTimeFormat.format to display it as a string it displays the same time as the string specifies which is what I want.
In Safari these time strings are interpreted as UTC and then the string format converts it to local time.
new Date("2020-05-06T13:25:00").getTime() === new Date("2020-05-06T13:25:00Z").getTime()
This returns true in Safari but false everywhere else. (It will also return true if your local timezone is UTC but we're not considering that case).
This is Safari running on a computer set to CDT. It taken 13:25 as UTC then displaying it with -5 hours.
This is Chrome (on Windows - not sure if that's relevant, I don't have access to a Mac). But it's taking the same timestamp as being local time and so then displays it as the same time. This is what I want.
Is there anyway we can work around this so I can return a time stamp which is then parsed as local time so it displays correctly.
I am using new Date(<date-string>) and then .getTime() to pass date strings to milliseconds from 1970.
The problem is that the date strings does not contain the timezone on them. They are British, so the timezone will be GMT or GMT+1 depending on the date...
When I use this technique in the front-end (Chrome), or in the back-end (Node.js). The time zone taken is the British one (GMT or GMT+1 depending on the date). I assume that is taken from the OS.
However, when using a Node.js server which I have been told is configured to be in UTC... the timezone is always going to be GMT, leading to errors during the British Summer Time.
Is there any way to tell Date to take the timezone from the OS without changing the server configuration?
Example:
var aDate = new Date('2016-06-23 10:15:0');
var timestamp = aDate.getTime();
Just in case my explanation is not clear:
// Executed on 28-06-2016
// In the browser (in London)
new Date().getTimezoneOffset(); // -60
new Date('28-06-2016 11:11:11').getTimezoneOffset(); // -60
new Date('28-01-2016 11:11:11').getTimezoneOffset(); // 0
// In the Node.js server I am forced to use, which is configured to use UTC
new Date().getTimezoneOffset(); // 0
new Date('28-06-2016 11:11:11').getTimezoneOffset(); // 0
new Date('28-01-2016 11:11:11').getTimezoneOffset(); // 0
// Ideally, I would like to have the output I get in the browser when I run the code in the UTC Node.js server
I recommend using Moment Timezone for this, since this would be needlessly complicated to implement without a library. To get UTC in milliseconds from a given date in a given timezone, you can do this:
const moment = require('moment-timezone');
function londonTimeToUTC(dateString) {
return moment.tz(dateString, 'DD-MM-YYYY HH:mm:ss', 'Europe/London').valueOf();
}
console.log(londonTimeToUTC('28-06-2016 11:11:11')); // 1467108671000
console.log(londonTimeToUTC('28-01-2016 11:11:11')); // 1453979471000
The second argument passed to moment.tz() is a format string, which is necessary if the date string is not in ISO format. The third argument is any valid timezone identifier.
Is there any way to tell Date to take the timezone from the OS without changing the server configuration?
The time zone from the OS is what the Date object uses. If you're asking if you can change that time zone without changing the configuration, then no - there is not a way to do that. The Date object always takes on the behavior of the local time zone. Even if you supply an offset in the input string, it just uses that to determine the internal UTC timestamp. Output via most of the properties (including toString and getTimezoneOffset) will always use the local time zone.
Even in your examples, you cannot count on the browser behavior always returning the values you showed, simply because each user visiting your web site may have a different time zone setting.
The recommended way to deal with this is by using the moment.js library, which can handle UTC and local time by itself, but may require use of the moment-timezone extension if you are wanting to work with a specific time zone, such as Europe/London.
Now, with that said, if you're certain that your entire node.js application will run in a single time zone, and you're running on Linux or OSX (not Windows), then you can indeed change which time zone that node.js considers to be "local". Simply set the TZ environment variable before you launch node, like this:
env TZ='Europe/London' node server.js
There is no equivalent for the browser, or for Windows. And you still have to contend with possible non-UK users on your web site - so this doesn't guaranteed a match between client and server time. But it does address your question.
See also:
How to initialize javascript date to a particular timezone
How to make the timezone of date to UTC
How to set default timezone in Node.js
My app is based on XULRUNNER. I found when I fetch the current timestamp with Date.prototype.getTime, It seems give me the GMT time not the time of my time zone. But in firefox, there is no such a problem. I am confused that is there a way to set the time zone in xulrunner with JS.
Date.prototype.getTime doesn't really have a notion of UTC or timezone, it's a number of milliseconds elapsed since a specific point in time, the Unix EPOCH, which happens to be defined in UTC. If you convert it to a date manually, you will always get a value seemingly in UTC, in XULRunner or Firefox.
You need to use the other methods on Date objects to retrieve the time in the local timezone.
var now = new Date();
console.log(now.getTime()); // 1390141979617
console.log(now.getUTCHours()); // 14
console.log(now.getHours()); // 9
Compare the results of toString() and toLocaleString()