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

pat*_*ick 13 javascript time google-sheets google-apps-script

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

表:

两张Google Spread Sheet

如果你读了E1的价值:

var total = sheet.getRange("E1").getValue();
Logger.log(total);
Run Code Online (Sandbox Code Playgroud)

结果是:

周四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)
Run Code Online (Sandbox Code Playgroud)

1374127872020.000000

381702.1866722222

问题是如何获得20000的正确值?

Eri*_*eda 18

扩展了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;
}
Run Code Online (Sandbox Code Playgroud)

你可以像这样使用这些函数:

var range = SpreadsheetApp.getActiveSheet().getRange('A1');
Logger.log(getValueAsHours(range));
Run Code Online (Sandbox Code Playgroud)

不用说,从一个范围获得小时数是很多工作.请为问题402加注星标,这是一个功能请求,可以从单元格中获取文字字符串值.

  • 根据https://code.google.com/p/google-apps-script-issues/issues/detail?id=402#c26,问题402已修复:) (2认同)

lla*_*alu 10

对于未来的读者.有两个新功能getDisplayValue(),getDisplayValues()由App Script人员提供,返回显示值.在这里查看文档

  • 谢谢,是的,我需要专门从工作表中获取时间和日期到文档中。显示值,不会被时区或其他混乱。现在,我通过将所有相关文件和脚本中的时区设置为“ GMT(无夏令时)”来解决此问题。 (3认同)

Ser*_*sas 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)
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

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


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

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

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

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

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


小智 5

对于简单的电子表格,您可以将电子表格的时区更改为格林尼治标准时间而不使用夏令时,并使用以下简短转换功能:

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;
}
Run Code Online (Sandbox Code Playgroud)

埃里克·科莱达(Eric Koleda)的回答在许多方面都更为笼统。我写这篇文章的时候试图了解它如何处理电子表格时区,浏览器时区以及1900年阿拉斯加和斯德哥尔摩时区变化的极端情况。