处理日期/时间和时区时出现问题

时间:2019-07-02 23:42:34

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

我正在基于链接到Google表单的Google表格中的信息在Google日历上创建活动系列。处理日期是一团糟,我得到的结果不固定。

我在电子表格上有一个字段,其开始日期显示为YYYY/MM/DD
我有一个开始时间为HH:mm的字段
我有一个结束时间为HH:mm

的字段

我了解在内部,时间与年/月/日相关,而DATE也与时间相关(未显示)。

我最终将需要使用DATE中的DATE部分和从可以使用setHours() setMinutes()方法进行更改的时间开始的TIME部分创建日历事件系列。

现在,我的问题是从DATE单元格值创建一个一致的Date对象,因为它似乎发生了怪异的变化。

var ssTZ = SpreadsheetApp.getActive().getSpreadsheetTimeZone();
var SSDate = ss.getRange(6,8).getValue();
var dataStart = Utilities.formatDate(SSDate, 'America/Brasilia' , 'MMMM dd, yyyy 12:00:00 Z');
var dataStartTZ = Utilities.formatDate(SSDate, ssTZ , 'MMMM dd, yyyy 12:00:00 Z');
var dataStartSP = Utilities.formatDate(SSDate, 'America/Sao_Paulo' , 'MMMM dd, yyyy 12:00:00 Z');
var dataStartOS = Utilities.formatDate(SSDate, 'GMT-3' , 'MMMM dd, yyyy 12:00:00 Z');

var date = new Date(dataStart);
var dateTZ = new Date(dataStartTZ);
var dateSP = new Date(dataStartSP);
var dateOS = new Date(dataStartOS);  

Logger.log("Spreadsheet TimeZone: " + ssTZ);
Logger.log(SSDate);
Logger.log("");
Logger.log(date);  
Logger.log(dateTZ);
Logger.log(dateSP);
Logger.log(dateOS);

该代码产生以下日志输出:

  

[19-07-02 20:39:49:780 BRT]电子表格时区:美国/圣保罗(Sao_Paulo)
  [BRT 19-19-02 20:39:49:781] 2016年1月12日星期二00:00:00 GMT-02:00
  [19-07-02 20:39:49:782 BRT]
  [19-07-02 20:39:49:784 BRT] 2016年1月12日星期二10:00:00 GMT-02:00
  [19-07-02 20:39:49:784 BRT] 2016年1月12日星期二12:00:00 GMT-02:00
  [19-07-02 20:39:49:785 BRT] 2016年1月12日星期二12:00:00 GMT-02:00
  [19-07-02 20:39:49:786 BRT] 2016年1月1日星期一13:00:00 GMT-02:00

这没有意义,因为使用的所有时区实际上都应该是相同的。

编辑......添加的信息

按照@TheMaster的要求,来自Text格式变量的日志为:

  Logger.log(dataStart);  
  Logger.log(dataStartTZ);
  Logger.log(dataStartSP);
  Logger.log(dataStartOS);
  

[19-07-03 12:39:33:099 BRT] 2016年1月12日12:00:00 +0000

     

[19-07-03 12:39:33:100 BRT] 2016年1月12日12:00:00 -0200

     

[19-07-03 12:39:33:100 BRT] 2016年1月12日12:00:00 -0200

     

[19-07-03 12:39:33:100 BRT] 2016年1月11日12:00:00 -0300

@ziganotscha解释的前3个输出是由于夏令时更改为GMT-2,而美国/巴西利亚没有被确认为有效时区。

我仍然对为什么将GMT-3指定为时区更改为1月11日感到困惑。

此外,如果我直接从单元格值构建日期对象而不进行格式化,则会得到另一个不同的时间:

var rawDate = new Date(SSDate);
  

19-07-03 12:39:33:101 BRT] rawDate:2016年1月12日星期二00:00:00 GMT-0200(BRST)

我讨厌处理日期...如此令人困惑...

2 个答案:

答案 0 :(得分:1)

关于时区有一个困惑:

您的时区是'America/Sao_Paulo'时区-这就是Logger.log(dateTZ);Logger.log(dateSP);给您相同时间的原因-与您期望的一样。

但是,请记住,圣保罗在一月观察的是巴西利亚夏令时(UTC−02而不是UTC−03),这就是Logger.log(dateSP);和{{1} }。

https://www.timeanddate.com/time/zones/brt

对于dataStart-您为它分配时区Logger.log(dateOS);,这不是时区的定义名称。这就是为什么Apps脚本不接受该值并为您提供'America/Brasilia'时区的原因。

您可以验证formatDate()是否使用Java SimpleDateFormat指定的时区: https://developers.google.com/apps-script/reference/utilities/utilities http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

然后Java使用Olson时区数据库。

https://www.oracle.com/technetwork/java/javase/dst-faq-138158.html#worldwide https://en.wikipedia.org/wiki/Time_in_Brazil

答案 1 :(得分:0)

因此,电子表格时间SSDate

  

2016年1月12日星期二00:00:00 GMT-02:00

即1月12日从格林尼治标准时间-2小时的时区午夜开始。

'America/Brasilia'不是有效的时区,可以忽略。

America/Sao_PaulossTZ作为Utilities.formatDate()的第二个参数都产生相同的有效日期

  

2016年1月12日00:00:00 -0200

当偏移量为GMT-3时,距格林尼治标准时间午夜3时,或距格林尼治标准时间2时区-1小时,则日期为

  

2016年1月11日23:00:00 -0300

即前一天的晚上11点。

问题:

您的日志忽略了日期的时间部分,因为您为所有日期12:00:00 Z而不是HH:mm:ss提供了静态时间格式。

例如,在GMT-3上格式化的最后日期变为

  

2016年1月11日12:00:00 -0300

调用新的Date()会将上面的对象更改为本地时间GMT-2(格林尼治标准时间3,+ 1):

  

2016年1月11日星期一13:00:00 GMT-02:00

请注意,强烈建议不要使用new Date(timestring)进行解析。

参考文献: