Convert date to another timezone in JavaScript
Asked Answered
S

37

523

I am looking for a function to convert date in one timezone to another.

It need two parameters,

  • date (in format "2012/04/10 10:10:30 +0000")
  • timezone string ("Asia/Jakarta")

The timezone string is described in http://en.wikipedia.org/wiki/Zone.tab

Is there an easy way to do this?

Salerno answered 10/4, 2012 at 11:25 Comment(6)
Find the UTC offset of a given city. #3003410Yippie
I want to to calculate not just the UTC offset but also Daylight saving/summer time. So the time will return correctly.Salerno
possible duplicate of How to initialize javascript date to a particular timezoneAlimony
Check this one as well #16084813Hotheaded
Off set of your time zone using unix date command: date +%s -d '1 Jan 1970'Tinsel
Here you have a solution using Intl browser native internationalization APIFeint
F
445

Here is the one-liner:

function convertTZ(date, tzString) {
    return new Date((typeof date === "string" ? new Date(date) : date).toLocaleString("en-US", {timeZone: tzString}));   
}

// usage: Asia/Jakarta is GMT+7
convertTZ("2012/04/20 10:10:30 +0000", "Asia/Jakarta") // Tue Apr 20 2012 17:10:30 GMT+0700 (Western Indonesia Time)

// Resulting value is regular Date() object
const convertedDate = convertTZ("2012/04/20 10:10:30 +0000", "Asia/Jakarta") 
convertedDate.getHours(); // 17

// Bonus: You can also put Date object to first arg
const date = new Date()
convertTZ(date, "Asia/Jakarta") // current date-time in jakarta.

   

This is the MDN Reference.

Beware the caveat: function above works by relying on parsing toLocaleString result, which is string of a date formatted in en-US locale , e.g. "4/20/2012, 5:10:30 PM". Each browser may not accept en-US formatted date string to its Date constructor and it may return unexpected result (it may ignore daylight saving).

Currently all modern browser accept this format and calculates daylight saving correctly, it may not work on older browser and/or exotic browser.

side-note: It would be great if modern browser have toLocaleDate function, so we don't have to use this hacky work around.

Falsecard answered 10/1, 2019 at 10:54 Comment(17)
I changed answer to this, since this is correct and standard method without using any library.Salerno
The MDN documentation clearly says that the only timezone that is required to be recognized in all implementations is UTC. (#10088319) Clicking the [Run code snippet] button in IE11 produces an error.Fattal
For the "New York" output, when applicable, is DST adjustment automatically built in or do you have to make the adjustment manually.Enure
@DanielAllenLangdon sorry, but is anyone still using IE11? this answer is working for chrome too. I know that the MDN implementation is for firefox, but I think it is more future-proof than any answer in this questionSalerno
If anyone looking for implementation that works for all browser right now, they can try any answers below with it's own cons...Salerno
This answer shows correctly passing a time zone to toLocaleString, but then it very incorrectly shows passing that string back into the Date constructor. That is asking for trouble. The Date string parser is not required to accept locale specific formats, and the input would be treated as if it were in the local time zone. Don't do that. Just use the string output from the first toLocalString call.Alimony
@MattJohnson then you can't use getHour() or such methodsLinder
Applause and meta-déjà comment, and to the SO community having this answer accepted and most voted. new Date().toLocaleString("en-US", {timeZone: "America/New_York"}) results in '2/13/2020, 12:02:49 PM' just now, which seems to me a good way it should keep working.Sykes
@MattJohnson-Pint fixedSalerno
@RizkyRamadhan - That doesn't fix the problem. It should not be using new Date when logging the string, but just using the string.Alimony
Just a note to make sure you don't change 'en-US' to another code like I did. As when you put it back into` new Date()` it has to be in the 'en-US' format.Zendah
This is a flawed approach. It doesn't parse the OP format, it relies on browsers parsing a format that they aren't required to parse, it may incorrectly apply a daylight saving offset and it presents a timestamp as UTC that isn't. The .toLocaleString(...) part is OK, the rest is not.Dig
@Dig yes, I just re-answer my seemingly popular question.Salerno
Great. Now the question is, how to do it backwards? That is, FROM the given timezone to the localMook
convertTZ("2012/04/10 10:10:30 +0000", "Asia/Jakarta"), replace +0000 with your desired offset, and then replace "Asia/Jakarta" to your local timezone.Salerno
This function will remove millisecond precession!Geoff
Regarding @MattJohnson-Pint 's warning, the Date constructor relies on the locale "en-US". I tried with "de-AT" and it did not work. This is fragile and important to know, since this code relies on converting a string back into a date. The docs say that developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… is implemented with Date.parse, which says only developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… "Other formats are implementation-defined and may not work across all browsers."Cocks
H
152

Most browsers support the toLocaleString function with arguments, older browsers usually ignore the arguments.

const str = new Date().toLocaleString('en-US', { timeZone: 'Asia/Jakarta' });
console.log(str);
Hatch answered 29/8, 2014 at 0:8 Comment(8)
Edge and chrome liked it:)Fabrikoid
It worked just now on Chrome v59 and Firefox desktop v54 and Chome on Android v59 and Safari 10 on iOS 10.3. It didn't work on IE10. MDN's description of Date.prototype.toLocaleString() has a toLocaleStringSupportsLocales() implementation that allows you to reliably check for support.Rehearse
Also, in all the browsers above, they format exactly the same as shown in jsfiddle.net/pmorch/ptqwmbyuRehearse
Successfully tested in node.js v8.7.0Dropout
No, this starts from the current time, but the question is about converting an arbitrary time (& tz) and these are very different - Date just picks up the current system time with no way to override it.Success
According to [caniuse[(caniuse.com/mdn-javascript_builtins_date_tolocalestring_options), toLocaleString can be used on Safari since version 10Insalubrious
Perhaps this will help others who see the above answer. There is a list of timezone names here. en.wikipedia.org/wiki/List_of_tz_database_time_zones Use the TZ database name when setting the locale timezone. :)Subvention
If you want the date in "ISO" format, change en-US to sv-SE.Spanker
V
144

For moment.js users, you can now use moment-timezone. Using it, your function would look something like this:

function toTimeZone(time, zone) {
    var format = 'YYYY/MM/DD HH:mm:ss ZZ';
    return moment(time, format).tz(zone).format(format);
}
Voltcoulomb answered 4/9, 2013 at 11:26 Comment(10)
I wasn't sure how to add new timezones, the docs didn't help me. I'm just a programmer, not a time expert!Stroboscope
The problem here is that this does not return a new Date object, it returns a string. If that's what you want that's good, of course.Stepha
Isn't it "return moment(time).tz(zone).format(format);" ? The one you gave in your code have me "Invalid Date" error.Nevil
@Nevil that's because time is meant to be a string of the form "2012/04/10 10:10:30 +0000" but you are providing a Date object.Voltcoulomb
It is not possible to load Moment.js in the browser. Very sad :(Digitigrade
If you're not happy about sending 180K to the browser with a copy of the tz database and can live with degradation to the current timezone on older browsers, try out @lambinator's answer using Date.prototype.toLocaleString.Rehearse
Moment-timezone doesn't work in the browser. It shouldn't be used. github.com/moment/moment-timezone/issues/607 Is there an alternative?Trajectory
Moment-timezone does actually work in the browser, just need to include moment.js before itEliseoelish
For this you have to use "moment-timezone" instead of "moment". #47046567Bookmaker
N.B. moment.js has been deprecated. momentjs.com/docs/#/-project-statusCharlesettacharleston
I
100

Stolen shamelessly from: http://www.techrepublic.com/article/convert-the-local-time-to-another-time-zone-with-this-javascript/6016329

/** 
 * function to calculate local time
 * in a different city
 * given the city's UTC offset
 */
function calcTime(city, offset) {

    // create Date object for current location
    var d = new Date();
   
    // get UTC time in msec
    var utc = d.getTime();
   
    // create new Date object for different city
    // using supplied offset
    var nd = new Date(utc + (3600000*offset));
   
    // return time as a string
    return "The local time in " + city + " is " + nd.toLocaleString();
}

this function is useful to calculate time zone value by providing name of a city/country and offset value

Impeditive answered 10/4, 2012 at 11:40 Comment(8)
nice....but I think he wants the offset to be looked up for him based on the passed in city.Yippie
This doesn't take into account daylight savings changes.Fogbound
doesn't answer the question but answers mine (+1)Workhouse
That '3600000' literally killed me! In the input, tz should be given in hours! And, it should be subtracted. So, if you pass: var d=new Date calcTime('', d.getTimezoneOffset() / 60 ); It should give back the same time.Appearance
this doesn't account for daylight savings, nor the different dateline/tz time shifts that have occurred in history (eg, certain dates/times don't exist in certain timezones).Tetryl
This answer is seriously out of date and should be removed, particularly the part using toLocaleString, which will likely report the host timezone when it has been shifted to a different timezone. There are much better ways of manually creating timestamps for different offsets.Dig
@praveen Why should the offset be in hours? Times in JS are usually in milliseconds, and offsets are in minutes in the IANA timezone database. This makes sense, because many offsets are fractions of hours (e.g. NST in Canada; CWT in Australia). Also, while I'm sorry the comment literally killed you, it's pretty clever that you've managed to post from the dead.Charlesettacharleston
@MichaelScheper Say, d=new Date. This date will be in your timezone (Say offset +1). So, if your time is 6PM, UTC should be 5PM. Now, d.getTimezoneOffset() gives you in minutes (as you only pointed out), So, it will output = -60 (Not +60) Now, we need to call calcTime('', d.getTimezoneOffset()/60); // Here is what I meant by the tz should be in hours. Now, this will give the utc time i.e. 5PM NOT the other way round i.e. utc to city time , opposite to the expectation. So, we need to subtract : var nd = new Date(utc - (3600000*offset)); Btw, thanks for acknowledging my cleverness :DAppearance
S
55

Okay, found it!

I'm using timezone-js. this is the code:

var dt = new timezoneJS.Date("2012/04/10 10:10:30 +0000", 'Europe/London');
dt.setTimezone("Asia/Jakarta");

console.debug(dt); //return formatted date-time in asia/jakarta
Salerno answered 10/4, 2012 at 12:51 Comment(4)
I have to vote against this, timezone-js does not support DST and it does not advertise that in its readme, which makes it a bad tip for people looking for this. See: github.com/mde/timezone-js/issues/51 and a number of other issues that have been filed and that don't seem to get fixed.Telegram
@nus yeah, but there really is not a solution for client side timezone/date management... jquery ui datepicker has been driving me crazy because of this. cheersBaynebridge
@Marabunta, looks like moment-timezone(answer by Brian Di Palma) supports DST github.com/moment/moment-timezone/issues/21Intravasation
Don't use TimezoneJS, it's bugged around DST changes.Creech
E
47

If you don't want to import some big library you could just use Intl.DateTimeFormat to convert Date objects to different timezones.

// Specifying timeZone is what causes the conversion, the rest is just formatting
const options = {
  year: '2-digit', month: '2-digit', day: '2-digit',
  hour: '2-digit', minute: '2-digit', second: '2-digit',
  timeZone: 'Asia/Jakarta',
  timeZoneName: 'short'
}
const formatter = new Intl.DateTimeFormat('sv-SE', options)
const startingDate = new Date("2012/04/10 10:10:30 +0000")

const dateInNewTimezone = formatter.format(startingDate) 
console.log(dateInNewTimezone) // 12-04-10 17:10:30 GMT+7

Offsets, daylight saving, and changes in the past will be taken care of for you.

UPDATE

There is also this new Temporal tool that handles timezones among other things. Like only dates or only time. It's experimental as of now

It's meant to replace the old legacy Date

var isoDate = new Date().toJSON() // eg: '2022-11-18T13:56:09.697Z'
Temporal.Instant.from(isoDate).toZonedDateTimeISO('Europe/Stockholm')
Endoderm answered 4/4, 2018 at 9:55 Comment(9)
IE10+ doesn't support Intl API for time zones. moment.github.io/luxon/docs/manual/matrix.htmlTrajectory
This is actually the best answer. toLocaleString has inconsistent implementation, and this works from IE11 onward.Cabral
FYI: This actually does not work in IE11, at least on Windows 8.1. When you try to create the formatter object, you get: ``` Option value 'Asia/Jakarta' for 'timeZone' is outside of valid range. Expected: ['UTC'] ```Tanatanach
is there a way to convert the final result from the formatter into a Date object again?Deyoung
This worked out great for my needs. As far as support goes, if IE isn't a requirement, it's at 96%, so for me that was good enough. @Deyoung use new Date(Date.parse(new Intl.DateTimeFormat(...))), though note that Date.parse is ES5 and up only.Jacalynjacamar
@mding5692: You'd need to parse it, but be careful about locale and daylight savings, and be aware that Date objects always assume local time, which is a real issue when daylight savings start or finish, because the change probably happens at a different time locally from the time zone you're working with. And then there's all the confusion around that US date format. ☹Charlesettacharleston
IMO Date conversion should be a one way street, the (HTML) is how you present the date and the js-code should only deal with Date object, timestamps or ISO standard string (never human entered string), for example don't use a text input for date, use type="datetime-local" or something that produce ISO strings, there is also input.valueAsDate that you can use to get it as a Date. You should not need to convert it back to a Date. use something like <time> to be more bot friendlyEndoderm
Temporal isn't implemented in any browsers yet, try using on a JSFiddle...it won't work.Nazareth
Wild that the sv-SE Sweden locale has exactly the formatting I wanted. I kept looking for flexible formatting without having to parse and concatenate fields manually, and just stumbled on this example with a locale that matches.Kirbee
D
13

Got it!

Wanted to force the date shown = server date, no mattter the local settings (UTC).

My server is GMT-6 --> new Date().getTimezoneOffset() = 360

myTZO = 360;
myNewDate = new Date(myOldDateObj.getTime() + (60000*(myOldDateObj.getTimezoneOffset()-myTZO)));
alert(myNewDate);
Devonian answered 17/2, 2015 at 1:19 Comment(6)
Although it shows the correct naive time, the timezone information from myOldDateObj is kept. So actually it is the wrong time (when you take time as an instance in time and not the time on a watch).Transferor
@Transferor : You won't be able to change the server time using Javascript... To fix the server time, do it at operating system level.Devonian
I don't need to fix server time ;) Server time is always UTC for me. But I have different organisation in different timezones. And their devices should always show the time of where their organisation is stationed, wherever they are.Transferor
We hava similar problem of showing dates always X timezone. We try to send all the dates in string format from server and in the browser we just treat them as local timezone dates.Piassava
Is there a reliable way to get the offset, where it considers daylight savings?Charlesettacharleston
If you always want to show UTC -6, use date.setUTCHours(date.getUTCHours() -6) then date.toISOString().replace('Z','-06:00').Dig
A
7

You can use to toLocaleString() method for setting the timezone.

new Date().toLocaleString('en-US', { timeZone: 'Asia/Kolkata' })

For India you can use "Asia/Kolkata" and the following are the various timeZones,

"Antarctica/Davis",
    "Asia/Bangkok",
    "Asia/Hovd",
    "Asia/Jakarta",
    "Asia/Phnom_Penh",
    "Asia/Pontianak",
    "Asia/Saigon",
    "Asia/Vientiane",
    "Etc/GMT-7",
    "Indian/Christmas"
Armageddon answered 10/7, 2018 at 8:13 Comment(4)
You aren't setting the timeZone, but rather producing a string with the time expressed in that timeZone. The date stays the same.Moskowitz
The toLocaleString solution was already given 4 years ago.Fulgent
"Etc/GMT-7" - is a very useful value.Cuspidation
India/Christmas is the time zone identifier for Christmas Island (an Australian territory located in the Indian Ocean). For India, the preferred time zone identifier is Asia/Kolkata.Alimony
S
5

A simple, functional, and cross-browser solution for converting between time zones and converting a date to a string with a selected time zone:

export function convertTimeZone(
  date: Date,
  timeZoneFrom?: string | null, // default timezone is Local
  timeZoneTo?: string | null, // default timezone is Local
): Date {
  const dateFrom = timeZoneFrom == null
    ? date
    : new Date(
      date.toLocaleString('en-US', {
        timeZone: timeZoneFrom,
      }),
    )

  const dateTo = timeZoneTo == null
    ? date
    : new Date(
      date.toLocaleString('en-US', {
        timeZone: timeZoneTo,
      }),
    )

  const result = new Date(date.getTime() + dateTo.getTime() - dateFrom.getTime())

  return result
}

export function dateToString(date: Date, timeZone: string): string {
  date = convertTimeZone(date, 'UTC', timeZone)

  const year = date.getUTCFullYear().toString().padStart(4, '0')
  const month = (date.getUTCMonth() + 1).toString().padStart(2, '0')
  const day = date.getUTCDate().toString().padStart(2, '0')
  const hours = date.getUTCHours().toString().padStart(2, '0')
  const minutes = date.getUTCMinutes().toString().padStart(2, '0')
  const seconds = date.getUTCSeconds().toString().padStart(2, '0')

  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}

Tests

describe('date', function () {
  it('convertTimeZone', function () {
    // UTC => UTC
    expect(convertTimeZone(new Date('2020-01-01T00:00:00.000Z'), 'UTC', 'UTC'))
      .toEqual(new Date('2020-01-01T00:00:00.000Z'))

    // UTC => Europe/Kiev
    expect(convertTimeZone(new Date('2020-01-01T00:00:00.000Z'), 'UTC', 'Europe/Kiev'))
      .toEqual(new Date('2020-01-01T02:00:00.000Z'))

    // Europe/Kiev => UTC
    expect(convertTimeZone(new Date('2020-01-01T00:00:00.000Z'), 'Europe/Kiev', 'UTC'))
      .toEqual(new Date('2019-12-31T22:00:00.000Z'))

    // Europe/Kiev => America/Los_Angeles
    expect(convertTimeZone(new Date('2020-01-01T00:00:00.000Z'), 'Europe/Kiev', 'America/Los_Angeles'))
      .toEqual(new Date('2019-12-31T14:00:00.000Z'))

    // America/Los_Angeles => Europe/Kiev
    expect(convertTimeZone(new Date('2020-01-01T00:00:00.000Z'), 'America/Los_Angeles', 'Europe/Kiev'))
      .toEqual(new Date('2020-01-01T10:00:00.000Z'))

    // Local => Local
    expect(convertTimeZone(new Date('2020-01-01T00:00:00.000Z'), null, null))
      .toEqual(new Date('2020-01-01T00:00:00.000Z'))

    // forward and backward for timezone list
    const timeZones = [
      null, // Local
      'UTC',
      'Europe/Kiev',
      'America/Los_Angeles',
      'America/New_York',
      'America/Chicago',
      'America/Denver',
      'Europe/London',
      'Europe/Paris',
      'Europe/Moscow',
      'Europe/Berlin',
      'Asia/Tokyo',
      'Asia/Shanghai',
      'Asia/Hong_Kong',
      'Asia/Kolkata',
      'Australia/Sydney',
      'Australia/Melbourne',
      'Australia/Perth',
      'Australia/Brisbane',
    ]
    for (const timeZoneFrom of timeZones) {
      for (const timeZoneTo of timeZones) {
        const date = new Date('2020-01-01T00:00:00.000Z')
        const result = convertTimeZone(date, timeZoneFrom, timeZoneTo)
        const resultBack = convertTimeZone(result, timeZoneTo, timeZoneFrom)
        expect(resultBack).toEqual(date)
      }
    }
  })

  it('dateToString', function () {
    expect(dateToString(new Date('2020-01-01T00:00:00.000Z'), 'UTC'))
      .toEqual('2020-01-01 00:00:00')

    expect(dateToString(new Date('2020-01-01T00:00:00.000Z'), 'Europe/Kiev'))
      .toEqual('2020-01-01 02:00:00')

    expect(dateToString(new Date('2020-01-01T00:00:00.000Z'), 'America/Los_Angeles'))
      .toEqual('2019-12-31 16:00:00')

    expect(dateToString(new Date('2020-01-01T00:00:00.000Z'), 'America/New_York'))
      .toEqual('2019-12-31 19:00:00')
  })

  it('dateToString current', function () {
    console.log(`Current date UTC: ${dateToString(new Date(), 'UTC')}`)
    console.log(`Current date Europe/Kiev: ${dateToString(new Date(), 'Europe/Kiev')}`)
    console.log(`Current date America/Los_Angeles: ${dateToString(new Date(), 'America/Los_Angeles')}`)
  })
})
Spill answered 18/2, 2023 at 7:59 Comment(0)
F
4

Using luxon library:

import { DateTime } from "luxon";

// Convert function:
const convertTz = (datetime, fromTz, toTz, format='yyyy-MM-dd HH:mm:ss') => {
  return DateTime.fromFormat(datetime, format, { zone: fromTz }).setZone(toTz).toFormat(format);
}

// Use it like this:
console.log(convertTz('2021-10-03 19:00:00', 'Europe/Lisbon', 'America/New_York'));

Fumigator answered 3/11, 2021 at 23:13 Comment(0)
P
3

Set a variable with year, month, and day separated with - symbols, plus a T and the time in HH:mm:ss pattern, followed by +01:00 at the end of the string (in my case the time zone is +1). Then use this string as the argument for the date constructor.

// desired format: 2001-02-04T08:16:32+01:00
dateAndTime = year+"-"+month+"-"+day+"T"+hour+":"+minutes+":00+01:00";

var date = new Date(dateAndTime );
Parotic answered 26/9, 2016 at 13:33 Comment(0)
T
3

I should note that I am restricted with respect to which external libraries that I can use. moment.js and timezone-js were NOT an option for me.

The js date object that I have is in UTC. I needed to get the date AND time from this date in a specific timezone('America/Chicago' in my case).

 var currentUtcTime = new Date(); // This is in UTC

 // Converts the UTC time to a locale specific format, including adjusting for timezone.
 var currentDateTimeCentralTimeZone = new Date(currentUtcTime.toLocaleString('en-US', { timeZone: 'America/Chicago' }));

 console.log('currentUtcTime: ' + currentUtcTime.toLocaleDateString());
 console.log('currentUtcTime Hour: ' + currentUtcTime.getHours());
 console.log('currentUtcTime Minute: ' + currentUtcTime.getMinutes());
 console.log('currentDateTimeCentralTimeZone: ' +        currentDateTimeCentralTimeZone.toLocaleDateString());
 console.log('currentDateTimeCentralTimeZone Hour: ' + currentDateTimeCentralTimeZone.getHours());
 console.log('currentDateTimeCentralTimeZone Minute: ' + currentDateTimeCentralTimeZone.getMinutes());

UTC is currently 6 hours ahead of 'America/Chicago'. Output is:

currentUtcTime: 11/25/2016
currentUtcTime Hour: 16
currentUtcTime Minute: 15

currentDateTimeCentralTimeZone: 11/25/2016
currentDateTimeCentralTimeZone Hour: 10
currentDateTimeCentralTimeZone Minute: 15
Tetracaine answered 25/11, 2016 at 16:26 Comment(4)
new Date(); return local timezone, not UTCOg
from the docs: If no arguments are provided, the constructor creates a JavaScript Date object for the current date and time according to system settings.Og
Hmm. Kinda confusing. This doesn't change the timezone on a date; rather it creates a new date with the changed hours. It would be much clearer to use a regular expression to extract the values you want from the string that is created from the toLocaleString call.Moskowitz
Seems unreliable. This might work for users in US Central time, with their browsers set to a US locale, but it will break in other places when daylight savings start or finish (because the time change will be at a different time), and at least some JS interpreters parse date strings using the machine-set locale.Charlesettacharleston
S
3

If you just need to convert timezones I have uploaded a stripped-down version of moment-timezone with just the bare minimum functionallity. Its ~1KB + data:

S.loadData({
    "zones": [
        "Europe/Paris|CET CEST|-10 -20|01010101010101010101010|1GNB0 1qM0 11A0 1o00 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0 WM0 1qM0 11A0 1o00 11A0 1o00 11A0 1qM0 WM0 1qM0|11e6",
        "Australia/Sydney|AEDT AEST|-b0 -a0|01010101010101010101010|1GQg0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1fA0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0 1cM0|40e5",
    ],
    "links": [
        "Europe/Paris|Europe/Madrid",
    ]
});

let d = new Date();
console.log(S.tz(d, "Europe/Madrid").toLocaleString());
console.log(S.tz(d, "Australia/Sydney").toLocaleString());
Styria answered 22/4, 2017 at 16:19 Comment(2)
This is a time bomb… it will break when daylight savings rules change, which happens all the time.Charlesettacharleston
@michael-scheper of course you need to keep the zones data up to date.Styria
K
3

Here is my code, it is working perfectly, you can try with give below demo:

$(document).ready(function() {
   //EST
setInterval( function() {
var estTime = new Date();
 var currentDateTimeCentralTimeZone = new Date(estTime.toLocaleString('en-US', { timeZone: 'America/Chicago' }));
var seconds = currentDateTimeCentralTimeZone.getSeconds();
var minutes = currentDateTimeCentralTimeZone.getMinutes();
var hours =  currentDateTimeCentralTimeZone.getHours()+1;//new Date().getHours();
 var am_pm = currentDateTimeCentralTimeZone.getHours() >= 12 ? "PM" : "AM";

if (hours < 10){
     hours = "0" + hours;
}

if (minutes < 10){
     minutes = "0" + minutes;
}
if (seconds < 10){
     seconds = "0" + seconds;
}
    var mid='PM';
    if(hours==0){ //At 00 hours we need to show 12 am
    hours=12;
    }
    else if(hours>12)
    {
    hours=hours%12;
    mid='AM';
    }
    var x3 = hours+':'+minutes+':'+seconds +' '+am_pm
// Add a leading zero to seconds value
$("#sec").html(x3);
},1000);


});
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<p class="date_time"><strong id="sec"></strong></p>
</body>
</html>
Kingkingbird answered 16/10, 2018 at 9:50 Comment(6)
Welcome to StackOverflow! Can u provide more information like how this code works and what it does? How it fixes the problem?Paranymph
My given above code is to update your timezone to other countries timezone.Kingkingbird
You need to put the HTML in your html file and given above jquery code need to be in the footer. It will work for you as per ('en-US', { timeZone: 'America/Chicago' }) you need to update these two values, if you want other countries timezone ThanksKingkingbird
No wait. I just upvoted this without looking carefully. Why are you adding 1 to currentDateTimeCentralTimeZone.getHours() ? Without that it would work and is the same as seeking27's answer https://mcmap.net/q/73740/-convert-date-to-another-timezone-in-javascriptKishke
'It is working perfectly'—are you sure? Have you tested it in multiple time zones, at different times of year (thus with different daylight savings rules), in different locales (including the default US locale, with its confusing date format)? I've definitely met JS interpreters that use the system locale when parsing new Date(string), so forcing an AM/PM time and US-formatted date is asking for trouble IMHO.Charlesettacharleston
@MichaelScheper Yes its working I have tested this with multiple timezone. If you still find any problem with that, just let me knowKingkingbird
N
2

You can also use https://www.npmjs.com/package/ctoc_timezone

It has got much simple implementation and format customisation.

Changing format in toTimeZone:

CtoC.toTimeZone(new Date(),"EST","Do MMM YYYY hh:mm:ss #{EST}");

Output :

28th Feb 2013 19:00:00 EST

You can explore multiple functionalities in the doc.

Nelsonnema answered 1/11, 2018 at 6:49 Comment(0)
A
2

Do it as easy:

const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(timeZone);

var d = new Date();
console.log(d.toLocaleString('en-US', { timeZone }));
Atal answered 6/12, 2020 at 6:51 Comment(1)
The trouble with this is that the output is a String, and JavaScript doesn't seem to provide an elegant, 'as easy' way to convert from a String to a timezone-naïve Date, without the potential of getting messed up by locale and daylight savings issues.Charlesettacharleston
K
1

You can try this also for convert date timezone to India:

var indianTimeZoneVal = new Date().toLocaleString('en-US', {timeZone: 'Asia/Kolkata'});
var indainDateObj = new Date(indianTimeZoneVal);
indainDateObj.setHours(indainDateObj.getHours() + 5);
indainDateObj.setMinutes(indainDateObj.getMinutes() + 30);
console.log(indainDateObj);
Kerstin answered 29/9, 2016 at 7:15 Comment(3)
after the 2nd step itself i get the time in India... so why are you still adding 5&1/2hrs to it?Col
When using that method I get the following here in Norway when I console log with Chrome: Original: Thu Sep 27 2018 15:53:46 GMT+0200 (sentraleuropeisk sommertid). Modified: Thu Sep 27 2018 19:23:46 GMT+0200 (sentraleuropeisk sommertid). “sentraleuropeisk sommertid” means Central European Summer Time. Not sure if that would work when you need summer time for India, or vice versa when you're in India and need summer time for Europe, and so on.Rabbin
Using setHours() like this does not account for day, month, year transitions, for example 3:30 am in New Dell on the 8th is 11 pm on the 7th in London. Then consider the end of the month, year and leap days. Have Date do that math <pre> let local_time = new Date(zulu_time.getTime() + 3600000*std_timezone.timezone_factor - 60*60*1000); let date_str = local_time.toISOString().slice(0, 10); let time_str = local_time.toISOString().slice(11, -1); let timezone_str = std_timezone.timezone_str; </pre>Mislay
L
1

I recently did this in Typescript :

// fromTimezone example : Europe/Paris, toTimezone example: Europe/London
private calcTime( fromTimezone: string, toTimezone: string, dateFromTimezone: Date ): Date {
  const dateToGetOffset = new Date( 2018, 5, 1, 12 );

  const fromTimeString = dateToGetOffset.toLocaleTimeString( "en-UK", { timeZone: fromTimezone, hour12: false } );
  const toTimeString = dateToGetOffset.toLocaleTimeString( "en-UK", { timeZone: toTimezone, hour12: false } );

  const fromTimeHours: number = parseInt( fromTimeString.substr( 0, 2 ), 10 );
  const toTimeHours: number = parseInt( toTimeString.substr( 0, 2 ), 10 );

  const offset: number = fromTimeHours - toTimeHours;

  // convert to msec
  // add local time zone offset
  // get UTC time in msec
  const dateFromTimezoneUTC = Date.UTC( dateFromTimezone.getUTCFullYear(),
    dateFromTimezone.getUTCMonth(),
    dateFromTimezone.getUTCDate(),
    dateFromTimezone.getUTCHours(),
    dateFromTimezone.getUTCMinutes(),
    dateFromTimezone.getUTCSeconds(),
  );

  // create new Date object for different city
  // using supplied offset
  const dateUTC = new Date( dateFromTimezoneUTC + ( 3600000 * offset ) );

  // return time as a string
  return dateUTC;
}

I Use "en-UK" format because it is a simple one. Could have been "en-US" or whatever works.

If first argument is your locale timezone and seconde is your target timezone it returns a Date object with the correct offset.

Lautrec answered 29/5, 2018 at 15:57 Comment(0)
R
1

Having looked around a lot including links from this page i found this great article, using moment timezone:

https://www.webniraj.com/2016/11/23/javascript-using-moment-js-to-display-dates-times-in-users-timezone/

To summarise it:

Get the user's timezone

var tz = moment.tz.guess();
console.info('Timezone: ' + tz);

Returns eg: Timezone: Europe/London

Set the default user timezone

moment.tz.setDefault(tz);

Set custom timezone

moment.tz.setDefault('America/Los_Angeles');

Convert date / time to local timezone, assumes original date/time is in UTC

moment.utc('2016-12-25 07:00').tz(tz).format('ddd, Do MMMM YYYY, h:mma');

Returns: Sun, 25th December 2016, 7:00am

Convert date/time to LA Time

moment.utc('2016-12-25 07:00').tz('America/Los_Angeles').format('ddd, Do MMMM YYYY, h:mma');

Returns: Sat, 24th December 2016, 11:00pm

Convert from LA time to London

moment.tz('2016-12-25 07:00', 'America/Los_Angeles').tz('Europe/London').format( 'ddd, Do MMMM YYYY, h:mma' );

Returns: Sun, 25th December 2016, 3:00pm

Rurik answered 13/9, 2018 at 12:8 Comment(0)
E
1

Provide the desired time zone, for example "Asia/Tehran" to change the current time to that timezone. I used "Asia/Seoul".

You can use the following codes. change the style if you need to do so.

please keep in mind that if you want to have h:m:s format instead of HH:MM:SS, you'll have to remove "function kcwcheckT(i)".

function kcwcheckT(i) {
  if (i < 10) {
    i = "0" + i;
  }
  return i;
}
function kcwt() {
var d = new Date().toLocaleString("en-US", {timeZone: "Asia/Seoul"});
d = new Date(d);
  var h = d.getHours();
  var m = d.getMinutes();
  var s = d.getSeconds();
  h = kcwcheckT(h);
  m = kcwcheckT(m);
  s = kcwcheckT(s);
  document.getElementById("kcwcurtime").innerHTML = h + ":" + m + ":" + s;
  var days = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
document.getElementById("kcwcurday").innerHTML = days[d.getDay()]
}
kcwt();
window.setInterval(kcwt, 1000);
@import url('https://fonts.googleapis.com/css2?family=Nunito&display=swap');

.kcwsource {color:#040505;cursor: pointer;display:block;width: 100%;border: none;border-radius:5px;text-align:center;padding: 5px 10px 5px 10px;}
.kcwsource p {font-family: 'Nunito', sans-serif;}


.CurTbx {color:#040505;cursor: pointer;display:block;width: 100%;border: none;border-radius:5px;text-align:center;padding: 5px 10px 5px 10px;}
.kcwcstyle {font-family: 'Nunito', sans-serif; font-size: 22px;display: inline-block;}
.kcwcurstinf {font-family: 'Nunito', sans-serif; font-size: 18px;display: inline-block;margin: 0;}
.kcwcurday {margin: 0;}
.kcwcurst {margin: 0 10px 0 5px;}

/*Using the css below you can make your style responsive!*/

@media (max-width: 600px){
  .kcwcstyle {font-size: 14px;}
  .kcwcurstinf {font-size: 12px;}
}
<div class="kcwsource"><p>This Pen was originally developed for <a href="http://kocowafa.com" target="_blank">KOCOWAFA.com</a></p></div>
<div class="CurTbx"><p class="kcwcurst kcwcstyle" id="kcwcurday"></p><p class="kcwcurst kcwcstyle" id="kcwcurtime"></p><p class="kcwcurstinf">(Seoul, Korea)</p></div>
Ephemeral answered 14/8, 2020 at 3:52 Comment(0)
R
1

You can use Intl.DateTimeFormat to specify timezone as an option and it would convert the date or time to your desired timezone.

let timezone = "Asia/Jakarta";
let date = new Date("2012/04/10 10:10:30 +0000");
let formattedDate = new Intl.DateTimeFormat("en-US", { dateStyle: "long" , timeStyle: "short",  timeZone: timezone}).format(date);
Roulers answered 22/10, 2022 at 10:50 Comment(0)
W
1

This is UTC date; converting UTC to IST timezone;

let sampleArray = [
  {
    date: "2022-12-22T19:16:26.803"
  },
  {
    date: "2022-12-22T19:16:26.77"
  },
  {
    date: "2022-12-22T19:16:26.737"
  },
  {
    date: "2022-12-22T19:16:26.72"
  }
];

// Get all the results whose boolresult is 'true'
// solution 1
sampleArray.map((element) => {
  let utcDate = new Date(element.date).getTime();
  let dateIST = new Date(utcDate);
  dateIST.setHours(dateIST.getHours() + 5);
  dateIST.setMinutes(dateIST.getMinutes() + 30);
  element.date = dateIST;
});
console.log("Result ==>>", sampleArray);

// solution 2
sampleArray.map((element) => {
  element.date = new Date(element.date).toLocaleString("en-US", {
    timeZone: "Asia/Kolkata"
  });
});
console.log("Result 2==>>", sampleArray);
Ways answered 10/1, 2023 at 20:3 Comment(0)
C
1

The code below works for this question and may help others with similar problems. This could be helpful when we need the epoch in milliseconds or the UNIX timestamps at another timezone.

function convertDate(date, timeZone) {
    let diff = 0;
    const now = new Date(new Date().toLocaleString());
    const newDate = new Date(now.toLocaleString('en-US', { timeZone }));

    if (now.getTime() !== newDate.getTime()) { // prevent from unnecessary conversions
      diff = now.getTime() - newDate.getTime();
    }
    
    return new Date(date.getTime() - diff);
}


console.log(convertDate(new Date(), "Asia/Jakarta").toLocaleString());
Cyrano answered 3/5, 2023 at 18:58 Comment(1)
Above code resolved my issue where i had time delay in the date&time column.Speculative
C
0

I don't know an easy method to convert a date object to any time zone, but if you want to convert it to the local time zone, you can just convert it with Date.prototype.getTime() to the corresponding number of milliseconds, and back again.

let date0 = new Date('2016-05-24T13:07:20');
let date1 = new Date(date0.getTime());

console.log(`${date0}\n${date1}`);

For example, date.getHours() will now return 15 instead of 13 if you are, like me, in Austria (and it's summer).

I've read that the various datetime functions may exhibit non-standard behaviour in some browsers, so test this first. I can confirm that it works in Chrome.

Cygnet answered 24/5, 2016 at 13:22 Comment(3)
Why was this voted down? This is by far the easiest and best way of doing this. Most of the answers above do not take summer/winter time into considerationApollo
What's the point of the second line? The Date constructor assumes your local time zone already. Both of these lines returns a date in the local browser time zone, and doesn't answer the question on how to convert to another time zone with daylight savings time.Trajectory
This answer is pointless. The initial string should be parsed as local, so the first statement will create a Date with a time value that is equivalent to 2016-05-24T13:07:20 in the host timezone. The second line just copies that Date. How it could be upvoted at all is a mystery.Dig
E
0

There is an npm module called timezones.json you can use for this. It basically consists of a json file with objects containing information on daylight savings and offset.

For asia/jakarta, it would be able to return this object:

{
  "value": "SE Asia Standard Time",
  "abbr": "SAST",
  "offset": 7,
  "isdst": false,
  "text": "(UTC+07:00) Bangkok, Hanoi, Jakarta",
  "utc": [
    "Antarctica/Davis",
    "Asia/Bangkok",
    "Asia/Hovd",
    "Asia/Jakarta",
    "Asia/Phnom_Penh",
    "Asia/Pontianak",
    "Asia/Saigon",
    "Asia/Vientiane",
    "Etc/GMT-7",
    "Indian/Christmas"
  ]
}

You can find it here:

https://github.com/dmfilipenko/timezones.json

https://www.npmjs.com/package/timezones.json

hope it's useful

Enthalpy answered 25/7, 2016 at 6:4 Comment(0)
T
0

People familiar with the java 8 java.time package, or joda-time will probably love the new kid on the block: the js-joda library.

Install

npm install js-joda js-joda-timezone --save

Example

<script src="node_modules/js-joda/dist/js-joda.js"></script>
<script src="node_modules/js-joda-timezone/dist/js-joda-timezone.js"></script>
<script>
var dateStr = '2012/04/10 10:10:30 +0000';
JSJoda.use(JSJodaTimezone);
var j = JSJoda;
// https://js-joda.github.io/js-joda/esdoc/class/src/format/DateTimeFormatter.js~DateTimeFormatter.html#static-method-of-pattern
var zonedDateTime = j.ZonedDateTime.parse(dateStr, j.DateTimeFormatter.ofPattern('yyyy/MM/dd HH:mm:ss xx'));
var adjustedZonedDateTime = zonedDateTime.withZoneSameInstant(j.ZoneId.of('America/New_York'));
console.log(zonedDateTime.toString(), '=>', adjustedZonedDateTime.toString());
// 2012-04-10T10:10:30Z => 2012-04-10T06:10:30-04:00[America/New_York]
</script>

In true java nature, it's pretty verbose lol. But, being a ported java library, especially considering they ported 1800'ish test cases, it also probably works superbly accurately.

Chrono manipulation is hard. That's why many other libraries are buggy in edge cases. Moment.js seems to get timezones right, but the other js libs I've seen, including timezone-js, don't seem trustworthy.

Tetryl answered 14/12, 2017 at 0:14 Comment(0)
J
0

I was having trouble using Moment Timezone. I am adding this answer just so if somebody else faces the same issue. So I have a date string 2018-06-14 13:51:00 coming from my API. I know that this is stored in UTC but the string doesn't speak for itself.

I let moment timezone know, what timezone this date is from by doing:

let uTCDatetime = momentTz.tz("2018-06-14 13:51:00", "UTC").format();
// If your datetime is from any other timezone then add that instead of "UTC"
// this actually makes the date as : 2018-06-14T13:51:00Z

Now I would like to convert it to a specific timezone by doing:

let dateInMyTimeZone = momentTz.tz(uTCDatetime, "Asia/Kolkata").format("YYYY-MM-DD HH:mm:ss");
// now this results into: 2018-06-14 19:21:00, which is the corresponding date in my timezone.
Jeanmariejeanna answered 6/6, 2018 at 13:54 Comment(0)
C
0

Just set your desire country timezone and You can easily show in html it update using SetInteval() function after every one minut. function formatAMPM() manage 12 hour format and AM/PM time display.

$(document).ready(function(){
        var pakTime = new Date().toLocaleString("en-US", {timeZone: "Asia/Karachi"});
        pakTime = new Date(pakTime);

        var libyaTime = new Date().toLocaleString("en-US", {timeZone: "Africa/Tripoli"});
        libyaTime = new Date(libyaTime);



         document.getElementById("pak").innerHTML = "PAK  "+formatAMPM(pakTime);
         document.getElementById("ly").innerHTML = "LY   " +formatAMPM(libyaTime);

        setInterval(function(today) {
            var pakTime = new Date().toLocaleString("en-US", {timeZone: "Asia/Karachi"});
            pakTime = new Date(pakTime);

            var libyaTime = new Date().toLocaleString("en-US", {timeZone: "Africa/Tripoli"});
            libyaTime = new Date(libyaTime);


           document.getElementById("pak").innerHTML = "PAK  "+formatAMPM(pakTime);
           document.getElementById("ly").innerHTML = "LY  " +formatAMPM(libyaTime);

        },10000);

         function formatAMPM(date) {
            var hours = date.getHours();
            var minutes = date.getMinutes();
            var ampm = hours >= 12 ? 'pm' : 'am';
            hours = hours % 12;
            hours = hours ? hours : 12; // the hour '0' should be '12'
            minutes = minutes < 10 ? '0'+minutes : minutes;
            var strTime = hours + ':' + minutes + ' ' + ampm;
            return strTime;
        }


    });
Capo answered 4/4, 2020 at 12:1 Comment(0)
D
0

there is server issue pick gmt+0000 standard time zone you can change it by using library moment-timezone in javascript

const moment = require("moment-timezone")
const dateNew = new Date()
const changeZone = moment(dateNew);
changeZone.tz("Asia/Karachi").format("ha z");
// here you can paste "your time zone string"
Dorella answered 21/12, 2020 at 6:48 Comment(0)
G
0

A bit redundant with all these answers, but this worked for me for getting the current Date object with a specific hourly offset.

 function hourToMs(hour)
    {
        return hour * 60 * 1000 * 60;
    }
    
    function minToMs(min)
    {
        return min * 60 * 1000;
    }
    
    function getCurrentDateByOffset(offset)
    {
        // Get the current timezone in milliseconds to reset back to GMT aka +0
        let timezoneOffset = minToMs((new Date()).getTimezoneOffset());
        
        // get the desired offset in milliseconds, invert the value because javascript is dum
        let desiredOffset = hourToMs(offset * -1);
    
        return new Date(Date.now() + timezoneOffset - desiredOffset);
    }
    
    // -6 hours is central timezone
    console.log("The time is: " + getCurrentDateByOffset(-6));
Gerdy answered 13/3, 2021 at 19:15 Comment(0)
C
0

This is worked for me in React Native Application.

import moment from 'moment-timezone'

function convertTZ(date, tzString) {
  const formatedDate = moment(date).tz(tzString).format()
  return formatedDate
}

export {convertTZ}
Cazzie answered 28/2, 2022 at 15:29 Comment(0)
P
0

This should work for everyone. You can test out different time zones by changing the time manually on your machine. This function will adapt accordingly.

 function getCurrentTime() {
     const d = new Date() //2022-07-22T16:27:21.322Z
     const t = d.getTime(); //d in milliseconds 1658507241322
     const offset = -d.getTimezoneOffset()/60 //current offset in hours -4
     const curretMilli = t + (offset * 3600000) //cuuret local time milliseconds need to convert offset to milliseconds
     return new Date(curretMilli) //converts current local time in milliseconds to a Date //2022-07-22T12:27:21.322Z
 }
Pendleton answered 22/7, 2022 at 16:37 Comment(1)
This takes neither the time nor the timezone as input parameters.Hebrides
H
0

It's very odd, that we still don't have a solution for that long running problem.

I came with simple way to get timezone offset only on the backend, but it's very HACKY, so take it into consideration.

process.env.TZ = 'Europe/Berlin';
console.log(new Date().getTimezoneOffset());

P.S. Best answer is still the best tho.

Horme answered 18/7, 2023 at 21:10 Comment(0)
M
0

JavaScript is TERRIBLE when it comes to TZ support.

If you are only interested in converting hours (in a real prod scenario), the best way is unfortunately to compute manually:

const localDate = new Date();
const localOffset = - localDate.getTimezoneOffset() / 60 ;

let from = user.hourToConvert - user.offset + localOffset;

if(from < 0 ) from += 24; // -2 becomes 22h at night
if(from >= 24 ) from -= 24 ; // 28 hours because 4 in morning

Where you already retrieved user.offset (with the same localOffset method), and you want to convert user.hourToConvert to localOffset.

Manus answered 30/12, 2023 at 12:2 Comment(0)
F
-1
You can use this if you have a timezone offset:
const timezoneDate = (timestamp: number, offsetInHours: number) => {
  const shiftedTimestamp = timestamp + offsetInHours * 3600000;

  const shiftedDate = new Date(shiftedTimestamp);

  return {
    date: shiftedDate.getUTCDate(),
    hours: shiftedDate.getUTCHours(),
    minutes: shiftedDate.getUTCMinutes(),
    // ...other UTC methods
  }
};

// Usage:
const newYorkDate = timezoneDate(Date.now(), -5);

console.log(
  `It is ${newYorkDate.hours}:${newYorkDate.minutes} in NYC`
);
Fusionism answered 28/1, 2023 at 20:57 Comment(0)
T
-2

Time Zone Offset for your current timezone

date +%s -d '1 Jan 1970'

For my GMT+10 timezone (Australia) it returned -36000

Tinsel answered 15/2, 2018 at 4:49 Comment(0)
D
-8

quick and dirty manual hour changer and return:

return new Date(new Date().setHours(new Date().getHours()+3)).getHours()
Disengagement answered 13/7, 2019 at 4:36 Comment(1)
too dirty (and too messy)Unintelligent

© 2022 - 2024 — McMap. All rights reserved.