Google Apps脚本中的时区

时间:2012-09-16 22:32:32

标签: google-apps-script

我想将日期对象转换为与Google电子表格中使用的日期的基础值一致的“序列号”。我的理解是,在Javascript中,日期对象的原始值是1970年1月1日午夜之后(或之前)的毫秒数;在Google Spreadsheets中,日期的原始值在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()?
}

这会返回一个有点偏离的值 - 我认为“off”对应于我与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上运行,而“调整”实际上是一个错误的解决方法?

2 个答案:

答案 0 :(得分:2)

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

像getHours(),getMinutes()等方法会给出片刻的时间。结果取决于所用日期对象的时区。如果你想独立于日期对象的时区,你应该使用getUTCHours(),getUTCMinutes()等等。

答案 1 :(得分: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 ;
}