在JavaScript中将日期转换为另一个时区

Riz*_*han 294 javascript timezone

我正在寻找一个功能,将日期在一个时区转换为另一个时区.

它需要两个参数,

  • 日期(格式为"2012/04/10 10:10:30 +0000")
  • 时区字符串("亚洲/雅加达")

时区字符串在http://en.wikipedia.org/wiki/Zone.tab中描述

是否有捷径可寻?

Bri*_*lma 128

对于moment.js用户,您现在可以使用moment-timezone.使用它,你的功能看起来像这样:

function toTimeZone(time, zone) {
    var format = 'YYYY/MM/DD HH:mm:ss ZZ';
    return moment(time, format).tz(zone).format(format);
}
Run Code Online (Sandbox Code Playgroud)

  • 这里的问题是,这不会返回一个新的Date对象,它返回一个字符串.当然,如果这就是你想要的那么好. (7认同)
  • 我不确定如何添加新时区,文档对我没有帮助。我只是一个程序员,不是时间专家! (6认同)
  • 不是“返回时刻(时间)。tz(区域)。格式(格式);” ? 您在代码中给出的那个有我“无效日期”错误。 (2认同)
  • 如果你不满意使用tz数据库的副本向浏览器发送180K并且可以在旧版浏览器中使用降级到当前时区,请使用`Date.prototype.toLocaleString`尝试@ lambinator的答案. (2认同)

Udh*_*aya 107

var aestTime = new Date().toLocaleString("en-US", {timeZone: "Australia/Brisbane"});
aestTime = new Date(aestTime);
console.log('AEST time: '+aestTime.toLocaleString())

var asiaTime = new Date().toLocaleString("en-US", {timeZone: "Asia/Shanghai"});
asiaTime = new Date(asiaTime);
console.log('Asia time: '+asiaTime.toLocaleString())

var usaTime = new Date().toLocaleString("en-US", {timeZone: "America/New_York"});
usaTime = new Date(usaTime);
console.log('USA time: '+usaTime.toLocaleString())

var indiaTime = new Date().toLocaleString("en-US", {timeZone: "Asia/Kolkata"});
indiaTime = new Date(indiaTime);
console.log('India time: '+indiaTime.toLocaleString())
Run Code Online (Sandbox Code Playgroud)

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

  • 这个答案显示正确地将时区传递给`toLocaleString`,但是随后却非常不正确地显示了将该字符串传递回`Date`构造函数。那是自找麻烦。日期字符串解析器不需要接受特定于语言环境的格式,并且输入将被视为位于本地时区。不要那样做 只需使用第一个“ toLocalString”调用中的字符串输出即可。 (5认同)
  • @MattJohnson 那么你不能使用 getHour() 或此类方法 (4认同)
  • 我改变了这个答案,因为这是正确的标准方法,不使用任何库。 (2认同)
  • MDN文档明确指出,所有实现中唯一需要识别的时区是UTC。(/sf/ask/706147361/)单击IE11中的[运行代码段]按钮会产生错误。 (2认同)
  • 这是一个有缺陷的方法。它不解析 OP 格式,它依赖于浏览器解析不需要解析的格式,它可能会错误地应用夏令时偏移量,并且它会显示一个不是 UTC 的时间戳。`.toLocaleString(...)` 部分没问题,其余部分则不行。 (2认同)

Val*_*i69 89

:从无耻被盗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();

    // convert to msec
    // add local time zone offset
    // get UTC time in msec
    var utc = d.getTime() + (d.getTimezoneOffset() * 60000);

    // 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();
}
Run Code Online (Sandbox Code Playgroud)

此功能通过提供城市/国家/地区的名称和偏移值来计算时区值

  • 这没有考虑夏令时的变化. (110认同)
  • 不回答问题,但回答我的(+1) (12认同)
  • 很好....但我认为他希望根据传入的城市来查找偏移量. (4认同)
  • 这个答案已经过时了,应该删除,特别是使用 *toLocaleString* 的部分,当它转移到不同的时区时,它可能会报告主机时区。有更好的方法可以为不同的偏移量手动创建时间戳。 (3认同)
  • 仅当前日期不能用于过去的日期。 (2认同)

lam*_*tor 86

除Safari之外的大多数桌面(非移动)浏览器都支持带参数的toLocaleString函数,旧浏览器通常会忽略这些参数.

new Date().toLocaleString('en-US', { timeZone: 'Asia/Jakarta' })
Run Code Online (Sandbox Code Playgroud)

  • 因为这在FF和IE11 +中很难实现,所以需要找到另一种解决方案. (10认同)
  • 它刚刚在Android v59上的Chrome v59和Firefox桌面v54和Chome以及iOS 10.3上的Safari 10上运行.它在IE10上无效.[MDN对Date.prototype.toLocaleString()的描述](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString)有一个`toLocaleStringSupportsLocales()`实现,允许您可靠地检查支持. (6认同)
  • 不,这从当前时间开始,但问题是关于转换任意时间 (& tz),这些是非常不同的 - 日期只是获取当前系统时间,无法覆盖它。 (5认同)
  • 在Firefox和Edge中失败:( (4认同)
  • Edge和chrome喜欢它:) (2认同)

Riz*_*han 57

好的,找到了!

我正在使用timezone-js.这是代码:

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
Run Code Online (Sandbox Code Playgroud)

  • 我必须投票反对这一点,timezone-js不支持DST,它不会在其自述文件中做广告,这对于寻找此问题的人来说是一个糟糕的提示.请参阅:https://github.com/mde/timezone-js/issues/51以及其他一些已经提交但似乎无法解决的问题. (85认同)
  • @Marabunta,看起来像时刻时区(Brian Di Palma的回答)支持DST https://github.com/moment/moment-timezone/issues/21 (2认同)
  • 不要使用TimezoneJS,它会围绕DST更改进行窃听. (2认同)

Ced*_*mon 10

得到它了 !

想要强制显示的日期=服务器日期,不要使用本地设置(UTC).

我的服务器是GMT-6 - > new Date().getTimezoneOffset()= 360.

myTZO = 360;
myNewDate=new Date(myOldDateObj.getTime() + (60000*(myOldDateObj.getTimezoneOffset()-myTZO)));
alert(myNewDate);
Run Code Online (Sandbox Code Playgroud)

  • 尽管它显示了正确的原始时间,但仍保留myOldDateObj中的时区信息.所以实际上是错误的时间(当你把时间作为一个实例,而不是手表上的时间). (2认同)
  • 我不需要修复服务器时间;)服务器时间对我来说总是UTC.但是我在不同的时区有不同的组织.他们的设备应始终显示其组织所在的时间,无论他们身在何处. (2认同)

End*_*ess 10

如果您不想导入一些大型库,则可以使用Intl.DateTimeFormat将Date对象转换为不同的时区。

// 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 formater = new Intl.DateTimeFormat('sv-SE', options)
const startingDate = new Date("2012/04/10 10:10:30 +0000")

const dateInNewTimezone = formater.format(startingDate) 
console.log(dateInNewTimezone) // 12-04-10 17:10:30 GMT+7
Run Code Online (Sandbox Code Playgroud)

偏移量,夏时制和过去的更改将为您解决。

  • 有没有办法将格式化程序的最终结果再次转换为 Date 对象? (2认同)

Cod*_*ker 8

您可以使用 toLocaleString() 方法来设置时区。

new Date().toLocaleString('en-US', { timeZone: 'Indian/Christmas' })
Run Code Online (Sandbox Code Playgroud)

对于印度,您可以使用“Indian/Christmas”,以下是不同的时区,

"Antarctica/Davis",
    "Asia/Bangkok",
    "Asia/Hovd",
    "Asia/Jakarta",
    "Asia/Phnom_Penh",
    "Asia/Pontianak",
    "Asia/Saigon",
    "Asia/Vientiane",
    "Etc/GMT-7",
    "Indian/Christmas"
Run Code Online (Sandbox Code Playgroud)

  • `India/Christmas` 是[圣诞岛](https://en.wikipedia.org/wiki/Christmas_Island)(位于印度洋的澳大利亚领土)的时区标识符。对于印度,首选时区标识符是“亚洲/加尔各答”。 (2认同)