【问题标题】:Date comparisons with formatDate in Google Apps Script are 1 day behind与 Google Apps 脚本中 formatDate 的日期比较晚了 1 天
【发布时间】:2018-04-10 17:11:57
【问题描述】:

编写一个 Google Apps 脚本,通过 Google Tasks API(作为一项高级服务)查看任务并检查它们的截止日期以查看它们是否过期。如果是,则应将它们移至当前日期。

已完成的项目

我使用这段代码创建了这个项目,以使 Google Tasks 保持最新状态:

Keep Google Tasks Updated

问题

当比较当前日期和任务到期日期时,任务到期日期总是晚一天。

研究

调查后我发现这可能与夏令时有关,而仅仅休息一小时可能意味着两天的差异。我发现this question 有类似的问题,他们的解决方案是使用Session.getScriptTimeZone() 正确设置时区。

但是,即使我使用Session.getScriptTimeZone() 设置时区,它仍然比任务的截止日期晚了一天。

代码

function checkOverdue(t) {
  var today = Utilities.formatDate(new Date(), "EST", "MM/dd/yyyy");
  //var today = new Date();
  var tasks = t;
  if (tasks.items) {
    for (var i = 0; i < tasks.items.length; i++) {
      var task = tasks.items[i];
      if (task.due) {
        var taskDue = Utilities.formatDate(new Date(task.due), "EST", "MM/dd/yyyy");
        Logger.log('"%s", Comparing "%s" to "%s"',
                 task.title, taskDue, today);
        if (taskDue.valueOf() < today.valueOf()) {
          Logger.log('Task with title "%s" is past due', task.title);
        }
      }
    }
  } else {
    Logger.log('No tasks found.');
  }
}

日志

[18-04-10 13:12:33:927 EDT] "Create Bio presentation", Comparing "04/09/2018" to "04/10/2018"
[18-04-10 13:12:33:928 EDT] Task with title "Create Bio presentation" is past due
[18-04-10 13:12:33:929 EDT] "Bio Presentation", Comparing "04/10/2018" to "04/10/2018"
[18-04-10 13:12:33:930 EDT] "Matrix HW", Comparing "04/09/2018" to "04/10/2018"
[18-04-10 13:12:33:930 EDT] Task with title "Matrix HW" is past due

=== [更新] ===

我注意到,如果我记录原始的task.due,它似乎有正确的日期。所以关于格式的一些事情正在改变日期。

新代码

function checkOverdue(t) {
  var today = Utilities.formatDate(new Date(), "EST", "MM/dd/yyyy");
  //var today = new Date();
  var tasks = t;
  if (tasks.items) {
    for (var i = 0; i < tasks.items.length; i++) {
      var task = tasks.items[i];
      if (task.due) {
        var taskDue = Utilities.formatDate(new Date(task.due), "EST", "MM/dd/yyyy");
        Logger.log('"%s", Comparing TaskDue: "%s" to today: "%s", task.due "%s"', task.title, taskDue, today, task.due);
        if (taskDue.valueOf() < today.valueOf()) {
          Logger.log('Task with title "%s" is past due', task.title);
        }
      }
    }
  } else {
    Logger.log('No tasks found.');
  }
}

新日志

[18-04-10 14:15:17:628 EDT] "Create Bio presentation", Comparing TaskDue: "04/09/2018" to today: "04/10/2018", task.due "2018-04-10T00:00:00.000Z"
[18-04-10 14:15:17:629 EDT] Task with title "Create Bio presentation" is past due
[18-04-10 14:15:17:630 EDT] "Bio Presentation", Comparing TaskDue: "04/10/2018" to today: "04/10/2018", task.due "2018-04-11T00:00:00.000Z"
[18-04-10 14:15:17:631 EDT] "Matrix HW", Comparing TaskDue: "04/09/2018" to today: "04/10/2018", task.due "2018-04-10T00:00:00.000Z"
[18-04-10 14:15:17:631 EDT] Task with title "Matrix HW" is past due

=== [更新 2] ===

将 formatDate 中的 "EST" 都更改为 Session.getScriptTimeZone()

删除 .valueOf() 以进行比较。

仍然导致同样的问题

新代码

function checkOverdue(t) {
  var today = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "MM/dd/yyyy");
  //var today = new Date();
  var tasks = t;
  if (tasks.items) {
    for (var i = 0; i < tasks.items.length; i++) {
      var task = tasks.items[i];
      if (task.due) {
        var taskDue = Utilities.formatDate(new Date(task.due), Session.getScriptTimeZone(), "MM/dd/yyyy");
        Logger.log('"%s", Comparing TaskDue: "%s" to today: "%s", task.due "%s"', task.title, taskDue, today, task.due);
        if (taskDue < today) {
          Logger.log('Task with title "%s" is past due', task.title);
        }
      }
    }
  } else {
    Logger.log('No tasks found.');
  }
}

新日志

[18-04-10 15:21:01:988 EDT] "Create Bio presentation", Comparing TaskDue: "04/09/2018" to today: "04/10/2018", task.due "2018-04-10T00:00:00.000Z"
[18-04-10 15:21:01:988 EDT] Task with title "Create Bio presentation" is past due
[18-04-10 15:21:01:990 EDT] "Bio Presentation", Comparing TaskDue: "04/10/2018" to today: "04/10/2018", task.due "2018-04-11T00:00:00.000Z"
[18-04-10 15:21:01:991 EDT] "Matrix HW", Comparing TaskDue: "04/09/2018" to today: "04/10/2018", task.due "2018-04-10T00:00:00.000Z"
[18-04-10 15:21:01:991 EDT] Task with title "Matrix HW" is past due

【问题讨论】:

  • 为什么您仍在代码的某些部分使用硬编码的“EST”时区?您应该在任何地方替换它以获得一致的结果。
  • 另外,您不应该将日期转换为字符串,日期方法显然不适用于字符串,因此当您在比较中使用 valueOf() 时,它没有意义。留下日期,因为日期和事情应该可以工作。
  • 非常感谢@Sergeinsas,我修改了代码,但仍然得到相同的结果。我在更新 2 中展示了我在上述问题中所做的事情
  • @Sergeinsas 更乱我注意到 task.due 是一个字符串,而不是一个日期。因此,如果它不是字符串,则比较似乎不起作用。这是一个问题,因为将其转换为字符串时会出现错误的日期
  • 将 task.due 转换为日期对象,这是最好的方法。如果您需要有关如何实现这一目标的帮助,请立即联系我们

标签: date google-apps-script date-comparison google-tasks-api google-tasks


【解决方案1】:

根据 Google Tasks API 文档,task#due property 是一个 RFC 3339 日期时间值,例如"2018-04-11T0:45:26.000Z"。 从此字符串中,您可以原生构造 Javascript Date,即

var taskDueDate = new Date(task.due);

请注意,这相当于调用 Date.parse(),因此可能是您的日期比较失败的原因,因为 Google Apps 脚本是 Javascript 1.6(即不是 ES5+)。一个可能更好的方法是使用自定义解析器,因为您知道从task.due 获得的严格的特定格式。 this answer 中详细介绍了一种这样的解析器。

正如@Serge 所提到的,您应该使用本机Date 对象而不是Strings 来执行此比较:

function isOverdue(task) {
  if(!task.due)
    return false;

  var now = new Date();
  var endOfToday = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + 1)); // Also known as start of tomorrow ;)
  var taskDueDate = myFunctionToConvertRFC3339StringToJSDate(task.due);
  return taskDueDate < endOfToday;
}

【讨论】:

  • 真的很感激!
【解决方案2】:

对于信息,这是我用来将 RFC339 时间转换为日期对象的小代码。 我发现它更容易阅读和理解。

function parseDate_RFC3339(string) {
  var refStr = new Date().toString();
  Logger.log('refStr = '+refStr);
  var tzOffset = Number(refStr.substr(refStr.indexOf('GMT')+4,2));
  Logger.log('TZ offset = '+tzOffset);
  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]+tzOffset,+t[1],0));
}

【讨论】:

  • 非常感谢!真的有帮助
  • 感谢您的接受,但我认为接受的答案应该是 tehhowch 的答案,我的代码只提供了一种简单的方法来获得他的建议。
  • 很公平,我完成了我的代码并归功于你们俩。如果您愿意,可以检查一下。我在问题中链接了它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多