【问题标题】:Weird inconsistencies in writing a date into Google sheets将日期写入 Google 表格时出现奇怪的不一致
【发布时间】:2023-03-22 19:50:01
【问题描述】:

在将构建的日期写入谷歌表格时,我看到了奇怪的不一致和差异,一旦稍后检索表格值,它们并不总是转换为日期对象。

通过构造日期,我的意思是它们是通过将较小的日期、月份和时间字符串组合成一个字符串“01/02/1991 00:00:00”来创建的。然后使用 .setValues() 将它们写入工作表。然后在工作完成后,我使用 .getValues() 检索数组,只发现偶尔会以字符串值的形式检索这些日期,其中绝大多数是日期对象。

最初,我没有填充值,但现在我添加(在字符串内)前导 0。这已经解决了一些地方但不是所有地方的问题。

以下是我如何创建最终使用 .setValues 写入的数组的一些摘录

  var date = data_range[i][header_date].toString()
  var day = parseInt(date.slice(6,8),10)
  var month =  parseInt(date.slice(4,6),10)
  var year =  parseInt(date.slice(0,4),10)

  organised_data[organised_data_index].data = organised_data[organised_data_index].data.concat(data_range[i].slice(header_data, header_data+int_entries))

  var datetime_array = []
  for (var k = 0; k< minutes_array.length; k++){
    datetime_array[k] = pad(day,2) + "/" + pad(month,2) + "/"+ year + " " + pad(parseInt(minutes_array[k]/60),2)+ ":" + pad((minutes_array[k] % 60),2) + ":00" 
  }
  organised_data[organised_data_index].datestamp = organised_data[organised_data_index].datestamp.concat(datetime_array) 

这是我在调试中看到的: https://i.imgur.com/OTT296s.png

这是我在工作表中看到的内容: https://i.imgur.com/hDvqGP3.png

有没有其他人遇到过这些问题,我做错了吗?

所以对于任何人问我为什么要这样写我的日期,这是因为脚本将在国家之间传递,而且我注意到本地化发生了变化,因此在 javascript 中使用日期对象变得非常糟糕。我选择创建字符串本身,因为数据与时区无关。我们可以将我的问题的那一面视为约束吗?

谢谢大家,这可要了我的命。

【问题讨论】:

  • 欢迎。其他人可能马上就知道这个问题的答案。就我而言,我需要查看电子表格和代码。请您分享您的电子表格副本(不包括任何私人或机密信息)吗?
  • 寻求与此类似帮助的问题应包括minimal reproducible example
  • 时间为00:00:000的情况下是否总是出现不一致?很高兴看到您如何设置和获取值。
  • 嗨 Wholemeal - 这是一个有趣的错误。当我使用您的“dd/MM/YYYY hh:mm:ss”格式生成 15,000 个字符串并将它们放在一张表中时,当我读回它们时,其中有超过 9,000 个作为字符串而不是日期对象返回。当我使用“MMM dd, YYYY hh:mm:ss”格式时,我得到了 15,000 个日期。如果我得到更明确的答案,我会更新我的答案。您能否提供更多自己的代码和工作表数据以更好地了解您在做什么?您是否尝试过不同的字符串格式?你如何保持“时区不可知论”?你试过 Date.UTC() 吗?
  • 你的工作表location settings是什么?

标签: google-apps-script google-sheets google-sheets-api


【解决方案1】:

我实际上并没有看到你的不一致我希望我能看到你所有的代码。

Date 对象的另一个问题是不允许使用 google.script.run 传递 Date() 对象,这将导致整个对象丢失其数据。出于这个原因,我使用了这样的函数来生成可以轻松传递的日期字符串,然后用作服务器上日期的构造函数。在某些项目中,我喜欢完全消除时区,只是假设电子表格的时区与 WebApp 用户相同,尽管通常情况并非如此。

function formatDateTime(dt){
  if(dt && Object.prototype.toString.call(dt) === '[object Date]'){
    var M=dt.getMonth()+1;
    var d=dt.getDate();
    var h=dt.getHours();
    var m=dt.getMinutes();
    var s=dt.getSeconds();
    var MM=(M<10)?String('0'+M):String(M);
    var dd=(d<10)?String('0'+d):String(d);
    var hh=(h<10)?String('0'+h):String(h);
    var mm=(m<10)?String('0'+m):String(m);
    var ss=(s<10)?String('0'+s):String(s);
    var ds=dt.getFullYear() + '-' + MM + '-' + dd + 'T' + hh + ':' + mm;
    return ds;
  }else{
    throw("Invalid Parameter Type in formatDateTime Code.gs.  Parameter is not a date.");
  }
}

Reference

【讨论】:

  • 您好库珀,感谢您的回复。在调试图像中可以看到不一致,该图像显示了日期和值数组的调试扩展。大约有 15,000 个条目 - 但有时您会看到其中一个日期对象只是一个字符串。
  • @Wholemean 然后修复该字符串而不是解决它。
【解决方案2】:

在表格中将字符串自动转换为日期对象对我来说也是几个错误的根源(虽然不是您的特定错误!)。

由于您已经编写了在字符串和日期之间进行转换的辅助函数,我建议您完全消除工作表中的日期对象,使用Range.setNumberFormat("@") 始终将日期视为字符串。

【讨论】:

  • 我不同意。日期应该是日期,并在整个过程中保持为日期。表格不会将字符串转换为日期对象。电子表格日期转换为 JavaScript 日期。就像 JavaScript 类型一样,也有电子表格类型。就像typeof date=type(A2)=ISDATE(A2) 一样。电子表格日期类型仅转换为 js 日期类型。将所有内容一揽子转换为字符串,仅仅因为数据输入中的某个人没有正确输入日期是不可接受的,IMO。
  • @TheMaster - 我从 OP 的日期字符串格式 ("dd/MM/YYYY hh:mm:ss") 中得到了非常有趣的结果 - 这种非标准日期字符串确实有问题.彻底调查后,我会更新我的答案。 typeof date 假设 date 是一个 Date 对象将返回 "object"=type(A2) 返回代码 1 用于数字(因为它存储了 Date.getTime() 值)。这些东西不容易跟踪,虽然我原则上同意我们应该尝试并坚持内置功能,但我认为根据具体情况使用纯字符串是一种有效的替代方案。
  • ISDATE(A1) 应确认电子表格中的日期类型,dt instanceof Date 应确认日期 js 对象 dt。我不认为表格是错误的。它可以处理非标准日期字符串。
猜你喜欢
  • 2019-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-21
  • 2015-03-05
  • 2015-02-21
  • 1970-01-01
相关资源
最近更新 更多