How do I get a UTC Timestamp in JavaScript?
Asked Answered
G

17

239

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.

Glebe answered 18/3, 2012 at 4:57 Comment(3)
I know this is kind of an old question, but try not to extend native objects like the Date object. Upvoted because I like the question itself.Mam
Date.parse(new Date().toUTCString())Anesthesiology
This is an old question that came up in my feed today, and it's full of misinformation. Timestamp is always in UTC. new Date().toString() will show you current time zone time representation, new Date().toUTCString() will show you UTC time repr, but new Date().getTime() is always UTC, because that is what Unix time is defined as: "Unix time (also known as POSIX time or epoch time) is a system for describing instants in time, defined as the number of seconds that have elapsed since 00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970, not counting leap seconds."Buine
O
209
  1. 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.)

  2. 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.

Od answered 18/3, 2012 at 5:14 Comment(5)
1) I didn't construct a date... I added a prototype function that worked on this. 2) Good point, I should do the Math.floor / 1000 -- but still I would need that function in order to have the UTC timestamp of an existing date object... right?Glebe
@Merc: 1) you are calling new Date(), that creates a new date from your UTC input but treats it as local date/time. 2) Yes, you should use Math.floor(this.getTime() / 1000) in this case.Od
Answering here as I need to update the code... This is to have the Unix timestamp in UTC for an existing date: function (){ return Math.floor( new Date( this.getUTCFullYear(), this.getUTCMonth(), this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds() ).getTime() / 1000); } This means that I can do: var n = new Date(2008,10,10) ... ... n.getUTCTime(); (This will be DIFFERENT to n.getUTCTime() )Glebe
Thanks Bro Its working file Math.floor((new Date()).getTime() / 1000)Zaxis
I need the UTC Hours and Minutes and this helped me d1.getUTCHours(), d1.getUTCMinutes().Zibeline
M
133

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
Measureless answered 4/6, 2016 at 0:29 Comment(8)
This is the correct answer. Lots of other answers give a "universal time string" but do not give the current "universal coordinated time". I do not understand why everything is so complicated here.Dulcedulcea
Thank you @gburton. Appreciate you see the simple way to truth. :)Measureless
I use this, along with ".split('T')[0]" for easy YYYY-MM-DD date-based comparisons.Kremlin
Nice to have @SeanOMeasureless
This provides a UTC time string, but OP is asking for a UTC timestamp (epoch)Concuss
This is misleading, it does NOT provide a UTC timestampBerti
> why everything is so complicated here - because web-development is all about JS which was made up in 1995.. the majority of them are not very bright so they steamroll any attempt of innovation being afraid of loosing their piece of stale bread.Cattail
EPOC timestamp is also added to the post.Measureless
S
75

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)
Sholes answered 18/3, 2012 at 5:21 Comment(5)
Thanks, this is nowhere to be found on the internet!Parsimony
I test the following codes: var tt = new Date('Thu Jan 01 1970 08:00:00 GMT+0800 (China Standard Time)'); (tt.getTime() - tt.getTimezoneOffset()*60*1000)/1000. It seems tt.getTime() - tt.getTimezoneOffset() is correct for GMT+0800.Callao
This is more better var UTCseconds = (Math.floor(x.getTime()/1000) + x.getTimezoneOffset()*60)Pileup
It looks like this doesn't work as written.. It looks like you have to pass in time string into new Date() that includes a timezone..which kinda defeats the purpose of trying to do it in js..Aglimmer
This is simply wrong, the value assigned to UTCseconds is not UTC seconds.. A Date's time value is UTC, changing it by whatever method means it represents a different moment in time.Telescopic
P
17

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.

Perilune answered 18/3, 2012 at 6:29 Comment(0)
A
13

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

Aver answered 26/8, 2014 at 18:42 Comment(9)
By adding the getTimezoneOffset value in your getCurrentTimeUTC function, you're actually returning a different point in time. The result of getTime is already in UTC.Sharpfreeze
@MattJohnson: That is incorrect. The result of tmLoc.getTime() is an offset against local time. That is easy to check if you have access to anything that runs JavaScript.Aver
Sorry, but that's not true. See the MDN reference. You can also see this in the ECMAScript spec. §15.9.3.3 describes getTime, which points you at the "time value" defined in §15.9.5, which is a PrimitiveValue, as set in §15.9.3.3 explicitly as UTC.Sharpfreeze
As an experiment, you can try two machines (with their clocks set correctly) set in two different time zones. Running simultaneously new Date().getTime() should result in near identical values, despite the time zone difference. The difference between them should be on the order of seconds or milliseconds due to clock synchronization, but not on the order of hours that time zone adjustments would account for.Sharpfreeze
@MattJohnson: Simply get the value from tmLoc.getTime() and calculate it yourself "on the back of the napkin."Aver
Well, since you obtain tmLoc via new Date(), then its the same thing. The time zone will affect the string output of tmLoc.toString() and similar items, but it will not affect tmLoc.getTime() That's always just a number of milliseconds since midnight 1970-01-01 in UTC.Sharpfreeze
Can I know where do you get 60000?Pileup
@StefansArya: //The offset is in minutes -- convert it to msAver
So if it was GMT+2, getTimezoneOffset() will return -60*2= -120 minutes then convert it to ms.. Ok, got the idea. Thanks!Pileup
C
13

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.

How it works:

  • Create date object : new Date().
  • Convert to timestamp by adding unary + before object creation to convert it to timestamp integer. : +new Date().
  • Convert milliseconds to seconds: +new Date() / 1000
  • Use double tildes to round off the value to integer. : ~~(+new Date())
Color answered 27/3, 2015 at 7:13 Comment(3)
Do not use this. With the current ecma spec, bitwise operations (like the tilde - bitwise not) handle signed integer values of 32 bits. That means this tilde magic will not work after 19 jan 2038 when timestamp value will be over the max value of a 32 bit signed integer. jsfiddle.net/phb20ymbBlockish
@Blockish I use this because it's still not 2038 yet!Nostradamus
I promise to come to downvote this answer 20.1.2038.Tahmosh
P
7

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
Poe answered 7/12, 2016 at 9:56 Comment(1)
Another wrong answer, getTime returns a UTC offset, adding the local timezone offset completely messes it up. The ECMAScript offsets are +ve for west and -ve for east, so they should be subtracted from UTC to get local. But since the time value is UTC to start with, adding it essentially shifts it away from UTC in the opposite direction to the local offset.Telescopic
H
7

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)
Harmonious answered 11/10, 2017 at 9:40 Comment(0)
B
6

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();
Blowfly answered 24/11, 2016 at 11:46 Comment(6)
Cleanest solution. THX!Mariselamarish
But that's not a clean solution to send dates, because TimeStamps are always UTC. Best solution for me when sending dates, is to use a string representation like "dd/MM/yyyy HH:mm:ss" and then parse it on server side with server's default TimeZone to get an UTC timestamp or whatever. See this answerBlowfly
parsing a string - you're calling that clean? mehMariselamarish
Be sure, there are methods to generate a date in string format according to ISO specifications. The method is toISOString(). You can parse it cleanly in Java using something like: DateTime dt = new DateTime ("2018-07-15T02:36:00+02:00");Blowfly
Another wrong answer, this.getTime() returns a UTC offset, subtracting the local timezone offset makes it local, not UTC so getUTCTime returns a local offset, not UTC.Telescopic
I agree... 4 years before ;)... correct method name will be 'getLocalTimestamp'... useless method.Blowfly
U
4

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.

Undershorts answered 21/3, 2015 at 1:5 Comment(0)
A
3

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
Agrimony answered 28/12, 2016 at 6:10 Comment(1)
Is there any reason why you don't do new Date().toUTCString() ?Qp
T
2

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/

Tittivate answered 31/5, 2014 at 0:12 Comment(0)
G
1

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.

Glebe answered 18/3, 2012 at 15:39 Comment(2)
did you see @DCoder's update to his answer? Your method getUTCUnixTime gets the wrong time, and JavaScript does provide a straightforward way to get the unix timestamp from a Date object - using the getTime method. See all other answers.Protuberancy
Ugh you are right, just saw them. (Banging head against wall)Glebe
M
0

Once you do this

new Date(dateString).getTime() / 1000

It is already UTC time stamp

   const getUnixTimeUtc = (dateString = new Date()) => Math.round(new Date(dateString).getTime() / 1000)

I tested on https://www.unixtimestamp.com/index.php

Mame answered 9/4, 2020 at 15:38 Comment(0)
W
0

I've found an easyest way to get UTC timestamp by adding unary + before date object.

Note: The time value at the heart of a Date object is UTC

const date = new Date();

const UTC_Timestamp = +date; 

console.log(UTC_Timestamp);

This gives the same result as Date.prototype.getTime() and Date.now()

Whipstall answered 16/2 at 6:11 Comment(0)
H
-1

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

Hildebrand answered 11/7, 2022 at 10:42 Comment(2)
just do const time = +new Date();Furiya
This doesnt give UTC timeSnake
S
-3

This will return the timestamp in UTC:

var utc = new Date(new Date().toUTCString()).getTime();
Subdelirium answered 27/1, 2017 at 3:14 Comment(1)
This does not return the time in UTC: new Date(new Date().toUTCString()) gives Wed Oct 04 2017 07:20:14 GMT+0200 (GMT+02:00)Heymann

© 2022 - 2024 — McMap. All rights reserved.