我一直围着这一个圈子......我有一个电子表格,里面有两个日期,我需要找到两者之间经过的年数(即某个人在给定日期的年龄) ;这是Excel的DATEDIF的替代品。
第一步是将Google的序列号转换为JS Date对象,但似乎没有Date构造函数执行此操作。有什么想法吗?
感谢。
答案 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;
}