在Google reference documentation中,我找到了一个将RFC3339日期字符串转换为有效Date对象的简短函数。代码非常简单,如下所示:
function parseDate(string) {
var parts = string.split('T');
parts[0] = parts[0].replace(/-/g, '/');
return new Date(parts.join(' '));
}
问题在于它不起作用。(我很惊讶他们发布的代码不起作用......我错过了什么?)
我在使用JSON进行字符串化和解析日期时也遇到了问题,因为JSON方法返回UTC值(结尾为Z),因此我丢失了时区信息。谷歌的代码也没有处理这个问题(即使它有效)。
下面是我用来测试它的演示代码和我写的解决方案,以获得我想要的东西。不确定它是非常有效还是写得不好,但至少我得到了我想要的结果(我在比利时夏令时设置为GMT + 2的脚本中执行此代码)。 我愿意接受任何改进此代码的建议。(这将成为这个问题的主题)
我在代码中添加了很多日志和注释,以使其尽可能清晰:
function testJSONDate() {
Logger.log('starting value : "2016/3/31 12:00:00"');
var jsDate = JSON.stringify(new Date("2016/3/31 12:00:00"));// time is 12:00 I'm in GMT+2
Logger.log('JSON.stringify value : '+jsDate);
Logger.log('JSON parse jsDate : '+JSON.parse(jsDate)); // time is 10:00, UTC
var jsDateWithoutQuotes = jsDate.replace(/"/,'');
var date = parseDate(jsDateWithoutQuotes);
Logger.log('parsed RFC3339 date using Google\'s code : '+date); // does not return a valid date
var otherFunction = parseDate2(jsDateWithoutQuotes);
Logger.log('parsed RFC3339 date using other code : '+otherFunction); // does return a valid date in my TZ
}
function parseDate(string) {
var parts = string.split('T');
parts[0] = parts[0].replace(/-/g, '/');
return new Date(parts.join(' '));
}
function parseDate2(string) {
var refStr = new Date().toString();
var fus = Number(refStr.substr(refStr.indexOf('GMT')+4,2));
Logger.log('TZ offset = '+fus);
var parts = string.split('T');
parts[0] = parts[0].replace(/-/g, '/');
var t = parts[1].split(':');
return new Date(new Date(parts[0]).setHours(+t[0]+fus,+t[1],0));
}
在对代码进行少量更改后,我设法让Google的代码段工作,但由于JSON转换JS日期对象的方式,时区丢失的问题仍然存在。
下面的新代码和记录器结果:
function testJSONDate() {
Logger.log('starting value : 2016/3/31 12:00:00');
var jsDate = JSON.stringify(new Date("2016/3/31 12:00:00"));// time is 12:00 I'm in GMT+2
Logger.log('JSON.stringify value : '+jsDate);
Logger.log('JSON parse jsDate : '+JSON.parse(jsDate)); // time is 10:00, UTC
var jsDateWithoutQuotesAndMillisecAndZ = jsDate.replace(/"/g,'').split('.')[0];
Logger.log('jsDateWithoutQuotesAndMillisecAndZ = '+jsDateWithoutQuotesAndMillisecAndZ);
var date = parseDate(jsDateWithoutQuotesAndMillisecAndZ);
Logger.log('parsed RFC3339 date using Google\'s code : '+date); // does not return a valid date
var otherFunction = parseDate2(jsDateWithoutQuotesAndMillisecAndZ);
Logger.log('parsed RFC3339 date using other code : '+otherFunction); // does return a valid date in the right tz
}
答案 0 :(得分:1)
你已经从上下文中获得了一些辅助功能。它只是作为一个权宜之计设备来获取特定API(Google Calendar API)返回的字符串,以便在Apps脚本中正确解析。它不是任何一种通用日期转换器。项目成员在filing an issue时将它放在一起,并且该线程中的后续消息指出该函数无法处理的另一个细节。
截至目前,Apps Script中的日期解析器正确解析以下格式:
function testdate() {
Logger.log(new Date("2016/03/31 10:00:00")); // local time
Logger.log(new Date("2016/03/31 10:00:00 +2:00")); // with given offset
Logger.log(new Date("2016-03-31T08:00:00.000Z")); // in UTC
}
请注意,UTC时间戳需要毫秒,但其他时间戳不允许。
使用需要解析但不是上述之一的日期时间字符串,取决于其格式。如果您有2016-03-31T10:00:00
(显然,这是Google Calendar API返回的内容)并且这意味着在当地时间,那么您需要引用的解析函数所做的事情:用空格替换T,用/替换。如果相同的字符串表示UTC时间,则需要在末尾添加.000Z
。等等。