【问题标题】:Odd timezone offset when converting转换时的奇数时区偏移
【发布时间】:2022-01-06 23:14:28
【问题描述】:

我尽可能使用 UTC。现在我发现了以下奇怪的行为,我真的不明白发生了什么。如果有人可以提供建议,那就太好了。

注意:我在 Google Apps 脚本编辑器中编写代码。

我使用以下代码创建日期并以我的本地时区获取输出:

var testDate = Date.UTC(2022,0,1,0,0,0,0);
Logger.log(Utilities.formatDate(new Date(testDate), 'Europe/Berlin', 'dd.MM.yyyy hh:mm'));

结果是01.01.2022 01:00,正如预期的那样,因为“Europe/Berlin”比 UTC 晚 1 小时。因此,如果我希望输出为 01.01.2022 00:00,我会尝试以下操作:

var testDate = Date.UTC(2021,11,31,23,0,0,0);
Logger.log(Utilities.formatDate(new Date(testDate), 'Europe/Berlin', 'dd.MM.yyyy hh:mm'));

但我得到的结果是:01.01.2022 12:00 谁能提示我为什么我的期望是错误的?

(希望我的英语没问题。)

【问题讨论】:

  • Date.UTC(2021,11,31,23,0,0,0 你真的是指 11 月 31 日吗?在我所在的地区,11 月只有 30 天。
  • 月份参数从零开始(0 = 一月),因此 11 = 十二月。
  • ` 'Europe/Berlin' 比 UTC 晚 1 小时 ` 你的意思是 ahead 吗?
  • @Kos 没错。翻译可能有点迷失

标签: javascript date google-apps-script timezone utc


【解决方案1】:

我认为我们不能直接回答这个问题,因为看起来问题是 Utilities.formatDate 使用 12:00 表示午夜(这是写午夜的两种有效方式之一在许多系统中,尤其是在使用 12 小时制时,尽管通常您会在它后面加上一些指示它是上午 12:00,而不是下午 12:00)。例如,这是另一个格式化程序的示例,因为我明确告诉它使用 12 小时时间:

const testDate = Date.UTC(2022,0,1,0,0,0,0);
const dateTimeFormat = new Intl.DateTimeFormat("en", {
    hour12: true,
    timeZone: "UTC",
    timeStyle: "short",
}).format;
console.log(dateTimeFormat(testDate));

因此,您必须查看 Utilities.formatDate 以查看它是否有 24 小时时间的选项,或者至少像其他格式化程序一样使用 00:00 午夜时间。

但更根本的是,如果您尝试使用 UTC 格式,我不会玩偏移游戏来做到这一点,尤其是因为柏林并非总是与 UTC 相差一小时,有时这是两个小时的偏移量(夏令时)。¹相反,我有一个格式化程序,它使用DategetUTCHoursgetUTCMonth 等)上的 UTC 访问器来构建字符串,而不是使用本地时间版本。要么是某个库,要么是使用Intl.DateTimeFormat 的东西。例如:

const testDate = Date.UTC(2022,0,1,0,0,0,0);
const dateTimeFormat = new Intl.DateTimeFormat("de", {
    timeZone: "UTC",
    dateStyle: "medium",
    timeStyle: "short",
}).format;
// Outputs "01.01.2022, 00:00", which is close to but
// not quite the same as your desired format
console.log(dateTimeFormat(testDate));

// Outputs your desired format, but may not be flexible across locales
const dateFormat = new Intl.DateTimeFormat("de", {
    timeZone: "UTC",
    dateStyle: "medium",
}).format;
const timeFormat = new Intl.DateTimeFormat("de", {
    timeZone: "UTC",
    timeStyle: "short",
}).format;
console.log(`${dateFormat(testDate)} ${timeFormat(testDate)}`);

¹ 请记住,UTC 是不变的,它没有夏令时。

【讨论】:

  • 感谢您的回答。我知道夏令时问题及其在实际应用中的含义。但我的问题更多地与我的问题中的具体示例有关。我确实使用 23 作为小时值并得到了上述结果,但不明白为什么。
  • @OleRehr-Doh!你做到了,不是吗!我看得太快了,在月槽中看到了 11。对于那个很抱歉!我已经更新了我怀疑问题的答案,但实际上这将取决于Utilities.formatDate 所做的事情。
  • @OleRehr 尝试用HH 代替hh,或KK,参见docs.oracle.com/javase/7/docs/api/java/text/…
  • @T.J.Crowder - 你的回答很有帮助!当谈到日期和时间时,我仍然陷入每一个陷阱。
  • @Kos - JavaScript,不是 Java。 :-)
猜你喜欢
  • 2011-05-23
  • 2021-06-29
  • 1970-01-01
  • 2017-11-22
  • 2021-10-16
  • 2020-09-24
  • 1970-01-01
  • 1970-01-01
  • 2019-04-07
相关资源
最近更新 更多