如何从Google电子表格中读取正确的时间值
我试图从一个时间格式单元格(hh:mm:ss)得到的小时值,值可以是更大的24:00:00例如20000:00:00应该给20000:
表:
如果你读了E1的价值:
var total = sheet.getRange("E1").getValue(); Logger.log(total);
结果是:
星期六4月12日07:09:21 GMT + 00:09 1902
现在我试着把它转换成一个Date对象,并得到它的Unix时间戳:
var date = new Date(total); var milsec = date.getTime(); Logger.log(Utilities.formatString("%11.6f",milsec)); var hours = milsec / 1000 / 60 / 60; Logger.log(hours)
1374127872020.000000
381702.1866722222
问题是如何获得20000的正确值?
为未来的读者。 有两个新的函数getDisplayValue()
和getDisplayValues()
由App Script提供返回显示值的人员。 查看这里的文档
扩展了Serge所做的工作,我写了一些函数,应该更容易阅读,并考虑电子表格和脚本之间的时区差异。
function getValueAsSeconds(range) { var value = range.getValue(); // Get the date value in the spreadsheet's timezone. var spreadsheetTimezone = range.getSheet().getParent().getSpreadsheetTimeZone(); var dateString = Utilities.formatDate(value, spreadsheetTimezone, 'EEE, d MMM yyyy HH:mm:ss'); var date = new Date(dateString); // Initialize the date of the epoch. var epoch = new Date('Dec 30, 1899 00:00:00'); // Calculate the number of milliseconds between the epoch and the value. var diff = date.getTime() - epoch.getTime(); // Convert the milliseconds to seconds and return. return Math.round(diff / 1000); } function getValueAsMinutes(range) { return getValueAsSeconds(range) / 60; } function getValueAsHours(range) { return getValueAsMinutes(range) / 60; }
你可以像这样使用这些函数:
var range = SpreadsheetApp.getActiveSheet().getRange('A1'); Logger.log(getValueAsHours(range));
不用说,从一个范围内获得小时数是一项很大的工作。 请星号问题402是一个function请求有能力从一个单元格获得文字string值。
您看到的值(Sat Apr 12 07:09:21 GMT + 00:09 1902)是Javascript标准时间的等效date,比参考date晚20000小时。
您应该简单地从结果中删除电子表格参考值以获得您想要的结果。
这个代码的诀窍是:
function getHours(){ var sh = SpreadsheetApp.getActiveSpreadsheet(); var cellValue = sh.getRange('E1').getValue(); var eqDate = new Date(cellValue);// this is the date object corresponding to your cell value in JS standard Logger.log('Cell Date in JS format '+eqDate) Logger.log('ref date in JS '+new Date(0,0,0,0,0,0)); var testOnZero = eqDate.getTime();Logger.log('Use this with a cell value = 0 to check the value to use in the next line of code '+testOnZero); var hours = (eqDate.getTime()+ 2.2091616E12 )/3600000 ; // getTime retrieves the value in milliseconds, 2.2091616E12 is the difference between javascript ref and spreadsheet ref. Logger.log('Value in hours with offset correction : '+hours); // show result in hours (obtained by dividing by 3600000) }
注意:这个代码只有几个小时,如果你有分钟和/或秒,那么它应该发展,以处理这个…让我们知道如果你需要它。
编辑:一个解释的话…
Spreadsheets使用12/30/1899的引用date,而Javascript使用01/01/1970,这意味着两个引用之间有25568天的差异。 所有这些假设我们在两个系统中使用相同的时区。 当我们将电子表格中的date值转换为javascriptdate对象时,GAS引擎会自动添加差异以保持date之间的一致性。
在这种情况下,我们不想知道某个东西的真实date,而是一个绝对小时值,即“持续时间”,所以我们需要删除25568日偏移量。 这是使用getTime()
方法完成的,该方法返回从JS引用date开始计算的毫秒数,我们唯一需要知道的是电子表格引用date的毫秒数值,并将该值从实际date对象中减去。 然后一些math来获得小时而不是毫秒,我们就完成了。
我知道这似乎有点复杂,我不确定我的解释的尝试是否会真正澄清这个问题,但总是值得一试,不是吗?
无论如何,只要(如评论中所述)根据电子表格的时区设置来调整偏移值,结果就是我们所需要的。 当然可以让脚本自动处理,但会使脚本更复杂,不确定是否真的有必要。
对于简单的电子表格,您可以在不使用夏令时的情况下将电子表格时区更改为GMT,并使用以下简短转换function:
function durationToSeconds(value) { var timezoneName = SpreadsheetApp.getActive().getSpreadsheetTimeZone(); if (timezoneName != "Etc/GMT") { throw new Error("Timezone must be GMT to handle time durations, found " + timezoneName); } return (Number(value) + 2209161600000) / 1000; }
Eric Koleda的答案在很多方面都比较一般。 我在写这篇文章的同时,试图了解它如何处理电子表格时区,浏览器时区以及1900年阿拉斯加和斯德哥尔摩的时区更改。