我有一个特定时区的日期时间作为字符串,我想将其转换为本地时间。但是,我不知道如何在Date对象中设置时区。

例如,我有2013年2月28日东部时间晚上7点,然后我可以

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

据我所知,我可以设置UTC时间或本地时间。但是,如何在另一个时区设置时间呢?

我尝试使用添加/减去UTC的偏移量,但我不知道如何对抗夏令时。我不确定我走的方向是否正确。

如何在javascript中将时间从不同的时区转换为本地时间?


当前回答

我在单元测试中遇到了类似的问题(特别是开玩笑地说,单元测试在本地运行以创建快照,然后CI服务器(可能)在不同的时区运行,导致快照比较失败)。我嘲笑我们的约会和一些辅助方法,如下所示:

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;
  });

});

其他回答

我也有同样的问题,但是我们可以使用我们想要的时区 我们使用。tolocaledatestring ()

例如: var day=new Date(); const选项={日:“数字”,月:“长”,年:“数字”,时区:“亚洲/加尔各答”}; const今天=。toLocaleDateString(“en-IN”,选项); console.log(今天);

我在运行GCP云函数时遇到了这个问题。当然,它在本地机器上工作,但是在云中运行使得new Date()的操作系统默认值(本地)无关紧要。在我的例子中,来自云的api调用需要东部标准时间,ISO格式(不带“Z”),偏移量为“-0500”或“-0400”,取决于DST,例如:

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

同样,这不是浏览器格式问题,所以我被迫采用这种格式,以便api调用能够正确工作。

使用@chickens代码作为开始,这是有效的:

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

在上面的答案的基础上,我使用本机的一行代码将长时区字符串转换为三个字母的字符串:

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

这将根据所提供的日期给出PDT或PST。在我的特殊用例中,在Salesforce (Aura/Lightning)上开发,我们能够从后端获得长格式的用户时区。

简单,支持Node.JS

传入时区与UTC时间的偏移量

function initDateInTimezone(offsetHours) {
  const timezoneOffsetInMS = offsetHours * 60 * 60000;
  let d = new Date().getTimezoneOffset() * 60000 + timezoneOffsetInMS;
  const date = new Date(new Date().getTime() - d);
    return 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;
};

如何与时区和本地时间一起使用:

dateWithTimeZone("America/Los_Angeles",2019,8,8,0,0,0)