Google apps script Google应用程序脚本中的时区

Google apps script Google应用程序脚本中的时区,google-apps-script,Google Apps Script,我想将日期对象转换为“序列号”,该序列号与Google电子表格中使用的日期的基本值一致。我的理解是,在Javascript中,日期对象的基本值是1970年1月1日午夜之后(或之前)的毫秒数;在谷歌电子表格中,1899年12月30日午夜的日期原始值为0(零),此后每天等于1(例如,7小时等于7除以24) 我尝试了这个功能: function date2Serial(date) { return (date.getTime() + 2209161600000) / 86400000; //

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

现在我尝试使用该方法,该方法似乎可以纠正问题:

function date2Serial(date) {
  return (date.getTime() + 2209161600000 - (date.getTimezoneOffset() * 60000)) / 86400000;
}
但是,这取决于项目属性时区是否正确,而不是电子表格设置时区(实际上可以对每个时区进行不同的设置)

我的问题:

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

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


像getHours()、getMinutes()之类的方法给出了一部分时间。结果取决于所用日期对象的时区。如果你想独立于日期对象的时区,你应该使用getUTCHours()、getUTCMinutes()等等。

这段代码也会考虑到当地的夏季时间。这有点低效,因为要正确创建日期对象必须创建两次

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

谢谢你,塔拉斯,这很有帮助。我现在意识到getTime()将在1970年1月1日UTC的午夜为零,在谷歌电子表格中,无论电子表格设置在哪个时区,0的值都对应于1899年12月30日的午夜-这是一个本质的区别。