498

I have date time in a particular timezone as a string and I want to convert this to the local time. But, I don't know how to set the timezone in the Date object.

For example, I have Feb 28 2013 7:00 PM ET, then I can

var mydate = new Date();
mydate.setFullYear(2013);
mydate.setMonth(02);
mydate.setDate(28);
mydate.setHours(7);
mydate.setMinutes(00);  

As far as I know, I can either set the UTC time or local time. But, how do I set time in another timezone?

I tried to use the add/subtract the offset from UTC but I don't know how to counter daylight savings. Am not sure if I am heading the right direction.

How can I go about converting time from a different timezone to local time in javascript?

Matt Johnson-Pint
  • 214,338
  • 71
  • 421
  • 539
pavanred
  • 11,147
  • 14
  • 51
  • 59
  • 3
    [This answer may help you](http://stackoverflow.com/a/439871/1046057) – DarkAjax Feb 28 '13 at 17:26
  • 5
    Date objects don't have a timezone, they are UTC. – RobG Nov 14 '19 at 20:42
  • 2
    worth reading this article https://medium.com/@toastui/handling-time-zone-in-javascript-547e67aa842d, the conclusion is you can't in JavaScript but you can use libraries like Moment Timezone to do it – Neekey Aug 09 '20 at 09:56
  • 4
    Date objects most certainly DO have timezones. That's why they have two different sets of getters and setters. One for UTC, one for local. – John Lord Sep 30 '20 at 19:52
  • 7
    @JohnLord No, the local getters simply convert the stored UTC time _into_ the _host_ timezone. For example, do `d = new Date()` then `d.getHours()` in the console, change your computer's time zone by an hour, and try `d.getHours()` again. There is no local time zone information stored in `d`. – Lynn Dec 08 '20 at 02:15
  • I also wrote an article around this issue at https://medium.com/@EyeDin/time-and-time-zone-headaches-in-javascript-ae4d873a665d . Might worth reading. :) – Aidin Nov 14 '21 at 09:44

17 Answers17

661

Background

JavaScript's Date object tracks time in UTC internally, but typically accepts input and produces output in the local time of the computer it's running on. It has very few facilities for working with time in other time zones.

The internal representation of a Date object is a single number, representing the number of milliseconds that have elapsed since 1970-01-01 00:00:00 UTC, without regard to leap seconds.

There is no time zone or string format stored in the Date object itself.

When various functions of the Date object are used, the computer's local time zone is applied to the internal representation. If the function produces a string, then the computer's locale information may be taken into consideration to determine how to produce that string. The details vary per function, and some are implementation-specific.

The only operations the Date object can do with non-local time zones are:

  • It can parse a string containing a numeric UTC offset from any time zone. It uses this to adjust the value being parsed, and stores the UTC equivalent. The original local time and offset are not retained in the resulting Date object. For example:

      var d = new Date("2020-04-13T00:00:00.000+08:00");
      d.toISOString()  //=> "2020-04-12T16:00:00.000Z"
      d.valueOf()      //=> 1586707200000  (this is what is actually stored in the object)
    
  • In environments that have implemented the ECMASCript Internationalization API (aka "Intl"), a Date object can produce a locale-specific string adjusted to a given time zone identifier. This is accomplished via the timeZone option to toLocaleString and its variations. Most implementations will support IANA time zone identifiers, such as 'America/New_York'. For example:

      var d = new Date("2020-04-13T00:00:00.000+08:00");
      d.toLocaleString('en-US', { timeZone: 'America/New_York' })
      //=> "4/12/2020, 12:00:00 PM"
      // (midnight in China on Apring 13th is noon in New York on April 12th)
    

    Most modern environments support the full set of IANA time zone identifiers (see the compatibility table here). However, keep in mind that the only identifier required to be supported by Intl is 'UTC', thus you should check carefully if you need to support older browsers or atypical environments (for example, lightweight IoT devices).

Libraries

There are several libraries that can be used to work with time zones. Though they still cannot make the Date object behave any differently, they typically implement the standard IANA timezone database and provide functions for using it in JavaScript. Modern libraries use the time zone data supplied by the Intl API, but older libraries typically have overhead, especially if you are running in a web browser, as the database can get a bit large. Some of these libraries also allow you to selectively reduce the data set, either by which time zones are supported and/or by the range of dates you can work with.

Here are the libraries to consider:

Intl-based Libraries

New development should choose from one of these implementations, which rely on the Intl API for their time zone data:

Non-Intl Libraries

These libraries are maintained, but carry the burden of packaging their own time zone data, which can be quite large.

* While Moment and Moment-Timezone were previously recommended, the Moment team now prefers users chose Luxon for new development.

Discontinued Libraries

These libraries have been officially discontinued and should no longer be used.

Future Proposals

The TC39 Temporal Proposal aims to provide a new set of standard objects for working with dates and times in the JavaScript language itself. This will include support for a time zone aware object.

treecoder
  • 39,811
  • 21
  • 62
  • 89
Matt Johnson-Pint
  • 214,338
  • 71
  • 421
  • 539
  • 1
    When you do this in the Firebug console: `var date_time = new Date()`, the value of `date_time` is (for me in AEST) `Date {Sun Aug 21 2016 22:18:47 GMT+1000 (AEST)}` and so therefore it seems it *has* stored a timezone. How can I ensure `date_time` is purely the UTC time, without any timezone included? – user1063287 Aug 21 '16 at 12:22
  • Hmm, according to this answer (http://stackoverflow.com/a/8047885/1063287), it is this: `new Date().getTime();` – user1063287 Aug 21 '16 at 12:31
  • 3
    @user1063287—the *toString* method uses the host timezone offset to produce a date and time in the "local" time zone. The date object itself has a time value that is an offset from 1970-01-01T00:00:00Z, so effectively UTC. To see the UTC date and time, use [*toISOString*](http://ecma-international.org/ecma-262/7.0/index.html#sec-date.prototype.toisostring). – RobG Aug 23 '16 at 22:47
  • To clarify; the javascript Date *does* record a timezone in addition to the point in time represented by milliseconds since midnight 1970-01-01 UTC. For more info take a look at the rhino source code @ https://github.com/mozilla/rhino/blob/master/src/org/mozilla/javascript/NativeDate.java – redcalx Sep 20 '16 at 14:11
  • 1
    @redcalx - that is a Rhino specific implementation, but even then, if you scroll to the very bottom you'll see that `private double date` is the only instance field. Everything else is static, and primarily there for caching environment provided values. It's not something tracked per-instance, or something you can modify easily. – Matt Johnson-Pint Sep 20 '16 at 19:01
  • Hmm. Ok here'a a thing. If we create two dates, one with new Date(), the other with new Date(Date.UTC(2016,0,1,0,0,0)) and then do toString() on each, then one gives the date/time based on the local timezone, the other the date/time using the UTC timezone. So something somewhere is storing a timezone against each date instance. (test performed in Chrome). – redcalx Sep 20 '16 at 22:36
  • 1
    The `Date.UTC` function is computing the timestamp based on UTC inputs is all. The output of `.toString()` will be the local time equivalent, and will show the local time zone offset, name, or abbreviation. – Matt Johnson-Pint Sep 20 '16 at 22:53
  • That makes sense; my confusion was caused by the two dates I created having different timezone specifiers when using toString(), that was because I'm in a locale with daylight savings time, and toString() reports a local time, i.e. GMT+1 for dates in the summer, and GMT for dates in the winter. – redcalx Sep 27 '16 at 07:21
  • @redcalx— *toString* is implementation dependent and may or may not show the time zone in any particular format. Most browsers only return names or abbreviations for common time zones and the UTC offset for others. – RobG Dec 06 '16 at 04:35
  • This needs to be updated, as the format of *toString* is now set in the spec. ;-) – RobG Sep 08 '19 at 06:07
  • [Here](https://stackoverflow.com/a/68411332/1974681) you have a solution using plain [Intl](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat) Internationalization API – adrisons Jul 27 '21 at 10:07
  • It is worth to mention another Intl based library - [dayjs](https://github.com/iamkun/dayjs), which has the [smallest footprint](https://bundlephobia.com/result?p=dayjs@1.10.7). – Bruce Sun Oct 01 '21 at 07:28
180

As Matt Johnson said

If you can limit your usage to modern web browsers, you can now do the following without any special libraries:

new Date().toLocaleString("en-US", {timeZone: "America/New_York"})

This isn't a comprehensive solution, but it works for many scenarios that require only output conversion (from UTC or local time to a specific time zone, but not the other direction).

So although the browser can not read IANA timezones when creating a date, or has any methods to change the timezones on an existing Date object, there seems to be a hack around it:

function changeTimezone(date, ianatz) {

  // suppose the date is 12:00 UTC
  var invdate = new Date(date.toLocaleString('en-US', {
    timeZone: ianatz
  }));

  // then invdate will be 07:00 in Toronto
  // and the diff is 5 hours
  var diff = date.getTime() - invdate.getTime();

  // so 12:00 in Toronto is 17:00 UTC
  return new Date(date.getTime() - diff); // needs to substract

}

// E.g.
var here = new Date();
var there = changeTimezone(here, "America/Toronto");

console.log(`Here: ${here.toString()}\nToronto: ${there.toString()}`);
No Sssweat
  • 269
  • 1
  • 6
  • 22
commonpike
  • 9,516
  • 4
  • 61
  • 57
  • 7
    I'm wondering why this answer isn't getting more love. For my purposes it is absolutely the best solution. In my app, all dates are UTC, but they need to be input or output in explicit IANA timezones in the UI. For this purpose I use this solution and it works perfectly. Simple, effective, standard. – logidelic Feb 11 '19 at 13:55
  • 2
    @logidelic it is a pretty new post. to be honest, i amazed myself when it struck me you could use ``toLocaleString`` to achieve the reverse effect, and yes, this should be common knowledge ! go write an article about it and mention me :-) – commonpike Feb 11 '19 at 14:36
  • The only bad thing about this is the browser support of toLocaleString() :( – MikeyBeLike Mar 26 '19 at 15:04
  • 2
    For a node environment that is not in GMT already, the above code needs to change from var invdate = new Date(date.toLocaleString('en-US', { timeZone: ianatz })); into var invdate = new Date(${date.toLocaleString('en-US', { timeZone: ianatz })} GMT`); – Mike P. May 29 '19 at 20:28
  • 6
    Browsers are not required to parse the output of *toLocaleString*, so it's based on a faulty premise. – RobG Sep 08 '19 at 06:41
  • @RobG Yes, that is true, and strange. All browsers I encountered sofar can parse the output of their own version of toLocaleString. – commonpike Sep 23 '19 at 11:09
  • Not that strange given the history of *toLocaleString* and that the format is influenced by system regional and language settings that may not be the same when generating the string as when parsing it (e.g. en-GB and en-US). And that's without considering the variations caused by different options. There was a time when IE did not correctly parse the output of its own *Date.prototype.toString*. – RobG Sep 23 '19 at 13:14
  • 15
    "...why this answer isn't getting more love?" - because the `Date` object it returns is a lie. Even the example shown, the string output includes the local machine's time zone. On my computer, *both* results say "GMT-0700 (Pacific Daylight Time)", where that is only correct for the first one (Toronto is actually in Eastern Time.) Beyond just the string output, the timestamp held within the `Date` object has been shifted to a different point in time. This *can* be a useful technique, but comes with a lot of caveats - primarily that `Date` object functions will not have normal output. – Matt Johnson-Pint Apr 13 '20 at 20:48
  • The String output of `toLocaleString` is correct, but then parsing that into the Date Object will return faulty value since that String would be treated as if it were in the local timezone. – SJ00 May 14 '20 at 05:22
  • 1
    `I'm wondering why this answer isn't getting more love` @logidelic because it gives the wrong time, should be `date.getTime() - diff`. Made an edit to fix it, hopefully it gets approved. – No Sssweat Oct 31 '20 at 09:13
  • @NoSssweat I cant comment on your fix, but tempted to reject it; you also swapped `here` and `there` in the example and yes, then obviously you need to subtract the diff instead of adding it. My example says, if its 17:00 in Toronto now, what time is it here. Your example says, if it's 17:00 here now, what time is it in Toronto. – commonpike Oct 31 '20 at 10:13
  • 1
    @commonpike The original answer says Toronto (EST) is 3 hours behind my time, Vancouver (PST). Which is wrong, Toronto is 3 hours ahead of me. See [screenshot](https://i.imgur.com/EwRqWfb.png), this is what I see with your original answer. The `here` and `there` is just for console log and it was wrong. You assigned `here` to toronto and when logging used `there`. – No Sssweat Oct 31 '20 at 10:32
  • 1
    @NoSssweat you were right and fix approved ;-) Strange, `here` and `there` were apparently swapped by @RobG for some reason. – commonpike Oct 31 '20 at 20:21
  • This one should get more love.thanks man for saving my day. – Mmd Mahbub Apr 27 '21 at 13:44
  • 1
    @commonpike— I didn't change anything of substance, I converted the code to a runnable snippet and added the *console.log* line, maintaining here/there as they were. – RobG Jul 17 '21 at 11:03
  • This is great, but performance is really slow. I did edge browser profiling check, this function changeTimezone take 2.7ms per run. – Vincent Wen Sep 10 '21 at 10:28
  • 1
    I second @MattJohnson-Pint. You are having two `Date` objects, which are representing the same point-of-times (same number of seconds passed since 1/1/1970 00:00:00 in UTC), but they are not `==` :( That's why I believe confusing people with the incorrect fact that "`Date` has an internal `timestamp` in it", is a bad idea. I would encourage the @chickens solution (https://stackoverflow.com/a/57842203) which takes in timezone + six numbers, and produces ONE single `Date` object. TL;DR: Two strings for the same point-of-time are fine; but not two Date objects. – Aidin Nov 14 '21 at 21:01
  • 1
    There is an issue in this code with ms. Specifically, 'date' should have its ms set to zero or truncated before processing. For example, do something like one of these: `date = new Date(date.toISOString().split('.')[0] + 'Z');` or `date = new Date(date.setMilliseconds(0));` Explanation: If the 'ianatz' locale string used by 'invdate' does not include ms, then 'diff' (which uses getTime(), which does include ms) might be off by some number of ms because 'invdate' might truncate ms (setting them to 0) but 'date' still would have ms. – mikeypie May 19 '22 at 00:17
53

This should solve your problem, please feel free to offer fixes. This method will account also for daylight saving time for the given date.

dateWithTimeZone = (timeZone, year, month, day, hour, minute, second) => {
  let date = new Date(Date.UTC(year, month, day, hour, minute, second));

  let utcDate = new Date(date.toLocaleString('en-US', { timeZone: "UTC" }));
  let tzDate = new Date(date.toLocaleString('en-US', { timeZone: timeZone }));
  let offset = utcDate.getTime() - tzDate.getTime();

  date.setTime( date.getTime() + offset );

  return date;
};

How to use with timezone and local time:

dateWithTimeZone("America/Los_Angeles",2019,8,8,0,0,0)
chickens
  • 14,980
  • 4
  • 51
  • 50
  • This solution was fit for my need. I wasn't sure how exactly I can account for daylight saving. – hossein Oct 07 '19 at 09:08
  • Why not just return `tzDate` directly? – levi Jan 15 '20 at 22:57
  • 1
    Works perfectly fine in a Node js server! (Parse cloud code) – Joaquin Pereira Oct 07 '20 at 02:23
  • Very good solution, for me just returning utcDate was what I needed – Charis Moutafidis Feb 18 '21 at 12:51
  • 2
    This is a bad idea as the format of *toLocaleString* is not specified, and the built–in parser is not required to parse it, especially when options have been included. Further, it may produce unreliable results in areas that observe daylight saving where the date and time to be parsed either doesn't exist (going into DST) or exists twice (goint out of DST), where implementations must make a choice as how to resolve those issues. – RobG Aug 12 '21 at 00:42
  • Note that `month` here is 0-based, consistent with the most of internal JS functions for month, which you may not necessarily be familiar with. That's why `dateWithTimeZone("America/Los_Angeles",2019,8,8,0,0,0).toISOString()` produces `'2019-09-08T07:00:00.000Z'` – Aidin Nov 14 '21 at 06:09
  • @RobG, 1) are you talking about `basic` vs `best fit` of `formatMatcher` in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/DateTimeFormat? 2) Are you talking about that 2 hours per year (0.02%) that doesn't have any answer but possibly an Exception or `null`? – Aidin Nov 14 '21 at 10:04
  • @Aidin—the *formatMatcher* method isn't relevant to the answer as only one language is supplied. The built–in parser is not required to parse any timestamp generated by *toLocaleString*. DST issues may or may not throw an error, and two different implementations may or may not produce different results. It also assumes a conversion from timezone offset abbreviation based on common names like ET (which are not standardised and are ambiguous) to IANA representative location like "America/Los_Angeles". – RobG Nov 14 '21 at 20:31
  • @RobG-- 1) the output format of `.toLocaleString("en-US")` is ALWAYS like `'11/14/2021, 8:50:50 PM'`, which yes, might not be required to parse, but is the least you expect from your modern browser. 2) I was under the impression that the caller of this function knows that the first param should be an IANATimeZoneName (e.g. `America/Los_Angeles` and not common offset names like `PDT`. So if one does `PDT` they are on their own. TL;DR: Your concerns are valid, but are extremely minute to me. Thanks for your comments. – Aidin Nov 14 '21 at 20:56
  • Beautiful. Works like a charm. – Kode Charlie Apr 19 '22 at 22:28
48

You can specify a time zone offset on new Date(), for example:

new Date('Feb 28 2013 19:00:00 EST')

or

new Date('Feb 28 2013 19:00:00 GMT-0500')

Since Date store UTC time ( i.e. getTime returns in UTC ), javascript will them convert the time into UTC, and when you call things like toString javascript will convert the UTC time into browser's local timezone and return the string in local timezone, i.e. If I'm using UTC+8:

> new Date('Feb 28 2013 19:00:00 GMT-0500').toString()
< "Fri Mar 01 2013 08:00:00 GMT+0800 (CST)"

Also you can use normal getHours/Minute/Second method:

> new Date('Feb 28 2013 19:00:00 GMT-0500').getHours()
< 8

( This 8 means after the time is converted into my local time - UTC+8, the hours number is 8. )

maowtm
  • 1,836
  • 18
  • 22
  • 26
    Parsing any format other than ISO 8601 extended format is implementation dependant and should not be relied on. There is no standard for timezone abbreviations, e.g. "EST" might represent any one of 3 different zones. – RobG Dec 06 '16 at 04:36
  • 1
    The examples in this comment often do not work in internet explorer. As mentioned in the previous comment to this post, ISO 8601 is important. I confirmed by reading the ECMA-262 (Javascript 5th) edition language Specification. – Dakusan Sep 07 '17 at 23:24
9

I found the most supported way to do this, without worrying about a third party library, was by using getTimezoneOffset to calculate the appropriate timestamp, or update the time then use the normal methods to get the necessary date and time.

var mydate = new Date();
mydate.setFullYear(2013);
mydate.setMonth(02);
mydate.setDate(28);
mydate.setHours(7);
mydate.setMinutes(00);

// ET timezone offset in hours.
var timezone = -5;
// Timezone offset in minutes + the desired offset in minutes, converted to ms.
// This offset should be the same for ALL date calculations, so you should only need to calculate it once.
var offset = (mydate.getTimezoneOffset() + (timezone * 60)) * 60 * 1000;

// Use the timestamp and offset as necessary to calculate min/sec etc, i.e. for countdowns.
var timestamp = mydate.getTime() + offset,
    seconds = Math.floor(timestamp / 1000) % 60,
    minutes = Math.floor(timestamp / 1000 / 60) % 60,
    hours   = Math.floor(timestamp / 1000 / 60 / 60);

// Or update the timestamp to reflect the timezone offset.
mydate.setTime(mydate.getTime() + offset);
// Then Output dates and times using the normal methods.
var date = mydate.getDate(),
    hour = mydate.getHours();

EDIT

I was previously using UTC methods when performing the date transformations, which was incorrect. With adding the offset to the time, using the local get functions will return the desired results.

Shaun Cockerill
  • 742
  • 8
  • 10
4

For Ionic users, I had hell with this because .toISOString() has to be used with the html template.

This will grab the current date, but of course can be added to previous answers for a selected date.

I got it fixed using this:

date = new Date();
public currentDate: any = new Date(this.date.getTime() - this.date.getTimezoneOffset()*60000).toISOString();

The *60000 is indicating the UTC -6 which is CST so whatever TimeZone is needed, the number and difference can be changed.

Stephen Romero
  • 2,447
  • 3
  • 21
  • 42
  • @RichardVergis The question clearly states the user wants to change to local time, but doesn't state which time zone they're in. I stated my time zone as an example and the user can clearly read based off my example, they can input their time zone offset. – Stephen Romero Apr 29 '20 at 13:07
3

I ran into a similar problem with unit tests (specifically in jest when the unit tests run locally to create the snapshots and then the CI server runs in (potentially) a different timezone causing the snapshot comparison to fail). I mocked our Date and some of the supporting methods like so:

describe('...', () => {
  let originalDate;

  beforeEach(() => {
    originalDate = Date;
    Date = jest.fn(
      (d) => {
        let newD;
        if (d) {
          newD = (new originalDate(d));
        } else {
          newD = (new originalDate('2017-05-29T10:00:00z'));
        }
        newD.toLocaleString = () => {
          return (new originalDate(newD.valueOf())).toLocaleString("en-US", {timeZone: "America/New_York"});
        };
        newD.toLocaleDateString = () => {
          return (new originalDate(newD.valueOf())).toLocaleDateString("en-US", {timeZone: "America/New_York"});
        };
        newD.toLocaleTimeString = () => {
          return (new originalDate(newD.valueOf())).toLocaleTimeString("en-US", {timeZone: "America/New_York"});
        };
        return newD;
      }
    );
    Date.now = () => { return (Date()); };
  });

  afterEach(() => {
    Date = originalDate;
  });

});
JRulle
  • 7,246
  • 6
  • 38
  • 61
2

Try using ctoc from npm. https://www.npmjs.com/package/ctoc_timezone

It has got simple functionality to change timezones (most timezones around 400) and all custom formats u want it to display.

2

Building on the answers above, I am using this native one liner to convert the long timezone string to the three letter string:

var longTz = 'America/Los_Angeles';
var shortTz = new Date().
    toLocaleString("en", {timeZoneName: "short", timeZone: longTz}).
    split(' ').
    pop();

This will give PDT or PST depending on the date provided. In my particular use case, developing on Salesforce (Aura/Lightning), we are able to get the user timezone in the long format from the backend.

Shane K
  • 4,591
  • 1
  • 35
  • 36
  • 1
    Just because I like to play pedant from time to time, 'America/Los_Angeles' is not a timezone, it's a "representative location" for a particular offset and daylight saving rules and the history of those changes (per the [*IANA time zone database*](https://www.iana.org/time-zones)). ;-) – RobG Sep 23 '19 at 13:20
  • Haha, you have to post that comment on multiple answers here :P – Shane K Sep 23 '19 at 14:15
  • Yep. :-) BTW, not all timezone abbreviations are 3 letters, there are many with 4 such as ChST, AEST, AEDT, etc. and `timeZoneName: "short"` doesn't guarantee an abbreviation, sometimes it produces an offset like "GMT+10" depending on various factors. I think it's more reliable to use *toString* and get the part at the end between brackets, but still not 100%. :-( – RobG Aug 12 '21 at 00:49
2

I had the same problem but we can use the time zone we want
we use .toLocaleDateString()

eg:

var day=new Date();
const options= {day:'numeric', month:'long', year:"numeric", timeZone:"Asia/Kolkata"};
const today=day.toLocaleDateString("en-IN", options);
console.log(today);
myeongkil kim
  • 2,268
  • 4
  • 14
  • 20
  • 2
    The OP wants to parse a timestamp as if it was in a particular timezone, not generate a timestamp for a particular timezone, i.e. the opposite of what this answer does. They want to do something like "What is the time here when it was 10:30 am in Kolkata". – RobG Aug 12 '21 at 00:45
2

I ran into this issue running a GCP Cloud Function. Of course it works on a local machine, but running in the cloud makes the OS default (local) for new Date() irrelevant. In my case, an api call from the cloud required Eastern Standard Time, in ISO format (without the "Z") with offset as "-0500" or "-0400" depending on DST, for example:

2021-12-01T00:00:00.000-0500

Again, this is not a browser formatting issue, so I am forced into this format for the api call to work correctly.

Using @chickens code as a start, this is what worked:

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

var dt = new Date(now_utc);

let utcDate = new Date(dt.toLocaleString('en-US', { timeZone: "UTC" }));
let tzDate = new Date(dt.toLocaleString('en-US', { timeZone: "America/New_York" }));
let offset1 = utcDate.getTime() - tzDate.getTime();
let offset2 = offset1/60000;
let o1 = Math.abs(offset2);
console.log(offset2)
var offsetValue1 =  (offset2 < 0 ? "+" : "-") + ("00" + Math.floor(o1 / 60)).slice(-2) + ("00" + (o1 % 60)).slice(-2);
console.log(offsetValue1)
dt.setTime(dt.getTime() - offset1);

console.log(dt.toISOString());
console.log(dt.toISOString().slice(0,-1)+offsetValue1);
smoore4
  • 3,838
  • 3
  • 31
  • 49
1

Try: date-from-timezone, it resolves expected date with help of natively available Intl.DateTimeFormat.

I used that method in one of my projects for few years already, but it's now I decided to publish it as small OS project :)

Mariusz Nowak
  • 30,462
  • 4
  • 34
  • 37
1

Thanks to @commonpike answer, I wrote a function which takes an ISO String date such as 2020-10-10T08:00:00.000 as input and send an object which contains 2 main properties.

The first one is fromUtc is a Date corresponding to the timeZone entered as parameter.

The second one is toUtc which lets you to format a Date stemming from fromUtc.

const timeZoneTransformer = (stringDate, timeZone = "Europe/Paris") => {
  const now = new Date();
  const serverDate = new Date(stringDate);
  const utcDate = new Date(
    Date.UTC(
      serverDate.getFullYear(),
      serverDate.getMonth(),
      serverDate.getDate(),
      serverDate.getHours(),
      serverDate.getMinutes(),
      serverDate.getSeconds()
    )
  );
  const invdate = new Date(
    serverDate.toLocaleString("en-US", {
      timeZone,
    })
  );
  const diff = now.getTime() - invdate.getTime();
  const adjustedDate = new Date(now.getTime() - diff);
  return {
    toUtc: utcDate,
    fromUtc: adjustedDate,
  };
};
const fromUtc = timeZoneTransformer("2020-10-10T08:00:00.000").fromUtc;
console.log(fromUtc);
const toUtc = timeZoneTransformer(fromUtc).toUtc;
console.log(toUtc);
Maxime
  • 453
  • 7
  • 16
0

I know its 3 years too late, but maybe it can help someone else because I haven't found anything like that except for the moment-timezone library, which is not exactly the same as what he's asking for here.

I've done something similar for german timezone, this is a little complex because of daylight saving time and leap years where you have 366 days.

it might need a little work with the "isDaylightSavingTimeInGermany" function while different timezones change on different times the daylight saving time.

anyway, check out this page: https://github.com/zerkotin/german-timezone-converter/wiki

the main methods are: convertLocalDateToGermanTimezone convertGermanDateToLocalTimezone

I've put an effort into documenting it, so it won't be so confusing.

Pratik Gadoya
  • 1,394
  • 1
  • 15
  • 27
zerkotin
  • 43
  • 1
0

Try something like this,

public static getTimezoneOffset(timeZone: string, date = new Date()): number {
    const localDate = date.toLocaleString('fr', { timeZone, timeZoneName: 'long' });
    const tz = localDate.split(' ');
    const TZ = localDate.replace(tz[0], '').replace(tz[1], '').replace(' ', '');
    const dateString = date.toString();
    const offset = (Date.parse(`${dateString} UTC`) - Date.parse(`${dateString}${TZ}`)) / (3600 * 1000);
    return offset;
}
-3
//For Mumbai time difference is 5.5 hrs so
city_time_diff=5.5; //change according to your city

let time_now = Date.now();
time_now = time_now + (3600000 * city_time_diff); //Add our city time (in msec);
let new_date = new Date(time_now);
console.log("My city time is: ", new_date);
Korayem
  • 11,267
  • 5
  • 66
  • 54
-4

Was facing the same issue, used this one

Console.log(Date.parse("Jun 13, 2018 10:50:39 GMT+1"));

It will return milliseconds to which u can check have +100 timzone intialize British time Hope it helps!!

  • 4
    (This post does not seem to provide a [quality answer](https://stackoverflow.com/help/how-to-answer) to the question. Please either edit your answer, or just post it as a comment to the question). – sɐunıɔןɐqɐp Jun 14 '18 at 06:28