如何从Google电子表格中读取正确的时间值

时间:2013-07-18 06:14:00

标签: javascript time google-apps-script google-sheets

我试图从时间格式化Cell(hh:mm:ss)得到小时值,值可以更大24:00:00,例如20000:00:00应该给20000:

表:

two Google Spread Sheet

如果你读了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的正确值?

4 个答案:

答案 0 :(得分:17)

扩展了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));

毋庸置疑,要从一个范围获得小时数,需要做很多工作。请将Issue 402标记为功能请求,以便能够从单元格中获取文字字符串值。

答案 1 :(得分:9)

对于未来的读者。 App Script的人员提供了两个新函数(function(){ /* do something */ }()); // Douglas Crockford recommends (function(){ /* do something */ })(); // This way works as well o,它们返回显示值。查看文档here

答案 2 :(得分:8)

您看到的值(星期六12月12日07:09:21 GMT + 00:09 1902)是Javascript标准时间中的等效日期,比参考日期晚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)
}

enter image description here

注意:这段代码只需要几个小时,如果您需要几分钟和/或几秒钟,那么应该开发它来处理它...如果您需要它,请告诉我们。


编辑:一句解释......

当Javascript使用01/01/1970时,电子表格使用的引用日期为12/30/1899,这意味着两个引用之间的差异为25568天。所有这些假设我们在两个系统中使用相同的时区。当我们将电子表格中的日期值转换为javascript日期对象时,GAS引擎会自动添加差异以保持日期之间的一致性。

在这种情况下,我们不想知道某事的真实日期,而是一个绝对的小时值,即"持续时间",所以我们需要删除25568天的偏移量。这是使用getTime()方法完成的,该方法返回从JS引用日期开始计算的毫秒数,我们唯一需要知道的是电子表格引用日期的毫秒数值,并从实际日期对象中减去此值。然后用一些数学来得到几小时而不是几毫秒,我们就完成了。

我知道这看起来有点复杂,我不确定我的解释是否会真正澄清这个问题,但它总是值得尝试不是吗?

无论如何,结果就是我们所需要的,只要(如评论中所述)根据电子表格的时区设置调整偏移值。当然可以让脚本自动处理,但它会使脚本更复杂,不确定它是否真的有必要。

答案 3 :(得分:5)

对于简单的电子表格,您可以将电子表格时区更改为GMT而无需夏令时,并使用此短转换功能:

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年阿拉斯加和斯德哥尔摩的时区变化处理角落案例。