我想将日期对象转换为与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上运行,而“调整”实际上是一个错误的解决方法?
答案 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 ;
}