While writing a web application, it makes sense to store (server side) all datetimes in the DB as UTC timestamps.
I was astonished when I noticed that you couldn't natively do much in terms of Timezone manipulation in JavaScript.
I extended the Date object a little. Does this function make sense? Basically, every time I send anything to the server, it's going to be a timestamp formatted with this function...
Can you see any major problems here? Or maybe a solution from a different angle?
Date.prototype.getUTCTime = function(){
return new Date(
this.getUTCFullYear(),
this.getUTCMonth(),
this.getUTCDate(),
this.getUTCHours(),
this.getUTCMinutes(),
this.getUTCSeconds()
).getTime();
}
It just seems a little convoluted to me. And I am not so sure about performance either.
Use the getTime() method to get a UTC timestamp, e.g. new Date(). getTime() . The method returns the number of milliseconds since the Unix Epoch and always uses UTC for time representation. Calling the method from any time zone returns the same UTC timestamp.
UTC() method in JavaScript is used to return the number of milliseconds in a Date object since January 1, 1970, 00:00:00, universal time. The UTC() method differs from the Date constructor in two ways: Date. UTC() uses universal time instead of the local time.
In JavaScript, in order to get the current timestamp, you can use Date. now() . It's important to note that Date. now() will return the number of milliseconds since January, 1 1970 UTC.
now() The static Date. now() method returns the number of milliseconds elapsed since January 1, 1970 00:00:00 UTC.
Dates constructed that way use the local timezone, making the constructed date incorrect. To set the timezone of a certain date object is to construct it from a date string that includes the timezone. (I had problems getting that to work in an older Android browser.)
Note that getTime()
returns milliseconds, not plain seconds.
For a UTC/Unix timestamp, the following should suffice:
Math.floor((new Date()).getTime() / 1000)
It will factor the current timezone offset into the result. For a string representation, David Ellis' answer works.
To clarify:
new Date(Y, M, D, h, m, s)
That input is treated as local time. If UTC time is passed in, the results will differ. Observe (I'm in GMT +02:00 right now, and it's 07:50):
> var d1 = new Date();
> d1.toUTCString();
"Sun, 18 Mar 2012 05:50:34 GMT" // two hours less than my local time
> Math.floor(d1.getTime()/ 1000)
1332049834
> var d2 = new Date( d1.getUTCFullYear(), d1.getUTCMonth(), d1.getUTCDate(), d1.getUTCHours(), d1.getUTCMinutes(), d1.getUTCSeconds() );
> d2.toUTCString();
"Sun, 18 Mar 2012 03:50:34 GMT" // four hours less than my local time, and two hours less than the original time - because my GMT+2 input was interpreted as GMT+0!
> Math.floor(d2.getTime()/ 1000)
1332042634
Also note that getUTCDate()
cannot be substituted for getUTCDay()
. This is because getUTCDate()
returns the day of the month; whereas, getUTCDay()
returns the day of the week.
The easiest way of getting UTC time in a conventional format is as follows:
> new Date().toISOString()
"2016-06-03T23:15:33.008Z"
if you need EPOC timestamp, pass your date to Date.parse method
> Date.parse(new Date)
1641241000000
> Date.parse('2022-01-03T20:18:05.833Z')
1641241085833
Or you can use + for type casting from Date to Int
> +new Date
1641921156671
EPOC timestamp in seconds.
> parseInt(Date.parse('2022-01-03T20:18:05.833Z') / 1000)
1641241085
> parseInt(new Date / 1000)
1643302523
You could also do it utilizing getTimezoneOffset and getTime,
x = new Date()
var UTCseconds = (x.getTime() + x.getTimezoneOffset()*60*1000)/1000;
console.log("UTCseconds", UTCseconds)
I actually think Date values in js are far better than say the C# DateTime objects. The C# DateTime objects have a Kind property, but no strict underlying time zone as such, and time zone conversions are difficult to track if you are converting between two non UTC and non local times. In js, all Date values have an underlying UTC value which is passed around and known regardless of the offest or time zone conversions that you do. My biggest complaint about the Date object is the amount of undefined behaviour that browser implementers have chosen to include, which can confuse people who attack dates in js with trial and error than reading the spec. Using something like iso8601.js solves this varying behaviour by defining a single implementation of the Date object.
By default, the spec says you can create dates with an extended ISO 8601 date format like
var someDate = new Date('2010-12-12T12:00Z');
So you can infer the exact UTC time this way.
When you want to pass the Date value back to the server you would call
someDate.toISOString();
or if you would rather work with a millisecond timestamp (number of milliseconds from the 1st January 1970 UTC)
someDate.getTime();
ISO 8601 is a standard. You can't be confused about what a date string means if you include the date offset. What this means for you as a developer is that you never have to deal with local time conversions yourself. The local time values exist purely for the benefit of the user, and date values by default display in their local time. All the local time manipulations allow you to display something sensible to the user and to convert strings from user input. It's good practice to convert to UTC as soon as you can, and the js Date object makes this fairly trivial.
On the downside there is not a lot of scope for forcing the time zone or locale for the client (that I am aware of), which can be annoying for website-specific settings, but I guess the reasoning behind this is that it's a user configuration that shouldn't be touched.
So, in short, the reason there isn't a lot of native support for time zone manipulation is because you simply don't want to be doing it.
You generally don't need to do much of "Timezone manipulation" on the client side. As a rule I try to store and work with UTC dates, in the form of ticks
or "number of milliseconds since midnight of January 1, 1970." This really simplifies storage, sorting, calculation of offsets, and most of all, rids you of the headache of the "Daylight Saving Time" adjustments. Here's a little JavaScript code that I use.
To get the current UTC time:
function getCurrentTimeUTC()
{
//RETURN:
// = number of milliseconds between current UTC time and midnight of January 1, 1970
var tmLoc = new Date();
//The offset is in minutes -- convert it to ms
return tmLoc.getTime() + tmLoc.getTimezoneOffset() * 60000;
}
Then what you'd generally need is to format date/time for the end-user for their local timezone and format. The following takes care of all the complexities of date and time formats on the client computer:
function formatDateTimeFromTicks(nTicks)
{
//'nTicks' = number of milliseconds since midnight of January 1, 1970
//RETURN:
// = Formatted date/time
return new Date(nTicks).toLocaleString();
}
function formatDateFromTicks(nTicks)
{
//'nTicks' = number of milliseconds since midnight of January 1, 1970
//RETURN:
// = Formatted date
return new Date(nTicks).toLocaleDateString();
}
function formatTimeFromTicks(nTicks)
{
//'nTicks' = number of milliseconds since midnight of January 1, 1970
//RETURN:
// = Formatted time
return new Date(nTicks).toLocaleTimeString();
}
So the following example:
var ticks = getCurrentTimeUTC(); //Or get it from the server
var __s = "ticks=" + ticks +
", DateTime=" + formatDateTimeFromTicks(ticks) +
", Date=" + formatDateFromTicks(ticks) +
", Time=" + formatTimeFromTicks(ticks);
document.write("<span>" + __s + "</span>");
Returns the following (for my U.S. English locale):
ticks=1409103400661, DateTime=8/26/2014 6:36:40 PM, Date=8/26/2014, Time=6:36:40 PM
If you want a one liner, The UTC Unix Timestamp can be created in JavaScript as:
var currentUnixTimestap = ~~(+new Date() / 1000);
This will take in account the timezone of the system. It is basically time elapsed in Seconds since epoch.
new Date()
.unary +
before object creation to convert it to timestamp integer
. : +new Date()
.+new Date() / 1000
~~(+new Date())
I think this is a better solution
// UTC milliseconds
new Date(Date.now()+(new Date().getTimezoneOffset()*60000)).getTime()
// UTC seconds
new Date(Date.now()+(new Date().getTimezoneOffset()*60000)).getTime()/1000|0
Since new Date().toUTCString()
returns a string like "Wed, 11 Oct 2017 09:24:41 GMT"
you can slice the last 3 characters and pass the sliced string to new Date()
:
new Date()
// Wed Oct 11 2017 11:34:33 GMT+0200 (CEST)
new Date(new Date().toUTCString().slice(0, -3))
// Wed Oct 11 2017 09:34:33 GMT+0200 (CEST)
I use the following:
Date.prototype.getUTCTime = function(){
return this.getTime()-(this.getTimezoneOffset()*60000);
};
Once defined this method you can do:
var utcTime = new Date().getUTCTime();
I want to make clear that new Date().getTime() does in fact return a UTC value, so it is a really helpful way to store and manage dates in a way that is agnostic to localized times.
In other words, don't bother with all the UTC javascript functions. Instead, just use Date.getTime().
More info on the explanation is here: If javascript "(new Date()).getTime()" is run from 2 different Timezones.
I am amazed at how complex this question has become.
These are all identical, and their integer values all === EPOCH time :D
console.log((new Date()).getTime() / 1000, new Date().valueOf() / 1000, (new Date() - new Date().getTimezoneOffset() * 60 * 1000) / 1000);
Do not believe me, checkout: http://www.epochconverter.com/
I think this what you are expecting...
var currTimestamp = Date.now(), //1482905176396
utcDateString = (new Date(currTimestamp)).toUTCString(); //"Wed, 28 Dec 2016 06:06:50 GMT"
Now,
new Date(utcDateString).getTime(); //This will give you UTC Timestamp in JavaScript
EDIT: The code below does NOT work. I was always assuming that new Date().getTime() returned the number of seconds since the 1st of January 1970 IN THE CURRENT TIMEZONE. This is not the case: getTime() returns the number of seconds in UTC. So, the code below does gross over-adjusting. Thank you everybody!]
First of all, thank you for your fantastic insights. I guess my question had the wrong title... it should have been "Get the UTC Unix Timestamp for an existing date".
So, if I have a date object:
var d = new Date(2009,01,31)
I was after a function that would tell me "The UTC Unix Timestamp".
This function seems to be the real trick:
Date.prototype.getUTCUnixTime = function (){
return Math.floor( new Date(
this.getUTCFullYear(),
this.getUTCMonth(),
this.getUTCDate(),
this.getUTCHours(),
this.getUTCMinutes(),
this.getUTCSeconds()
).getTime() / 1000);
}
Note that it works on "this" This means that I can do:
var n = new Date(2008,10,10)
...
...
n.getUTCUnixTime();
And get the number of seconds since the 1st of Jan 1970 in Unix time. Right?
It's a little insane, to me, that Javascript stores everything in UTC times, but then in order to get that number I have to create a new Date object passing the individual UTC getters and then finally call getTime() for that...
Merc.
Just do:
const time = new Date().getTime();
MDN states that:
Date.prototype.getTime() Returns the numeric value of the specified date as the number of milliseconds since January 1, 1970, 00:00:00 UTC. (Negative values are returned for prior times.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With