【问题标题】:Javascript converting Date to UTC (And leave unmodified if is already UTC)Javascript将日期转换为UTC(如果已经是UTC,则保持不变)
【发布时间】:2017-02-09 07:26:09
【问题描述】:

首先,我知道如何在 Javascript 中将本地日期转换为 UTC。这不是那个的复制品。

我一直在尝试获取一个将日期转换为 UTC(如果还没有)的函数,我无法控制输入是否为 UTC。我不能使用 Javascript 插件。

正常的解决方案是将本地日期解析为 UTC,但以这种方式解析已经是 UTC 的日期会输出错误地修改已经 UTC 日期的奇怪行为

我在下面有一个示例函数。

function temp() {
  var utc = new Date(Date.UTC(2017, 1, 10, 10, 10, 0));
  var local = new Date(2017, 1, 10, 10, 10, 0);

  var utc2 = new Date(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate(),  utc.getUTCHours(), utc.getUTCMinutes(), utc.getUTCSeconds());
  var local2 = new Date(local.getUTCFullYear(), local.getUTCMonth(), local.getUTCDate(),  local.getUTCHours(), local.getUTCMinutes(), local.getUTCSeconds());

  var utc3 = new Date(utc.getTime() + utc.getTimezoneOffset()*60*1000);
  var local3 = new Date(local.getTime() + local.getTimezoneOffset()*60*1000);

  Logger.log("Timezone offset: UTC=" + utc.getTimezoneOffset() + " Local=" + local.getTimezoneOffset());
  Logger.log("UTC: " + utc.getTime() + " -> UTC2(" + utc2.getTime() + ") or UTC3(" + utc3.getTime() +")");
  Logger.log("Local: " + local.getTime() + " -> UTC2(" + local2.getTime() + ") or UTC3(" + local3.getTime() +")");
}

返回

Timezone offset: UTC=420 Local=420
UTC: 1486721400000 -> UTC2(1486746600000) or UTC3(1486746600000)
Local: 1486746600000 -> UTC2(1486771800000) or UTC3(1486771800000)

请注意,即使是 UTC 日期也有时区偏移。并且将本地日期转换为 UTC 的两种方法都会将已经 UTC 日期修改为不正确的日期。

感谢您的帮助。

【问题讨论】:

  • 在谈论 ECMAScript Date 对象时,“我知道如何在 Javascript 中将本地日期转换为 UTC”这句话没有任何意义。 Javascript 日期总是 UTC,它们不能“转换为 UTC”。如果您有一个要解析的字符串,那就另当别论了。但是,您的问题没有解析。
  • "…即使是 UTC 日期也有时区偏移"。日期没有时区偏移。 getTimezoneOffset 方法从主机系统获取偏移量,它与 Date 实例无关。

标签: javascript date datetime


【解决方案1】:

这种行为没有什么奇怪的,很遗憾,您的问题没有答案(使用默认的 JavaScript Date 实现)。

在 JavaScript 中,每个 Date 都用自纪元以来的毫秒数表示。 Date 实例始终在解释器(例如,您的浏览器)时区内处理。因此,当您调用new Date(Date.UTC(2017, 1, 10, 10, 10, 0)); 时,您实际上创建了一个Date 实例,该实例在内部由1486721400000 表示。

getTimezoneOffset() 方法总是从您当前时区的角度返回值。所以在我的情况下(加利福尼亚),如下:

document.write(new Date(Date.UTC(2017, 1, 8, 10, 0, 0)).toString());
document.write("<br/>");
document.write(new Date(Date.UTC(2016, 8, 8, 10, 0, 0)).toString());

输出(使用 cmets)

480 // Wed Feb 08 2017 02:00:00 GMT-0800 (PST)
420 // Thu Sep 08 2016 03:00:00 GMT-0700 (PDT)

尝试为您的问题寻找答案

我能想到的唯一解决方案是您创建自己的Date 实现(因为您不想使用任何“插件”)。您可以创建自己的Date,它还可以存储时区,或者只是有一个标志来定义Date 是否在UTC 中。如果您重新考虑 JavaScript 库的使用,您可能需要查看,例如,https://momentjs.com/timezone/

这里有一个示例,说明如何开始您自己的实现

function TzDate (date, utc) {
  if (date instanceof Date) {
    this.date = date;
    this.utc = utc ? true : false;
  } else if (typeof date === 'number') {
    this.date = new Date(date);
    this.utc = true;
  } else if (typeof date === 'boolean') {
    this.date = new Date();
    this.utc = date;
  } else {
    this.date = new Date();
    this.utc = utc ? true : false;
  }
}
 
TzDate.prototype = {
  toString: function() {
    return this.isUTC() ? this.date.toUTCString() : this.date.toString()
  },
  
  getTimezoneOffset: function() {
    return this.isUTC() ? 0 : this.date.getTimezoneOffset();
  },

  isUTC: function() {
    return this.utc;
  }
};

console.log(new TzDate().toString());
console.log(new TzDate(true).toString());
console.log(new TzDate(Date.UTC(2017, 1, 8, 10, 0, 0)).toString());
console.log(new TzDate(new Date(2017, 1, 8, 10, 0, 0)).toString());

另见:

【讨论】:

  • 我添加了一个小代码 sn-p,它可以帮助您入门或了解您可以做什么。
猜你喜欢
  • 2021-04-19
  • 2019-12-05
  • 2012-10-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-07
  • 2021-12-31
  • 1970-01-01
  • 2011-11-06
相关资源
最近更新 更多