在 Apps 脚本中,为什么每当我尝试使用 Date() 进行数学运算时,2023 年 1 月 1 日都会重置为 2022 年 12 月 31 日?

In Apps Script, why does 1/1/2023 gets reset as 12/31/2022 whenever I try to do math using Date()?

提问人:newbie_in_python 提问时间:9/26/2023 最后编辑:Rubénnewbie_in_python 更新时间:9/27/2023 访问量:45

问:

  • 背景:我对应用程序脚本很陌生,我对其他语言有一些初学者知识。我正在尝试进行一些日期数学运算,当用户在单元格中输入两个日期(从和到)时,这会循环发生。我正在尝试迭代每个日期并在某些单元格中输入一些值。

  • 问题:用户输入值为“MM/DD/YYYY”。但是,当使用 2023 年 1 月 1 日时,这将变为“周六 12 月 31 日 16:00:00 GMT-05:00 2022”。此外,减法工作正常(一天中的毫秒数乘以要减去的天数),但加法运算失败并返回相同的值,即“Sat Dec 31 16:00:00 GMT-05:00 2022”。

  • 其他 StackOverflow 主题:我检查了类似的主题,但它们让我添加了试用版 2 和 3,但我的问题是特定于 1/1/yyyy 变成 12/31/yyyy-1。

  • 代码:

function PlayGround() {  
    // setting variables
    var spreadsheet = SpreadsheetApp.getActive();
    const MILLIS_PER_DAY = 1000 * 60 * 60 * 24 * 5; // multiplied by 5 (5 days)
    const now = new Date();

    // trial 1
    const aDate = spreadsheet.getRange('J4').getValue()
    // J4 data type is set to date from the interface, and its value is equal to "1/1/2023"
    Logger.log(new Date(aDate));
    Logger.log(new Date(aDate - MILLIS_PER_DAY));
    Logger.log(new Date(aDate + MILLIS_PER_DAY));
    // function returns
    // 2:56:12 PM   Info    Sat Dec 31 16:00:00 GMT-05:00 2022
    // 2:56:12 PM   Info    Mon Dec 26 16:00:00 GMT-05:00 2022
    // 2:56:12 PM   Info    Sat Dec 31 16:00:00 GMT-05:00 2022

    // trial 2
    var new_d = Utilities.formatDate(new Date(aDate), "EET", "MM/dd/yyyy")
    Logger.log(new Date(new_d));
    Logger.log(new Date(new_d - MILLIS_PER_DAY));
    Logger.log(new Date(new_d + MILLIS_PER_DAY));
    // function returns
    // 3:14:35 PM   Info    Sat Dec 31 00:00:00 GMT-05:00 2022
    // 3:14:35 PM   Info    Wed Dec 31 19:00:00 GMT-05:00 1969
    // 3:14:35 PM   Info    Wed Dec 31 19:00:00 GMT-05:00 1969

    // trial 3
    const d = new Date(aDate);
    Logger.log(d);
    Logger.log(new Date(d.setDate(d.getDate() + 5)));
    Logger.log(new Date(d.setDate(d.getDate() - 5)));
    Logger.log(new Date(d.setDate(d.getDate() - 20)));
    // function returns
    // 3:14:35 PM   Info    Sat Dec 31 16:00:00 GMT-05:00 2022
    // 3:14:35 PM   Info    Thu Jan 05 16:00:00 GMT-05:00 2023
    // 3:14:35 PM   Info    Sat Dec 31 16:00:00 GMT-05:00 2022
    // 3:14:35 PM   Info    Sun Dec 11 16:00:00 GMT-05:00 2022
    // the -5 does not work, but - 20 works!!

    }
javascript 日期时间 google-apps-script google-sheets

评论

0赞 RobG 10/9/2023
使用每天毫秒来增加或减去天数不是一个好主意,因为在遵守夏令时的地方,每年有两天不是 24 小时长。请参阅如何将 1 天添加到当前日期?

答:

1赞 TheAddonDepot 9/26/2023 #1

因为我会检查你的变量的类型。可能是您正在从 Google 表格中检索字符串而不是 Date 实例。检查要从中提取日期的单元格的格式。Trial 1aDate


Trail 2没有任何意义。你实际上是在减去两种不同的类型。就 Javascript 而言,代码中的以下语句:

new_d - MILLIS_PER_DAY

相当于

"12/31/2022" - 86400000

Apps 脚本/Javascript 不会从字符串中推断日期类型。


中的代码实际上正在按预期执行。Apps Script 在后台使用 Javascript 运行时(即 V8),因此您可以继承 Javascript 的 Date 类的所有特性。这意味着,当您使用该函数设置日期时,您可以更改日期的值。因此,每次调用 时都会更新日期的值/状态。Trial 3setDate()dsetDate()

评论

0赞 newbie_in_python 9/27/2023
我也喜欢第三个代码,我会使用它。但是 5 天的减法仍然没有给出预期的结果。谢谢!
0赞 TheAddonDepot 9/28/2023
@newbie_in_python setDate 函数按文档/预期工作。它不会按照您期望的方式工作。参见 setdate() 的 MDN 文档
1赞 Cooper 9/27/2023 #2

试试这个:

function PlayGround() {
  const ss = SpreadsheetApp.getActive();
  const day = 1000 * 60 * 60 * 24;
  const dt = new Date();
  ss.getRange("J4").setValue(new Date()).setNumberFormat("MM dd, yyyy HH:mm:ss");
  const aDate = new Date(ss.getRange('J4').getValue());
  Logger.log(new Date(aDate));
  Logger.log(new Date(aDate.valueOf() - day));
  Logger.log(new Date(aDate.valueOf() + day));
  var newds = Utilities.formatDate(new Date(aDate), "GMT-7", "MM/dd/yyyy")
  Logger.log(new Date(newds));
  let newd = new Date(newds);
  Logger.log(new Date(newd.valueOf() - day));
  Logger.log(new Date(newd.valueOf() + day));
  const d = new Date(aDate);
  Logger.log(d);
  Logger.log(new Date(d.setDate(d.getDate() + 1)));
  Logger.log(new Date(d.setDate(d.getDate() - 1)));
  Logger.log(new Date(d.setDate(d.getDate() - 20)))
}

Execution log
4:51:57 PM  Notice  Execution started
4:51:57 PM  Info    Tue Sep 26 16:51:57 GMT-06:00 2023
4:51:57 PM  Info    Mon Sep 25 16:51:57 GMT-06:00 2023
4:51:57 PM  Info    Wed Sep 27 16:51:57 GMT-06:00 2023
4:51:57 PM  Info    Tue Sep 26 00:00:00 GMT-06:00 2023
4:51:57 PM  Info    Mon Sep 25 00:00:00 GMT-06:00 2023
4:51:57 PM  Info    Wed Sep 27 00:00:00 GMT-06:00 2023
4:51:57 PM  Info    Tue Sep 26 16:51:57 GMT-06:00 2023
4:51:57 PM  Info    Wed Sep 27 16:51:57 GMT-06:00 2023
4:51:57 PM  Info    Tue Sep 26 16:51:57 GMT-06:00 2023
4:51:57 PM  Info    Wed Sep 06 16:51:57 GMT-06:00 2023
4:51:59 PM  Notice  Execution completed

评论

0赞 newbie_in_python 9/27/2023
我之前切换了值设置,因为一旦设置了格式,值就会更改为今天的日期。但是我发现了问题所在,提示在您的代码中,“GMT-7”。我把它改成我的时区,它起作用了,谢谢!