[英]Converting Google spreadsheet date into a JS Date object?
I've been going round in circles on this one... I've got a spreadsheet which holds two dates, and I need to find the number of elapsed years between the two (ie. someone's age at a given date; this is a replacement for Excel's DATEDIF).我一直在绕圈子......我有一个包含两个日期的电子表格,我需要找到两个日期之间经过的年数(即某人在给定日期的年龄;这是Excel 的 DATEDIF 的替代品)。
The first step is to convert Google's serial number into a JS Date object, but there doesn't appear to be Date constructor that does this.第一步是将 Google 的序列号转换为 JS 日期 object,但似乎没有执行此操作的日期构造函数。 Any ideas?
有任何想法吗?
Thanks.谢谢。
To convert a Google spreadsheet date to a javascript date :要将 Google 电子表格日期转换为 javascript 日期:
var JSdate = Date.parse(Cell.getValue())
To convert a javascript date to a Google spreadsheet date:要将 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 ;
}
I know you are happy with your solution as it stands, but I just wanted to add my observations of how Google Apps Script deals with "dates", either passed in a custom function, or retrieved from a cell with getValue().我知道您对目前的解决方案感到满意,但我只想添加我对 Google Apps 脚本如何处理“日期”的观察,这些日期要么传入自定义函数,要么从使用 getValue() 的单元格中检索。
My rule of thumb is that if Sheets (the spreadsheet application) is providing a value formatted as a date (either by automatic coercion, or the user setting the format), then Google Apps Script will automatically hold this value as a date object.我的经验法则是,如果 Sheets(电子表格应用程序)提供格式为日期的值(通过自动强制或用户设置格式),那么 Google Apps 脚本将自动将此值保存为日期对象。
Eg:例如:
function returnDate(value) {
return new Date(value);
}
If you enter 1/1/13
in A1, and in another cell you invoke =returnDate(A1)
, it will return the same date (as it would if you simply had return value;
in the code).如果您在 A1 中输入
1/1/13
,并在另一个单元格中调用=returnDate(A1)
,它将返回相同的日期(就像您只有return value;
在代码中)。 However, watch what happens when you format A1 as "Normal" (convert it to a numerical value).但是,请注意将 A1 格式化为“正常”(将其转换为数值)时会发生什么。 Here, the "Sheets serial number" (number of days from 30/12/1899) is converted into a date object by Google Apps Script, but in GAS it is "regarded" as the number of milliseconds from midnight 1/1/1970.
在这里,“工作表序列号”(从 30/12/1899 开始的天数)被 Google Apps 脚本转换为日期对象,但在 GAS 中它被“视为”从 1970 年 1 月 1 日午夜开始的毫秒数. So you might get unexpected results if you are passing numerical values that you believe are representative of a date.
因此,如果您传递的是您认为代表日期的数值,则可能会得到意想不到的结果。
Also compare:还比较:
=returnDate(DATE(2013;1;1))
=returnDate(VALUE("1/1/13"))
=returnDate(DATEVALUE("1/1/13"))
=returnDate("1/1/13")
=returnDate("1/1/2013")
The latter two "work", because new Date()
successfully creates the date object from a valid string, but note that Sheets automatically coerces to the current century, while GAS coerces a two-digit year to the 1900's.后两个“有效”,因为
new Date()
成功地从有效字符串创建了日期对象,但请注意,Sheets 会自动强制到当前世纪,而 GAS 会将两位数的年份强制到 1900 年代。
So IMO if you wanted it to behave exactly as it would in Excel (that is, "regard" a numerical value as a serial number for a date), you would need to first test if the passed parameter is a date object (or "valid" text string), and if not, mathematically convert it from "days from 30/12/1899" to "milliseconds from 1/1/1970", and then new Date()
it.因此,IMO 如果您希望它的行为与 Excel 中的完全一样(即,将数值“视为”日期的序列号),则您需要首先测试传递的参数是否为日期对象(或“有效”文本字符串),如果不是,则以数学方式将其从“从 30/12/1899 开始的天数”转换为“从 1/1/1970 开始的毫秒数”,然后将其转换为
new Date()
。
Apologies for the long-winded post.为冗长的帖子道歉。
This is what I did:这就是我所做的:
function numberToDate(number){
var date = new Date(number * 24 * 60 * 60 * 1000);
date.setFullYear(date.getFullYear() - 70);
date.setDate(date.getDate() - 1);
return (date);
}
This may seem a bit dirty, but this is the only solution I found for now这可能看起来有点脏,但这是我目前找到的唯一解决方案
After some more experimenting, it turned out that it just works, which was a bit of a surprise.经过一些更多的实验,结果证明它确实有效,这有点令人惊讶。
new Date(cell)
seems to internally convert the serial number into a string which is sufficient to create the date object. new Date(cell)
似乎在内部将序列号转换为足以创建日期对象的字符串。 Full answer:完整答案:
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;
}
你可以这样试试:
return new Date(1900, 0, --excelDate)
First, you have to get timezone setting from google sheet config.首先,您必须从谷歌工作表配置中获取时区设置。
Then, this is the perfect solution:然后,这是完美的解决方案:
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;
}
Works for me适合我
private static getDateFromGoogle(serialNumber: number): Date { // Google 30 Dec 1899 // Javascript 01 Jan 1970 return new Date((serialNumber - 25569) * 86400000); }
By "serial number" I'm guessing you're talking about a unix time in seconds or milliseconds from the epoch.通过“序列号”,我猜你是在谈论从纪元开始的以秒或毫秒为单位的 unix 时间。 You can simply use the standard Javascript Date object:
您可以简单地使用标准的 Javascript Date 对象:
new Date(value);
Google is your friend from there.谷歌是你的朋友。 Here's some references to start you off:
这里有一些参考资料可以让你开始:
Javascript allows you to do simple subtraction with two Dates, returning you the time difference in ms. Javascript 允许您对两个日期进行简单的减法运算,以毫秒为单位返回时差。
var timeDiffInMS = date2 - date1;
That should be all you need to figure it out, so I'll leave the years calculation as an exercise for the reader.这应该就是您需要弄清楚的全部内容,因此我将把年数计算留给读者作为练习。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.