将Google电子表格日期转换为JS Date对象?

时间:2013-01-16 16:28:46

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

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

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

感谢。

7 个答案:

答案 0 :(得分:8)

我知道您对目前的解决方案感到满意,但我只想添加我对Google Apps脚本如何处理“日期”的观察,或者通过自定义函数传递,或者使用getValue()从单元格中检索

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

例如:

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

如果您在A1中输入1/1/13,并在另一个单元格中调用=returnDate(A1),则会返回相同的日期(就像您在代码中只有return value;一样)。但是,请注意将A1格式设置为“正常”时会发生什么(将其转换为数值)。在这里,“Sheets序列号”(从18/12年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年。 / p>

所以IMO如果你想让它的行为与在Excel中完全一样(也就是说,“将数值视为日期的序列号”),你需要首先测试传递的参数是否是日期对象(或“有效”文本字符串),如果没有,则在数学上将其从“18/12/1899的天数”转换为“1970年1月1日的毫秒”,然后new Date()

为啰嗦的帖子道歉。

答案 1 :(得分:8)

将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 :(得分: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);
}

这看起来有点脏,但这是我现在找到的唯一解决方案

答案 3 :(得分:1)

经过一些更多的实验,结果证明它只是有效,这有点令人惊讶。 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;
}

答案 4 :(得分:0)

通过“序列号”我猜你正在谈论从纪元开始的几秒或几毫秒的unix时间。您只需使用标准的Javascript Date对象:

new Date(value);

谷歌是你的朋友。这里有一些启动你的参考:

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

var timeDiffInMS = date2 - date1;

这应该是你需要解决的全部内容,所以我将把年份计算作为读者的练习。

答案 5 :(得分:0)

您可以尝试这样:

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

答案 6 :(得分:0)

首先,您必须从Google表格配置中获取时区设置。

然后,这是完美的解决方案:

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;
}