【问题标题】:Converting Google spreadsheet date into a JS Date object?将 Google 电子表格日期转换为 JS Date 对象?
【发布时间】:2013-01-16 16:28:45
【问题描述】:

我一直在这个问题上兜圈子...我有一个包含两个日期的电子表格,我需要找到这两个日期之间经过的年数(即某人在给定日期的年龄; 这是 Excel 的 DATEDIF 的替代品)。

第一步是将 Google 的序列号转换为 JS Date 对象,但似乎没有 Date 构造函数可以执行此操作。有什么想法吗?

谢谢。

【问题讨论】:

  • 看看这个电子表格中的公式:docs.google.com/spreadsheet/…
  • 不行,恐怕 - 你不能在应用程序脚本中使用电子表格功能,所以你必须从头开始编写。
  • this thread 中的最后一篇文章建议您可以获取电子表格日期,使用一些电子表格 javascript 实用程序将其转换为 javascript 日期构造函数可以处理的文本格式,然后将该字符串提供给javascript日期构造函数。如果你认真地在谷歌上搜索这个问题,我怀疑你会找到答案。

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


【解决方案1】:

将 Google 电子表格日期转换为 javascript 日期:

var JSdate = Date.parse(Cell.getValue())

要将 javascript 日期转换为 Google 电子表格日期:

function GoogleDate( JSdate ) { 
   var D = new Date(JSdate) ;
   var Null = new Date(Date.UTC(1899,11,30,0,0,0,0)) ; // the starting value for Google
   return ((D.getTime()  - Null.getTime())/60000 - D.getTimezoneOffset()) / 1440 ;
}

【讨论】:

    【解决方案2】:

    我知道您对目前的解决方案很满意,但我只是想补充一下我对 Google Apps 脚本如何处理“日期”的观察,这些“日期”可以通过自定义函数传递,也可以使用 getValue() 从单元格中检索.

    我的经验法则是,如果表格(电子表格应用程序)提供一个值格式化作为日期(通过自动强制或用户设置格式),那么 Google Apps 脚本将自动将此值保存为日期对象。

    例如:

    function returnDate(value) {
      return new Date(value);  
    }
    

    如果您在 A1 中输入 1/1/13,并在另一个单元格中调用 =returnDate(A1),它将返回相同的日期(就像您在代码中仅包含 return value; 一样)。但是,请注意当您将 A1 格式化为“正常”(将其转换为数值)时会发生什么。在这里,“表格序列号”(从 1899 年 12 月 30 日开始的天数)被 Google Apps 脚本转换为日期对象,但在 GAS 中,它被“视为”从 1970 年 1 月 1 日午夜开始的毫秒数.因此,如果您传递您认为代表日期的数值,您可能会得到意想不到的结果。

    也比较一下:

    =returnDate(DATE(2013;1;1))

    =returnDate(VALUE("1/1/13"))

    =returnDate(DATEVALUE("1/1/13"))

    =returnDate("1/1/13")

    =returnDate("1/1/2013")

    后两个“有效”,因为new Date() 成功地从有效字符串创建了日期对象,但请注意,Sheets 自动强制转换为当前世纪,而 GAS 将两位数年份强制转换为 1900 年代。

    因此,IMO 如果您希望它的行为与 Excel 中的行为完全相同(即,将数值“视为”日期的序列号),您需要首先测试传递的参数是否为日期对象(或“有效”文本字符串),如果不是,则将其从“1899 年 12 月 30 日的天数”数学转换为“1970 年 1 月 1 日的毫秒数”,然后 new Date() 它。

    为这篇冗长的帖子道歉。

    【讨论】:

    【解决方案3】:

    这就是我所做的:

    function numberToDate(number){
      var date = new Date(number * 24 * 60 * 60 * 1000);
      date.setFullYear(date.getFullYear() - 70);
      date.setDate(date.getDate() - 1);
      return (date);
    }
    

    这可能看起来有点脏,但这是我目前找到的唯一解决方案

    【讨论】:

    • 我知道这不应该做,但你刚刚救了我的命! :)
    【解决方案4】:

    经过更多的实验,结果证明它确实有效,这有点令人惊讶。 new Date(cell) 似乎在内部将序列号转换为足以创建日期对象的字符串。完整答案:

    function datedif(first, second, format) {
      var e1  = new Date(first);
      var e2  = new Date(second);
      var age = e2.getFullYear() - e1.getFullYear();
      if(
          (e2.getMonth() <  e1.getMonth()) || 
         ((e2.getMonth() == e1.getMonth()) && (e2.getDate() < e1.getDate())))
        age--;
      return age;
    }
    

    【讨论】:

      【解决方案5】:

      你可以这样试试:

      return new Date(1900, 0, --excelDate)
      

      【讨论】:

      • 我试图将从 v4 API 返回的日期转换为数字。这是对我有用的答案
      【解决方案6】:

      首先,您必须从 google sheet config 获取时区设置。

      那么,这就是完美的解决方案:

      import { zonedTimeToUtc, utcToZonedTime } from "date-fns-tz";
      
      const SheetDate = {
        origin: Date.UTC(1899, 11, 30, 0, 0, 0, 0),
        dayToMs: 24 * 60 * 60 * 1000
      };
      function serialToDate(d: number, sheetTimeZone: string): Date {
        return zonedTimeToUtc(
          new Date(d * SheetDate.dayToMs + SheetDate.origin),
          sheetTimeZone
        );
      }
      function dateToSerial(date: Date, sheetTimeZone: string) {
        const msec = utcToZonedTime(date, sheetTimeZone).getTime() - SheetDate.origin;
        return msec / SheetDate.dayToMs;
      }
      

      【讨论】:

        【解决方案7】:

        为我工作

        private static getDateFromGoogle(serialNumber: number): Date {
          // Google     30 Dec 1899
          // Javascript 01 Jan 1970
          return new Date((serialNumber - 25569) * 86400000);
        }

        【讨论】:

        • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
        【解决方案8】:

        通过“序列号”,我猜你说的是从纪元开始以秒或毫秒为单位的 unix 时间。您可以简单地使用标准的 Javascript Date 对象:

        new Date(value);
        

        Google 是您的朋友。这里有一些参考资料可以帮助您开始:

        Javascript 允许您对两个日期进行简单的减法运算,以毫秒为单位返回时间差。

        var timeDiffInMS = date2 - date1;
        

        这应该是你需要弄清楚的全部,所以我将把年份计算留给读者作为练习。

        【讨论】:

        • Google 似乎以与 Excel 相同的方式存储日期值,从 1899 年的最后一天开始,因此 Google 一定在某个地方做了一些魔术。尽管如此,“新日期(值)”仍然有效,所以我会标记你... :)
        • 序列号与纪元时间不同。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-03-20
        • 2020-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-08
        相关资源
        最近更新 更多