【问题标题】:Google Sheets keep Time format with Datetime dataGoogle 表格使用日期时间数据保留时间格式
【发布时间】:2021-12-14 17:52:29
【问题描述】:

详情

在我的 Google 表格中,我有一列已格式化为 03:59 PM 格式。当我在其中插入时间时,数据会自动正确格式化为00:00 AM,但不是正确的日期,因为它说它是从 1899 年开始的。

当我首先插入数据并指定日期时,它会覆盖列00:00 AM 格式,而是插入MMM DD YYYY 00:00 格式,月份为文本,日期和年份为数字,没有上午或下午。当我再次使用03:59 PM 格式手动格式化单元格(或整列)时,它显示正确的时间格式并且具有正确的日期。

我目前正在通过带有 Gspread 模块的 Python 脚本添加数据。这使我可以使用指定的模式对其进行格式化。数据作为日期时间字符串添加到单元格中,然后更改单元格的格式,但紧接着该单元格再次被覆盖为hh:mm AM/PM 模式格式:{"numberFormat": {"type": "DATE_TIME", "pattern": "hh:mm AM/PM"}}

因此,现在仅在手动输入数据时,它不会像 Python 脚本那样立即被覆盖。

问题

如何在不覆盖列的00:00 AM 格式的情况下将数据插入到具有日期时间属性(或至少包含日期和时间)的工作表中?

试过了:

  • 格式化整列,然后输入数据
  • 输入各种格式的数据,例如 12/12/2021 3:00 PM,它添加了 PM,但仍只覆盖时间格式。

【问题讨论】:

  • 为什么不稍后输入和格式化?
  • 因为我想每天自动在这张表中添加一个条目,而不是手动重新格式化。
  • 您能解释一下automatically 的意思吗?如果输入来自 Python,onEdit 将不起作用
  • 刚刚编辑了原始问题,给出了更多细节。我对应用程序脚本不太熟悉,但 onEdit 可能会奏效。将不得不弄清楚如何只编辑手动数据,而不是重新格式化单个单元格两次。

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


【解决方案1】:

这是一个相当笨拙的解决方案,但它可能对你有用:

function onEdit(e) {
  if (e.range.columnStart != 2) return; // if it's not column B do nothing

  var value = e.range.getDisplayValue();
  if (value.length < 12 && value.length > 0) {
    var tz = Session.getTimeZone();
    var today = Utilities.formatDate(new Date(), tz, 'yyyy-MM-dd');
    var date = Utilities.formatDate(new Date(today + ' ' + value), tz, 'yyyy-MM-dd hh:mm a');
    e.range.setValue(date);
    e.range.setNumberFormat('hh:mm am/pm');
  }
}

它为任何少于 12 个字母的“日期”设置当前的年、月和日(假设这个“日期”是一个时间)。

您可能想将最后一行e.range.setNumberFormat('hh:mm am/pm'); 移出{}。在这种情况下,它会将所有输入的“日期”格式化为时间hh:mm

function onEdit(e) {
  if (e.range.columnStart != 2) return; // if it's not column B do nothing

  var value = e.range.getDisplayValue();
  if (value.length < 12 && value.length > 0) {
    var tz = Session.getTimeZone();
    var today = Utilities.formatDate(new Date(), tz, 'yyyy-MM-dd a');
    var date = Utilities.formatDate(new Date(today + ' ' + value), tz, 'yyyy-MM-dd hh:mm a');
    e.range.setValue(date);
  }
  e.range.setNumberFormat('hh:mm am/pm');
}

更新

以下是相同解决方案的一些不太笨拙的变体:

function onEdit(e) {
  if (e.range.columnStart != 2) return; // if it's not column B do nothing

  var date = e.range.getValue();

  if (date.getFullYear() < 1990) {
    var time = e.range.getDisplayValue();
    var tz = Session.getTimeZone();
    var today = Utilities.formatDate(new Date(), tz, 'yyyy-MM-dd a');
    var new_date = Utilities.formatDate(new Date(today + ' ' + time), tz, 'yyyy-MM-dd hh:mm');
    e.range.setValue(new_date);
  }

  e.range.setNumberFormat('hh:mm am/pm');
}

如果自动分配的年份小于 1990,则将年、月、日更改为当前日期。

【讨论】:

  • 我认为您根本不需要格式化日期。只需setValue(new Date()).setNumberFormat('hh:mm am/pm')
  • 我认为这样的事情会起作用:const [h, m, s] = ['Hours','Minutes','Seconds'].map(s =&gt; e.range.getValue()[`get${s}`]()); e.range.setValue(new Date(new Date().setHours(h,m,s,0)))
  • 我的意思是我们没有尝试在原始日期设置FullYear(虽然这是可能的),我的代码正在尝试将3:00[3h,00m,0s] 复制到new date(),如果时区不是问题,即在原始日期至少保留 h,m,s。如果 tz 发生变化,我们需要将会话 tz 修复为电子表格 tz。
  • @TheMaster Well。现在我懂了。它以更简洁的方式更改 hh:mm (而不是年份)。但看起来我在时区方面遇到了仓促的麻烦(我的时区莫斯科,俄罗斯 GMT+03,我不知道夏令时,可能它也在那里)。我刚刚尝试了您的代码pastebin.com/qZa0exeh(在新电子表格中),当我输入“22:22”时,它会得到日期“2021 年 12 月 15 日 22:51:43”(时间偏移 29 分 43 秒!可能它与 1900 年代左右俄罗斯帝国的日期有关)。这正是我更喜欢使用字符串的原因。如果您能告诉我应该如何正确完成,我将不胜感激。
  • 我同意在这种情况下这可能是最简单的,但通常,您应该避免使用字符串作为日期。即使在这种情况下,我也可能会建议使用日期。我认为可能使用基于日期的偏移量new Date(1899,11,30) 将适用于所有情况,但我没有测试它,我也不想浪费你的时间。如果我进行测试并找到方法,我会添加评论或编辑/添加另一个答案。
【解决方案2】:

清除B2:BB2

={A2:A}

然后您可以在A2:A 中输入完整日期,并在B2:B 中查看预期格式

  • 原始数据:A2:A
  • 介绍:B2:B

您还可以将原始数据和演示文稿分开到单独的工作表中。

【讨论】:

  • 这不是我想要的,因为这张表已经用于数据输入和呈现,而不是原始数据,所以在这种情况下 2 列并不理想。
  • @Nuxurious 既然你标记了脚本,我猜你打算使用onEdit 脚本。您能提供到目前为止您在脚本方面的尝试吗?
  • 脚本中还没有任何内容,但在 Python 自动化中,我能够在插入日期时间字符串时使用正确的模式重新格式化。这样,它会插入字符串,更改列的格式,但随后会立即重新格式化单元格。但这还不是手动输入的情况。
猜你喜欢
  • 2021-11-10
  • 2021-01-30
  • 2021-07-08
  • 2022-11-25
  • 1970-01-01
  • 2019-07-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多