2

我想将日期对象转换为与 Google 电子表格中使用的日期的基础值一致的“序列号”。我的理解是,在 Javascript 中,日期对象的原始值是 1970 年 1 月 1 日午夜之后(或之前)的毫秒数;在 Google 电子表格中,对于 1899 年 12 月 30 日午夜,日期的原始值是 0(零),之后的每一天都等于 1(例如,7 小时等于 7 除以 24)。

我试过这个功能:

function date2Serial(date) {
  return (date.getTime() + 2209161600000) / 86400000;
  // 2209161600000 = milliseconds between 1899-12-30 and 1970-01-01
  // 86400000 = milliseconds in a day
  // question "on the side" - is there any essential difference between
  //  .getTime() and .valueOf()?
}

这会返回一个有点偏离的值 - 我认为“关闭”对应于我与 GMT 的时区差异。因此,即使在我的情况下,电子表格设置和项目属性都设置为 GMT+10,getTime() 似乎在 GMT 上运行。

例如:

A1: 16/09/2012 06:00:00
A2: =date2serial(A1)
A3: =VALUE(A1)

A2 返回 41167.8333,其中 A3 返回 41168.25。

现在我尝试使用getTimezoneOffset()方法,该方法似乎可以解决问题:

function date2Serial(date) {
  return (date.getTime() + 2209161600000 - (date.getTimezoneOffset() * 60000)) / 86400000;
}

然而,这依赖于正确的项目属性时区,而不是电子表格设置时区(实际上可以不同地设置这些时区)。

我的问题:

这种行为是预期的吗,是否需要对时区进行“调整”?或者 getTime()(以及所有其他方法,如 getHours()、getMinutes() 等)是否应该在用户设置的时区而不是 GMT/UTC 上运行,而“调整”实际上是解决 bug 的一种方法?

4

2 回答 2

2

getTime() 返回一个持续时间,而不是某个时刻,因此没有时区。减去的参考时刻是 1970 年 1 月 1 日午夜(UTC)。

getHours()、getMinutes() 等方法会提供部分时间。结果取决于使用的日期对象的时区。如果您想独立于日期对象的时区,您应该使用 getUTCHours()、getUTCMinutes() 等。

于 2012-09-17T07:19:30.527 回答
0

此代码还将考虑当地的夏令时。这有点低效,因为要正确,必须创建两次 Date 对象。

function ValueToDate(GoogleDateValue) {
  var d = Date.UTC(1899,11,30,0,0,0)+(GoogleDateValue*86400000) ;
  return new Date(d+(new Date(d)).getTimezoneOffset()*60000) ;
}

function DateToValue(date) {
  return (date.getTime()-date.getTimezoneOffset()*60000)/86400000+25569 ;
}
于 2020-06-07T11:59:29.627 回答