831

Suppose a user of your website enters a date range.

2009-1-1 to 2009-1-3

You need to send this date to a server for some processing, but the server expects all dates and times to be in UTC.

Now suppose the user is in Alaska. Since they are in a timezone quite different from UTC, the date range needs to be converted to something like this:

2009-1-1T8:00:00 to 2009-1-4T7:59:59

Using the JavaScript Date object, how would you convert the first "localized" date range into something the server will understand?

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
dthrasher
  • 40,656
  • 34
  • 113
  • 139
  • 14
    resurrected this because it was the top Google hit for me, and newer browsers have built-in support for UTC date strings. – jcomeau_ictx Jun 28 '12 at 14:25
  • 5
    I updated the accepted answer to highlight the new ECMAscript 5 toISOString() method. See http://stackoverflow.com/a/11957822/19112 – dthrasher Jan 30 '13 at 19:18
  • 9
    so in 2015 i have to mess with stringifying and parsing dates? ridiculous! – Toolkit Feb 23 '15 at 05:48
  • 2
    Of course you have. You cannot ever rely on someone else doing the work for you :-P At least until the world stops using timezones and begin unifing the dates and times. – Erenor Paz Jul 10 '17 at 08:53
  • 7
    "Stardates", preferably. – Michael Daw Dec 14 '17 at 22:20
  • 2
    "*of course you have*" --- No,. of course not. We are talking about a set of problems that is solved for at least 20 years and it is an absolutely valid approach to just expect things like these from some run time library impl that deals with date and time and UTC. Or are you "of course" write your own OS yourself because "You cannot ever rely on someone else doing the work for you"? – JensG Aug 31 '21 at 10:32
  • add ` GMT` to the date string, and it does the trick – T.Todua Sep 04 '22 at 15:15

35 Answers35

716

Simple and stupid

var date = new Date();
var now_utc = Date.UTC(date.getUTCFullYear(), date.getUTCMonth(),
                date.getUTCDate(), date.getUTCHours(),
                date.getUTCMinutes(), date.getUTCSeconds());

console.log(new Date(now_utc));
console.log(date.toISOString());
RobG
  • 142,382
  • 31
  • 172
  • 209
DrunkCoder
  • 8,215
  • 3
  • 19
  • 14
  • 106
    I liked your idea and did a method I've been using many times. `function convertDateToUTC(date) { return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds()); }` – Tim Oct 04 '11 at 14:45
  • 32
    The shortest code I came up with to get the UTC date and time is by lopping off the time zone: `new Date(new Date().toUTCString().substr(0, 25))` – joelvh Mar 18 '12 at 03:58
  • 1
    Maybe `now.setMinutes(now.getMinutes()+now.getTimezoneOffset());` or `now.setUTCMinutes(now.getUTCMinutes()+now.getTimezoneOffset());`? They both seem to return the same thing. – Webveloper Apr 28 '12 at 04:31
  • 18
    Note that getUTCMonth() returns values 0 to 11. So if you are needing the month by number instead of a string, it helps to +1 to the value. – Talvi Watia Jun 06 '12 at 16:51
  • 1
    Wouldn't it just be sufficient to do: `var now = new Date(); var now_utc = new Date(now); now_utc.setMinutes(now_utc.getMinutes() - now_utc.getTimezoneOffset());`? – Victor Zamanian Dec 13 '12 at 21:31
  • 36
    This is nonsense. The new Date will have a different value than you actually want. Just use `now.toUTCSTring()` instead of (wrong) `now_utc.toString()`. – Bergi Jan 25 '13 at 15:02
  • 4
    For me, this created a date that **displayed as UTC** time, but was **not actually UTC** time. More Info in my answer below: http://stackoverflow.com/questions/948532/how-do-you-convert-a-javascript-date-to-utc/14610512#14610512 – Aaron Hoffman Jan 30 '13 at 17:56
  • You might want to add now.getUTCMilliseconds() to this, if you want to preserve milliseconds as well. – eselk Aug 01 '13 at 16:54
  • 37
    I would not use this - by using new Date() you get the brower's timezone. in Chrome 29 and IE10, the date + time appear to be correct, but the timezone is set to the browser's timezone, which could cause issues ... – Sean Aug 29 '13 at 14:21
  • 1
    Is this solution DST conform? I mean, I have saved Data on the Server by local time, datetime on sql is timezone aware, so I display it on client side like it is localtime by converting it to now_utc. The Browser still says e.g. GMT+2 (in debug window) but displays GMT via angular filter and the conversion. How does this work? I don't get the trick. – Sebastian Aug 19 '14 at 12:29
  • This will alter the actual time though it does allow me to display it as UTC time, which is what I need, thanks! – Bruce May 04 '16 at 01:08
  • 2
    This answer demonstrates one implementation of "epoch shifting" which is dangerous in isolation, as it can fail near edge cases like DST transitions. Not recommended. – Matt Johnson-Pint Jun 20 '16 at 23:58
  • 12
    It does not work. The new `Date` objects still has it's offset set according to the user's timezone. – Feuermurmel Jun 28 '16 at 10:29
  • 9
    This creates a new date IN THE CURRENT TIME ZONE with date and time values from UTC. So it no longer represents the same moment in time. – stone Jul 12 '16 at 23:46
  • Edited response for correctness as it was incorrect. – nurieta Mar 27 '18 at 22:00
  • 3
    `now_utc` has the same value as `date.getTime()` (except for the millisecond difference caused by ignoring date.getUTCMilliseconds()). How is this a correct answer? – Lahiru Chandima Mar 01 '20 at 16:23
  • 3
    This answer has been so hacked over the years as to be useless. It makes 3 copies of the same date and is essentially identical to: `var date = new Date(); var now_utc = new Date(date); return new Date(date)`. – RobG Apr 07 '20 at 22:06
  • This doesn't work for dates < 100AD and may not work if < 1000. Why is that important? It caused a bug in a React controlled component when editing a year while the year was temporarily < 100 as the user typed. Here's a workaround by using setFullYear: function convertDateToUTC(date) { const utcDate = new Date( date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), ); utcDate.setFullYear(date.getUTCFullYear()); return utcDate; } – user3141592 Mar 16 '21 at 00:08
  • Why do you said "stupid"? ```convertDateToUTC( new Date( myTimeStamp ) )``` still giving me my local time. – Magno C Mar 31 '22 at 00:12
576

The toISOString() method returns a string in simplified extended ISO format (ISO 8601), which is always 24 or 27 characters long (YYYY-MM-DDTHH:mm:ss.sssZ or ±YYYYYY-MM-DDTHH:mm:ss.sssZ, respectively). The timezone is always zero UTC offset, as denoted by the suffix "Z".

Source: MDN web docs

The format you need is created with the .toISOString() method. For older browsers (ie8 and under), which don't natively support this method, the shim can be found here:

This will give you the ability to do what you need:

var isoDateString = new Date().toISOString();
console.log(isoDateString);

For Timezone work, moment.js and moment.js timezone are really invaluable tools...especially for navigating timezones between client and server javascript.

Flimm
  • 136,138
  • 45
  • 251
  • 267
Will Stern
  • 17,181
  • 5
  • 36
  • 22
  • 1
    I've now marked this as the correct answer, although there are minor string formatting differences to my original question. The shim code is valuable for browsers that don't yet implement the ECMAscript 5 .toISOString() method. – dthrasher Jan 30 '13 at 19:16
  • 170
    actually this converts the date object to a string, won't be able to do further date operations on it – orszaczky Sep 05 '14 at 03:01
  • 6
    @TheRebel, the use-case given is that he needs to send the server a formatted string. – Will Stern Sep 05 '14 at 15:51
  • 51
    @Will, you're totally right, but - just as most of the viewers here I assume - I arrived here based on the title, searching for general JS date to UTC conversion, so I thought it's useful to mention it here :) – orszaczky Sep 06 '14 at 05:22
  • but on the server you will never know what date user intended to submit. User doesn't care about the UTC, he wants to submit 1 Jan in Tokyo, but the server sees 31st of Dec – Toolkit Feb 23 '15 at 05:59
  • 12
    Be wary when using this method! It does not create a UTC date - it formats the existing date data as-is into a UTC format and gives it a "Z" timezone. This is wrong 99% of the time! You must convert the date to GMT timezone before using this method! – user1944491 Aug 23 '18 at 13:00
  • 14
    @user1944491 I don't think this is correct. According to the MDN docs, `toISOString` does properly convert to UTC `[toISOString] returns a string in simplified extended ISO format ... The timezone is always zero UTC offset` Also in the example they show the offset is accounted for when toISOString is called – FFF Feb 27 '19 at 20:35
  • 5
    MomentJS is not invaluable its a horrible massive blob of code. Easy to use, not the most complete, but a bloated pig that does not even work with several modern frameworks without a hack. But it's so bloated there's no point in using it. – Rick O'Shea Mar 05 '19 at 14:07
  • @Toolkit When you get the UTC date from the server and display it back to the user, it will be converted to their timezone and display correctly. One should always store dates in UTC and only convert to local timezones when displaying to a user. – tim-phillips May 09 '19 at 01:10
  • 1
    var d = new Date(dateParam).toISOString(); var year = d.getFullYear(); not able to check getFullYear function if i use toISOString() function. – Kamlesh Oct 14 '19 at 14:28
  • be aware that although `new Date("2009-1-1")` will be interpreted as a local date, `new Date("2009-01-01")` will be interpreted as UTC – spatialaustin Apr 16 '22 at 05:45
  • Heads up: Even the Moment team now asks you to reconsider using Moment. https://momentjs.com/docs/#/-project-status/ Check out date-fns as an alternative. You only import the methods you need for a smaller payload. – Andy May 02 '22 at 20:27
  • 1
    @orszaczky—that comment is nonsensical. The *Date* instance isn't "converted" to anything, *toISOString* returns a UTC timestamp representing exactly the same instant in time **that can be sent to the server**, which is the OP's requirement. The original *Date* object remains untouched. – RobG Jun 11 '22 at 12:38
257

Here's my method:

var now = new Date();
var utc = new Date(now.getTime() + now.getTimezoneOffset() * 60000);

The resulting utc object isn't really a UTC date, but a local date shifted to match the UTC time (see comments). However, in practice it does the job.


Update: This answer is a quick-and-dirty way to get the UTC date when calling utc.toString(), utc.toLocaleString(), etc. Though, there are better solutions, in particular nowadays with modern browsers, and I should work on an improved answer. Basically, now.toISOString() (IE 9+) is what you want to use.

Gras Double
  • 15,901
  • 8
  • 56
  • 54
  • I was looking at that problem when I realized that `Date.now()` gives local time and not UTC time, and this solution seems the simplest to me. At least in my case where I want UNIX time and not a nicely formatted string. (the only difference was that I'd multiply by `60 * 1000` just to be extra clear :)) – Timothée Boucher Sep 13 '12 at 16:07
  • 23
    Adding the 60000 * Date.getTimezoneOffset() is incorrect! First, you must think of all Dates/Times as already being UTC with a timezone modifier for display purposes. Browsers may differ, however, Date.getTime() returns the number of milliseconds since 1970-01-01. If you create a new Date using this number, ex: new Date(Date.getTime()); it *will be UTC*, however when you display it (ex: through the chrome dev tools console) it will appear to be your local timezone. – Aaron Hoffman Jan 30 '13 at 17:37
  • 17
    In my browser, this creates a DateTime that is not UTC. However when displayed within my browser, this displays a DateTime in my local timezone that would be correct UTC time if timezone info is ignored. – Aaron Hoffman Jan 30 '13 at 17:44
  • Gotcha, interesting point. Let's compare `now.toString()` with `utc.toString()`: there's no timezone change, but time alteration, which is quite a different thing. However, a cleaner solution would be way more complex (I guess so), and this code does the job in vast majority of cases, as long as one doesn't deal further with timezones. It made me remind about [duck punching](http://paulirish.com/2010/duck-punching-with-jquery/): different thing but made to behave the same. Also note DrunkCoder's code has the same issue. – Gras Double Jan 31 '13 at 23:28
  • Thank you, it helped to solve issues with ASP.MVC Json serialized DateTime in Kendo grids. Telerik recommends a similar solution here: http://www.kendoui.com/code-library/mvc/grid/using-utc-time-on-both-client-and-server-sides.aspx but they have a flaw - they use current time offset and that breaks because of DST. Just remember to call getTimezoneOffset() on the date you are converting from, not on the current Date(), and you'll be fine. – JustAMartin May 15 '13 at 09:35
  • I've adapted this to send the individual components of the date/time including the Timezone Offset to the server, and then construct a (C#/.Net) DateTimeOffset from the data. That can then output a UtcDateTime. +1. – Stephen Kennedy May 28 '13 at 11:51
  • getTime() returns Unix timestamp in miliseconds. It is a clock related to the GMT time. You don't need to correct the time with current time zone. The timestamp has universal meaning in terms of time on the Earth. Since the server will work with UTC time it's more comfortable to leave Javascript Data object itself to do the time zone conversion. I.e. `var usertime = new Date(serverUnixEpochTime*1000)` -> goes to javascript code. `serverUnixEpochTime = usertime->getTime()/1000` -> goes to server. – 0xC0DEGURU Mar 10 '15 at 13:59
  • 5
    This answer demonstrates another common implementation of "epoch shifting" which is dangerous in isolation, as it can fail near edge cases like DST transitions. Not recommended. – Matt Johnson-Pint Jun 20 '16 at 23:58
  • Matt Johnson is correct. Here is a concrete example where it fails due to a daylight savings case. In NSW, Australia daylight savings started 2016-10-02 02:00:00 (The following would only show the problem if your locale is NSW) ```date = new Date('2016-10-02 03:00:00'); console.log( new Date(date.getTime() + date.getTimezoneOffset() * 60000) ); => Sat Oct 01 2016 15:00:00 GMT+1000 (AEST)``` which is incorrect. It should show the time as 16:00:00 (which is 3am - 11 hours). My answer or DrunkCoder's give the correct result – CMcClymont Nov 03 '16 at 23:24
39

Convert to ISO without changing date/time

var now = new Date(); // Fri Feb 20 2015 19:29:31 GMT+0530 (India Standard Time) 
var isoDate = new Date(now.getTime() - now.getTimezoneOffset() * 60000).toISOString();
//OUTPUT : 2015-02-20T19:29:31.238Z

Convert to ISO with change in date/time(date/time will be changed)

isoDate = new Date(now).toISOString();
//OUTPUT : 2015-02-20T13:59:31.238Z 

Fiddle link

RollerCosta
  • 5,020
  • 9
  • 53
  • 71
  • so this is kind of faking UTC? I shift my local date and i succeed to submit to the server the date and time that I actually see on on my PC clock. Wow. Anyway better than strinifying and parsing – Toolkit Feb 23 '15 at 06:13
  • Also you don't need .toISOString(), you can just send isoDate to the server – Toolkit Feb 23 '15 at 06:37
  • .toISOString() is simple and straight, getting date out of it will be an extra step( isoDate is not a function ). – RollerCosta Mar 12 '15 at 07:41
  • Don't you need to add the offset instead of subtracting it? Refer to http://stackoverflow.com/a/11964609/832230 – Asclepius Apr 14 '16 at 22:00
  • @A-B-B If current timezone offset is +ve then we should subtract it(in our case IST is +5:30) otherwise add. – RollerCosta Apr 18 '16 at 08:53
  • 2
    @RollerCosta please mention on your answer that subtracting/adding `now.getTimezoneOffset()` depends on whether the timezone of the user(browser) is before utc or after utc. – Iman Mahmoudinasab Feb 24 '22 at 22:58
  • @ImanMahmoudinasab It's not dependent on whether the user timezone is before or after UTC. The timezone is signed, itself, so you always subtract. – Auspex Sep 28 '22 at 09:11
  • @Auspex nope, `getTimezoneOffset()` is always positive in Javascript like in Java, just checked it out again and if you need to convert 00:00 in UTC to both Tokyo and PCT - you would need to minus for Tokyo and plus for PCT – Dzmitry Vasilevsky Mar 28 '23 at 08:15
  • @DzmitryVasilevsky Funny, I've been doing this for years, and it always has a sign – Auspex Mar 28 '23 at 14:43
  • @Auspex that's probably because your users are mostly western or eastern – Dzmitry Vasilevsky Mar 29 '23 at 16:19
  • @DzmitryVasilevsky You're not paying attention. It ALWAYS has a sign. In fact, _I_ am currently UTC+1, but I do much of my development in UTC-3 or UTC-4, so I do routinely see both signs. – Auspex Mar 30 '23 at 14:17
29

Another solution to convert to UTC and keep it as a date object: (It works by removing the ' GMT' part from the end of the formatted string, then putting it back into the Date constructor)

const now = new Date();
const now_utc = new Date(now.toUTCString().slice(0, -4));
console.log(now_utc.toString()); // ignore the timezone

I needed to do this to interface with a datetime picker library. But in general it's a bad idea to work with dates this way.

Users generally want to work with datetimes in their local time, so you either update the server side code to parse datetime strings with offsets correctly, then convert to UTC (best option) or you convert to a UTC string client-side before sending to the server (like in Will Stern's answer)

Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
CMcClymont
  • 586
  • 5
  • 6
27
Date.prototype.toUTCArray= function(){
    var D= this;
    return [D.getUTCFullYear(), D.getUTCMonth(), D.getUTCDate(), D.getUTCHours(),
    D.getUTCMinutes(), D.getUTCSeconds()];
}

Date.prototype.toISO= function(){
    var tem, A= this.toUTCArray(), i= 0;
    A[1]+= 1;
    while(i++<7){
        tem= A[i];
        if(tem<10) A[i]= '0'+tem;
    }
    return A.splice(0, 3).join('-')+'T'+A.join(':');    
}
kennebec
  • 102,654
  • 32
  • 106
  • 127
  • This works well. I just needed to replace the "-" in my source dates to "/" in order to create a JavaScript date, then I could call your toISO() function to get the correct output. – dthrasher Jun 04 '09 at 15:41
  • this works great. You can also feed the result into jQuery $.parseDate(...) to get a date object back that has been shifted to UTC. – Brian Ellis Dec 30 '10 at 22:01
24

My solution keeps the date the same no matter what timezone is set on the client-side. Maybe someone will find it useful.

My use case:

I'm creating a todo app, where you set date of your task. This date should remain constant no matter what timezone you're in.

Example. You want to call your friend at 8 am on June 25th.

You create this task 5 days before (June 20th) while you're in China.

Then, on the same day, you fly to New York for a few days.

Then on June 25th, while you're still in New York, you wake up at 7:30 am (which means you should receive task notification in 30 mins (even tho it's 1:30 pm already in China where you were when creating the task)

So the task is ignoring the timezone. It means 'I want to do it at 8 am in whatever timezone I'll be in'.

What I do is let's say 'I assume you're always in London Timezone - UTC'.

What it means is - when the user picks some date in her/his Timezone - I convert this date to the same date in UTC. ie. You pick 8 am in China, but I convert it to 8 am in UTC.

Then - next time you open the app - I read the date saved in UTC and convert it to the same date in your current timezone - eg. I convert 8 am in UTC to 8 am in the New York timezone.

This solution means that the date can mean something else depending on where you are when setting it and where you're reading it, but it remains constant in a way that it 'feels' like you're always in the same timezone.

Let's write some code:

First - we have 2 main functions for converting from/to UTC ignoring timezone:

export function convertLocalDateToUTCIgnoringTimezone(date: Date) {
  const timestamp = Date.UTC(
    date.getFullYear(),
    date.getMonth(),
    date.getDate(),
    date.getHours(),
    date.getMinutes(),
    date.getSeconds(),
    date.getMilliseconds(),
  );

  return new Date(timestamp);
}

export function convertUTCToLocalDateIgnoringTimezone(utcDate: Date) {
  return new Date(
    utcDate.getUTCFullYear(),
    utcDate.getUTCMonth(),
    utcDate.getUTCDate(),
    utcDate.getUTCHours(),
    utcDate.getUTCMinutes(),
    utcDate.getUTCSeconds(),
    utcDate.getUTCMilliseconds(),
  );
}

Then, I save/read this date like:

function saveTaskDate(localDate: Date) {
  // I convert your local calendar date so it looks like you've picked it being in UTC somewhere around London
  const utcDate = convertLocalDateToUTCIgnoringTimezone(localDate);
  api.saveTaskDate(utcDate);
}

function readTaskDate(taskUtcDate: Date) {
  // I convert this UTC date to 'look in your local timezone' as if you were now in UTC somewhere around london
  const localDateWithSameDayAsUTC = convertUTCToLocalDateIgnoringTimezone(taskUtcDate);

  // this date will have the same calendar day as the one you've picked previously
  // no matter where you were saving it and where you are now
}
Adam Pietrasiak
  • 12,773
  • 9
  • 78
  • 91
23

Browsers may differ, and you should also remember to not trust any info generated by the client, that being said, the below statement works for me (Google Chrome v24 on Mac OS X 10.8.2)

var utcDate = new Date(new Date().getTime());


edit: "How is this different than just new Date()?" see here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date

  • If no arguments are provided, the constructor creates a JavaScript Date object for the current date and time according to system settings.
  • Note: Where Date is called as a constructor with more than one argument, the specifed arguments represent local time. If UTC is desired, use new Date(Date.UTC(...)) with the same arguments. (note: Date.UTC() returns the number of millisecond since 1970-01-01 00:00:00 UTC)

Adding the 60000 * Date.getTimezoneOffset() as previous answers have stated is incorrect. First, you must think of all Dates/Times as already being UTC with a timezone modifier for display purposes.

Again, browsers may differ, however, Date.getTime() returns the number of milliseconds since 1970-01-01 UTC/GMT. If you create a new Date using this number as I do above, it will be UTC/GMT. However, if you display it by calling .toString() it will appear to be in your local timezone because .toString() uses your local timezone, not the timezone of the Date object it is called on.

I have also found that if you call .getTimezoneOffset() on a date, it will return your local timezone, not the timezone of the date object you called it on (I can't verify this to be standard however).

In my browser, adding 60000 * Date.getTimezoneOffset() creates a DateTime that is not UTC. However when displayed within my browser (ex: .toString() ), it displays a DateTime in my local timezone that would be correct UTC time if timezone info is ignored.

Aaron Hoffman
  • 6,604
  • 8
  • 56
  • 61
  • 13
    I just ran this code on Fx and Chrome, it doesn't seem to work: the result is exactly the same as from `new Date()`, neither timestamp nor timezone is changed – Gras Double Apr 16 '13 at 23:40
  • 3
    That's because timestamps are timezone-less. `new Date().getTime()` will always return a timestamp that is agnostic to timezone. There's no timestamp associated with it until you try to format it into something other than number of milliseconds since the Unix epoch. – frontendbeauty Jul 08 '13 at 18:48
  • 9
    As far as I can tell `new Date(new Date().getTime())` returns exactly the same value as `new Date()`. Can you explain in what sense your answer provides a distinct value from `new Date()`? – Kirk Woll Feb 14 '14 at 01:26
  • I am posting this value to my server `new Date("5/19/2014").getTime()`. The Date constructor created a date with a +7 offset. On the server (C#), I add the posted value as milliseconds to unix epoch `new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds(1401087600000)`. The result is `5/19/2014 7:00:00 AM`. So it seems getTime() gives the number of milliseconds including my UTC offset. – xr280xr May 14 '14 at 02:21
  • 1
    There are a lot of comments complaining that`new Date(new Date().getTime())` doesn't work. I can confirm that `new Date(Date.UTC(2019, 8, 27, 0, 0, 0))` does indeed produce UTC time. If you fail to use `Date.UTC(...)` you will get dates in UTC offset in your timezone. – Alex Barker Aug 27 '19 at 18:07
  • Thanks, @AlexBarker, this answer gets downvoted from time to time without comment. I have not been able to determine why :shrug: – Aaron Hoffman Aug 29 '19 at 21:44
18
var myDate = new Date(); // Set this to your date in whichever timezone.
var utcDate = myDate.toUTCString();
James Skidmore
  • 49,340
  • 32
  • 108
  • 136
10
date = '2012-07-28'; stringdate = new Date(date).toISOString();

ought to work in most newer browsers. it returns 2012-07-28T00:00:00.000Z on Firefox 6.0

jcomeau_ictx
  • 37,688
  • 6
  • 92
  • 107
9

Are you trying to convert the date into a string like that?

I'd make a function to do that, and, though it's slightly controversial, add it to the Date prototype. If you're not comfortable with doing that, then you can put it as a standalone function, passing the date as a parameter.

Date.prototype.getISOString = function() {
    var zone = '', temp = -this.getTimezoneOffset() / 60 * 100;
    if (temp >= 0) zone += "+";
    zone += (Math.abs(temp) < 100 ? "00" : (Math.abs(temp) < 1000 ? "0" : "")) + temp;

    // "2009-6-4T14:7:32+10:00"
    return this.getFullYear()   // 2009
         + "-"
         + (this.getMonth() + 1) // 6
         + "-"
         + this.getDate()       // 4
         + "T"
         + this.getHours()      // 14
         + ":"
         + this.getMinutes()    // 7
         + ":"
         + this.getSeconds()    // 32
         + zone.substr(0, 3)    // +10
         + ":"
         + String(temp).substr(-2) // 00
    ;
};

If you needed it in UTC time, just replace all the get* functions with getUTC*, eg: getUTCFullYear, getUTCMonth, getUTCHours... and then just add "+00:00" at the end instead of the user's timezone offset.

nickf
  • 537,072
  • 198
  • 649
  • 721
  • 1
    This is the first example I've seen that attempts to handle the timezone offset, so +1 for that. However, I found a couple of things with it - temp.substr(-2) causes an error because it's a number, not a string, so you need to do something like "temp = '' + temp;" first, to turn it into a string. Also, I prefer my ISO dates zero-padded - I think this makes them more standard. – Mick Sear Jun 10 '11 at 09:16
  • @Mick - I've updated to fix that bug. I've used `String(temp)` since the other way (`"" + temp`) is reported as a JSLint error these days. – nickf Jun 10 '11 at 09:42
  • This is now standardized as the [`toISOString` method](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toISOString) – Bergi Jan 25 '13 at 13:46
8

My recommendation when working with dates is to parse the date into individual fields from user input. You can use it as a full string, but you are playing with fire.

JavaScript can treat two equal dates in different formats differently.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse

Never do anything like:

new Date('date as text');

Once you have your date parsed into its individual fields from user input, create a date object. Once the date object is created convert it to UTC by adding the time zone offset. I can't stress how important it is to use the offset from the date object due to DST (that's another discussion however to show why).

var year = getFullYear('date as text');
var month = getMonth('date as text');
var dayOfMonth = getDate('date as text');

var date = new Date(year, month, dayOfMonth);

var offsetInMs = ((date.getTimezoneOffset() * 60)  // Seconds
                 * 1000);                          //  Milliseconds

var utcDate = new Date(date.getTime + offsetInMs);

Now you can pass the date to the server in UTC time. Again I would highly recommend against using any date strings. Either pass it to the server broken down to the lowest granularity you need e.g. year, month, day, minute or as a value like milliseconds from the unix epoch.

Timothy Gonzalez
  • 1,802
  • 21
  • 18
  • FYI getYear is being removed from web standards https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getYear – Ghan Mar 24 '16 at 15:21
7

If you are dealing with dates a lot, it's worth using moment.js (http://momentjs.com). The method to convert to UTC would be:

moment(yourTime).utc()

You can use format to change your date to any format you want:

moment(yourTime).utc().format("YYYY-MM-DD")

There is offset options in moment as well but there is an additional complementary library for dealing with timezone (http://momentjs.com/timezone/). The time conversion would be as simple as this:

moment.tz(yourUTCTime, "America/New_York")
Adam Boostani
  • 5,999
  • 9
  • 38
  • 44
  • what's the difference between `moment(yourTime).utc()` and `moment.utc(yourTime)` ? I usually use the latter. – ps0604 Aug 21 '18 at 06:30
  • 1
    It's probably worth noting from the docs...'We now generally consider Moment to be a legacy project in maintenance mode. It is not dead, but it is indeed done.' See [here](https://momentjs.com/docs/#/-project-status/recommendations/) for alternative recommendations. – shmuels May 17 '22 at 21:29
6

I've found the jQuery Globalization Plugin date parsing to work best. Other methods had cross-browser issues and stuff like date.js had not been updated in quite a while.

You also don't need a datePicker on the page. You can just call something similar to the example given in the docs:

$.parseDate('yy-mm-dd', '2007-01-26');
Brian Ellis
  • 1,829
  • 1
  • 19
  • 24
  • 1
    Just because something hasn't been updated, doesn't mean you shouldn't use it. Date.js has worked so perfectly for years, so it hasn't needed updating. The JS Date Object and the date formats in use haven't changed in the past few years, so why would the script that manipulates them? Date.JS is absolutely the best JS Date library out there. There's a few issues for it in github, but otherwise, it's perfect. https://github.com/datejs/Datejs – thugsb Jul 26 '12 at 17:53
5

Using moment.js UTC method;

const moment = require('moment');
const utc = moment.utc(new Date(string));
Yaki Klein
  • 3,978
  • 3
  • 37
  • 34
5

I just discovered that the 1.2.3 version of Steven Levithan's date.format.js does just what I want. It allows you to supply a format string for a JavaScript date and will convert from local time to UTC. Here's the code I'm using now:

// JavaScript dates don't like hyphens!    
var rectifiedDateText = dateText.replace(/-/g, "/");
var d = new Date(rectifiedDateText);

// Using a predefined mask from date.format.js.
var convertedDate = dateFormat(d, 'isoUtcDateTime'); 
dthrasher
  • 40,656
  • 34
  • 113
  • 139
  • 10
    This does not seem to be the best answer for your question. You should reconsider something that directly answers your question or ask your question differently. – hitautodestruct Jan 08 '12 at 15:44
  • 1
    I happen to be FIXING this exact script (and version) because it's insufficient for IE7 and Firefox. – Barbarrosa May 17 '12 at 02:41
4

This method will give you : 2017-08-04T11:15:00.000+04:30 and you can ignore zone variable to simply get 2017-08-04T11:15:00.000.

function getLocalIsoDateTime(dtString) {
    if(dtString == "")
        return "";
    var offset = new Date().getTimezoneOffset();
    var localISOTime = (new Date(new Date(dtString) - offset * 60000 /*offset in milliseconds*/)).toISOString().slice(0,-1);
    //Next two lines can be removed if zone isn't needed.
    var absO = Math.abs(offset);
    var zone = (offset < 0 ? "+" : "-") + ("00" + Math.floor(absO / 60)).slice(-2) + ":" + ("00" + (absO % 60)).slice(-2);
    return localISOTime + zone;
}
4

If you need Date Object

Passing only date string Date assumes time to be 00:00 shifted by time zone:

new Date('2019-03-11')
Sun Mar 10 2019 18:00:00 GMT-0600 (Central Standard Time)

If you add current hours and minutes you get proper date:

new Date('2019-03-11 ' + new Date().getHours() + ':' + new Date().getMinutes())
Mon Mar 11 2019 04:36:00 GMT-0600 (Central Standard Time)
keemor
  • 1,149
  • 15
  • 16
4

The getTimezoneOffset() method returns the time zone difference, in minutes, from current locale (host system settings) to UTC.

Source: MDN web docs

This means that the offset is positive if the local timezone is behind UTC, and negative if it is ahead. For example, for time zone UTC+02:00, -120 will be returned.

let d = new Date();
console.log(d);
d.setTime(d.getTime() + (d.getTimezoneOffset() * 60000));
console.log(d);

NOTE: This will shift the date object time to UTC±00:00 and not convert its timezone so the date object timezone will still the same but the value will be in UTC±00:00.

Ali Ataf
  • 391
  • 3
  • 13
4

For other people whos goal is to get it as a "Date Object" and not as a string, and you only want to display the date/time without the TZ (probably hardcoded), what you can do is:

const now = new Date();
const year = now.getUTCFullYear();
const month = now.getUTCMonth();
const day = now.getUTCDate();
const hour = now.getUTCHours();

const tomorrowUTC= new Date();
tomorrowUTC.setYear(year);
tomorrowUTC.setMonth(month);
tomorrowUTC.setDate(day + 1); // +1 because my logic is to get "tomorrow"
tomorrowUTC.Hours(hour);

// then use the tomorrowUTC for to display/format it
// tomorrowUTC is a "Date" and not a string.

You can then do stuff like:

We will delete your account at ${format(tomorrowUTC, 'EEEE do MMMM hh:mmaaa')} UTC

(format is a date-fns function, you can use other lib if you want);

This is kinda "hacky" as this is still using your local timezone, but if you just wanna display the date and not the timezone, then this works.

Sámal Rasmussen
  • 2,887
  • 35
  • 36
I am L
  • 4,288
  • 6
  • 32
  • 49
  • This answer is better than just "not showing the time zone". The definition for Unix Epoch time is the time in UTC. Using the UTC functions allows you to convert your local time, to UTC natively. – Narxx Oct 13 '21 at 16:44
3

This function works beautifully for me.

function ParseDateForSave(dateValue) {
    // create a new date object
    var newDate = new Date(parseInt(dateValue.substr(6)));

    // return the UTC version of the date
    return newDate.toISOString();
}
Will Strohl
  • 1,646
  • 2
  • 15
  • 32
3

This is what I have done in the past:

var utcDateString = new Date(new Date().toUTCString()).toISOString();
3

If your date has the timezone on it you can use date-fns-tz:

import { zonedTimeToUtc } from 'date-fns-tz';

const dateBrazil = new Date() // I'm in Brazil, you should have or get the user timezone.
const dateUtc = zonedTimeToUtc(dateBrazil, 'America/Sao_Paulo')
Lucas Andrade
  • 4,315
  • 5
  • 29
  • 50
2

Looking at your question its clear that you just want to send the date range to your backend for further post processing.

I am assuming you are conforming to the standard data guidelines which expect the data to be in a particular format. For example, I use ODATA which is a RESTfull API which expects date time objects to be in the format:-

YYYY-MM-DDT00:00:00.

That can be easily achieved via the snippet posted below(Please change the format as per your requirement).

var mydate;//assuming this is my date object which I want to expose var UTCDateStr = mydate.getUTCFullYear() + "-" + mydate.getUTCMonth() + "-" + mydate.getUTCDate() + "T00:00:00";

If on the other hand, you are in my situation wherein you have received a date from your backend, and the browser converts that to your local date. You on the other hand are interested in the UTC date then you can perform the following:-

var mydate;//assuming this is my date object which I want to expose var UTCDate = new Date(mydate);/*create a copy of your date object. Only needed if you for some reason need the original local date*/ UTCDate.setTime(UTCDate.getTime() + UTCDate.getTimezoneOffset() * 60 * 1000);

The code snippet above basically adds/subtracts the time added/subtracted by the browser based on the timezone.

For example if I am in EST(GMT-5) and my Service returns a date time object = Wed Aug 17 2016 00:00:00 GMT-0500 my browser automatically subtracts the timezone offset(5hrs) to get my local time. So if I try to fetch the time I get Wed Aug 16 2016 19:00:00 GMT-0500. This causes a lot of problems. There are a lot of libraries out there which will definitely make this easier but I wanted to share the pure JS approach.

For more info please have a look at: http://praveenlobo.com/blog/how-to-convert-javascript-local-date-to-utc-and-utc-to-local-date/ where in I got my inspiration.

Hope this helps!

Reeth
  • 62
  • 1
  • 8
2
var userdate = new Date("2009-1-1T8:00:00Z");
var timezone = userdate.getTimezoneOffset();
var serverdate = new Date(userdate.setMinutes(userdate.getMinutes()+parseInt(timezone)));

This will give you the proper UTC Date and Time.
It's because the getTimezoneOffset() will give you the timezone difference in minutes. I recommend you that not to use toISOString() because the output will be in the string Hence in future you will not able to manipulate the date

ddb
  • 2,423
  • 7
  • 28
  • 38
Sanket Patel
  • 901
  • 9
  • 21
2

Using moment package, you can easily convert a date string of UTC to a new Date object:

const moment = require('moment');
let b = new Date(moment.utc('2014-02-20 00:00:00.000000'));
let utc = b.toUTCString();
b.getTime();

This specially helps when your server do not support timezone and you want to store UTC date always in server and get it back as a new Date object. Above code worked for my requirement of similar issue that this thread is for. Sharing here so that it can help others. I do not see exactly above solution in any answer. Thanks.

Bimal Jha
  • 391
  • 2
  • 14
  • 4
    Even though this may answer the question, there is no explanation of your code. Please update your answer to provide an explanation of what you are doing. Thanks! – Miroslav Glamuzina Apr 04 '19 at 02:37
  • There is a similar answer above https://stackoverflow.com/a/51232409/52277 and more details on different question https://stackoverflow.com/a/17859318/52277 – Michael Freidgeim Jan 09 '22 at 04:19
0

I know this question is old, but was looking at this same issue, and one option would be to send date.valueOf() to the server instead. the valueOf() function of the javascript Date sends the number of milliseconds since midnight January 1, 1970 UTC.

valueOf()

weagle08
  • 1,763
  • 1
  • 18
  • 27
0

You can use the following method to convert any js date to UTC:

let date = new Date(YOUR_DATE).toISOString()

// It would give the date in format "2020-06-16T12:30:00.000Z" where Part before T is date in YYYY-MM-DD format, part after T is time in format HH:MM:SS  and Z stands for UTC - Zero hour offset
0

By far the best way I found to get the GMT time is first get your local date time. Then convert in to GMT String. Then use the string to build new time by removing the timezone.

let dtLocal = new Date()
let dt = new Date(dtLocal.toISOString().split('Z')[0])

Note: - it will create the new datetime in GMT. But it will be local date time as timezone will be attached to it.

CryptoManiac
  • 101
  • 1
  • 5
0

For Node Js timestamp conversion

process.env.TZ = "UTC"
var moment = require('moment')

module.exports = {
    mysqlTimeStamp: {
        CreateAt: moment(new Date()).format("YYYY-MM-DD HH:mm:ss"),
        UpdateAt: moment(new Date()).format("YYYY-MM-DD HH:mm:ss")
    },
    mysqlUpdateTimeStamp: {
        UpdateAt: moment(new Date()).format("YYYY-MM-DD HH:mm:ss")
    },
}
Sandip Patel - SM
  • 3,346
  • 29
  • 27
-1

So this is the way I had to do it because i still wanted a JavaScript date object to manipulate as a date and unfortunantly alot of these answers require you to go to a string.

//First i had a string called stringDateVar that i needed to convert to Date
var newDate = new Date(stringDateVar)

//output: 2019-01-07T04:00:00.000Z
//I needed it 2019-01-07T00:00:00.000Z because i had other logic that was dependent on that 

var correctDate = new Date(newDate.setUTCHours(0))

//This will output 2019-01-07T00:00:00.000Z on everything which allows scalability 
-1

Extension function:

if (!Date.prototype.toUTC){
    Date.prototype.toUTC = function(){
        var utcOffset = new Date().getTimezoneOffset();
        var utcNow    = new Date().addMinutes(utcOffset);
        return utcNow;
    };
}

Usage:

new Date().toUTC();
Jay
  • 740
  • 4
  • 8
  • 19
-2

As per what I observe,

var timeUtc = new Date();

timeUtc will always have UTC time but if you debug or console the browser will always show time as per the current timezone.

If you send timeUtc as a parameter to any post request then in the network tab of chrome you can check the post data and you will see timeUtc will have UTC time.

Saurabh Joshi
  • 71
  • 1
  • 8
-5
const event = new Date();

console.log(event.toUTCString());
zhulien
  • 5,145
  • 3
  • 22
  • 36
Sumit Khanduri
  • 3,619
  • 7
  • 30
  • 40
-8

Even simpler

myvar.setTime(myvar.getTime() + myvar.getTimezoneOffset() * 60000);