[英]Date comparisons with formatDate in Google Apps Script are 1 day behind
Writing a Google Apps Script that looks at tasks via the Google Tasks API (as an Advanced Service) and checks their due date to see if they are overdue. 编写Google Apps脚本,以通过Google Tasks API(作为高级服务)查看任务,并检查其到期日期,以查看是否过期。 If they are, it should then move them to the current day.
如果是,则应将其移至当天。
I used this code to create this project for keeping Google Tasks up to date: 我使用以下代码创建了此项目,以使Google任务保持最新状态:
Keep Google Tasks Updated 保持Google任务更新
When comparing the current day with the date the task is due, the date the task is due is always one day behind. 当将当前日期与任务到期日进行比较时,任务到期日总是滞后一天。
Looking into it I found that it could have to do with Daylight Savings Time and just one hour off could mean the difference in two days. 研究它,我发现它可能与夏时制有关,仅休息一小时就意味着两天的时间差。 I found this question that had a similar issue, their solution was to use
Session.getScriptTimeZone()
to set the timezone correctly. 我发现这个问题也有类似的问题,他们的解决方案是使用
Session.getScriptTimeZone()
正确设置时区。
However even when I set the timezone using Session.getScriptTimeZone()
it still has the task's due date one day behind. 但是,即使当我使用
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
I noticed that if I log the original task.due
it appears to have the correct date. 我注意到,如果我记录原始
task.due
,则该日期似乎正确。 So something about the formatting is changing the date. 因此,有关格式的某些事情正在更改日期。
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
Changed both "EST"
in formatDate to Session.getScriptTimeZone()
将formatDate中的
"EST"
都更改为Session.getScriptTimeZone()
Removed .valueOf()
for comparison. 删除了
.valueOf()
以进行比较。
Still results in the same issue 仍然导致相同的问题
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
Per Google Tasks API documentation, the task#due
property is an RFC 3339 datetime value, eg "2018-04-11T0:45:26.000Z"
. 根据Google Tasks API文档,
task#due
属性是RFC 3339日期时间值,例如"2018-04-11T0:45:26.000Z"
。 From this string, you can construct a Javascript Date
natively, ie 从这个字符串,您可以本地构造一个Javascript
Date
,即
var taskDueDate = new Date(task.due);
Note that this is equivalent to calling Date.parse()
and thus could be the reason your date comparisons fail, given that Google Apps Script is Javascript 1.6 (ie not ES5+). 请注意,这等效于调用
Date.parse()
,因此,鉴于Google Apps脚本是Javascript 1.6(即非ES5 +),因此日期比较失败的原因。 A possibly better method would be to use a custom parser, given that you know the strict specific format that you will get from task.due
. 假设您知道从
task.due
获得的严格的特定格式,那么使用自定义解析器可能是更好的方法。 One such parser is detailed in this answer . 此答案中有一个这样的解析器。
As @Serge mentions, you should perform this comparison using native Date
objects, and not Strings
: 如@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;
}
for info, this is a small code I use to convert RFC339 time to date object. 对于信息,这是一个小代码,用于将RFC339时间转换为日期对象。 I find it easier to read and understand.
我发现它更容易阅读和理解。
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));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.