生成类似于Google Tasks API的RFC 3339时间戳?

54

我在开发一个与Google任务同步的应用程序。作为同步的一部分,我想比较本地任务和API任务,并查看哪个任务最近更改。

每个来自Google API的任务都包含一个名为updated的属性,它长这样:

2011-08-30T13:22:53.108Z

现在我想生成一个类似的时间戳,以便每次在我的应用程序上更新任务时都会设置一个新的updated值。为了生成RFC 3339时间戳,我正在使用 - http://cbas.pandion.im/2009/10/generating-rfc-3339-timestamps-in.html,它会生成类似这样的内容:

2011-08-30T09:30:16.768-04:00
问题在于,API日期总是“大于”本地日期,即使本地日期更新了。我猜想这与两者之间的不同格式有关。
这里有两个日期,上面的来自Google Tasks API(约10分钟前),下面的是一分钟前本地生成的。当进行比较时,告诉我上面那个更大。
2011-08-30T13:22:53.108Z
2011-08-30T09:41:00.735-04:00

我的格式有问题吗?我在这里做错了什么?非常感谢您对此的任何帮助。

8个回答

84

看起来已经给出了很多复杂的答案,但这个方法完全可行,不是吗?

new Date().toISOString()

1
toISOString() 给出的日期表示中,日和月份的数字与 RFC3339 标准相比是颠倒的。 - Luca Di Liello
1
它包括秒的分数:2019-03-27T15:12:47.921Z。您需要将它们去掉。 - Ivan Yarych
9
RFC3339规定了日期格式为YYYY-MM-DD,这也是toISOString()输出的格式。 - Trenton D. Adams
2
@IvanYarych 毫秒是有效的ISO8601/RFC3339格式,只是很少使用。任何按照规范解析的内容都应该可以正常工作。 - Trenton D. Adams

53

ISO格式化要求,因此new Date().toISOString()将给出该形式。根据我的阅读,可能需要进行shimmed操作:

/* use a function for the exact format desired... */
function ISODateString(d){
 function pad(n){return n<10 ? '0'+n : n}
 return d.getUTCFullYear()+'-'
      + pad(d.getUTCMonth()+1)+'-'
      + pad(d.getUTCDate())+'T'
      + pad(d.getUTCHours())+':'
      + pad(d.getUTCMinutes())+':'
      + pad(d.getUTCSeconds())+'Z'}

var d = new Date();
print(ISODateString(d)); // prints something like 2009-09-28T19:03:12Z

来源:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date


这是JavaScript中有关日期和时间的内置对象。它允许您创建表示日期和时间的对象,使用各种方法来操作这些对象。例如,您可以获取当前日期、设置特定日期、计算两个日期之间的时间差等等。请注意,JavaScript中的日期对象基于UTC(协调世界时)。

2
哇,谢谢。我可能有点混淆了,因为谷歌说在拉取任务时要传递一个“RFC 3339时间戳”作为updatedMin参数。 - levi
1
RFC 3339是ISO 8601的一个狭窄子集。阅读RFC可以很好地解释为什么定义子集是有帮助的。几乎没有人使用或实现ISO 8601的所有选项,因此当人们说“ISO格式”时,他们通常指的是单个特定格式,经常是RFC 3339关注的那个。 - Beni Cherniavsky-Paskin

13

我发现 moment.js 库在 JavaScript 中处理时间很方便。 moment().format() 可以生成一个符合 Google API datetime 格式要求的时间戳。或者,为了不依赖默认格式是否正确,

moment().format("YYYY-MM-DDTHH:mm:ssZ")

所有字符串选项(包括如果需要的小数秒):http://momentjs.com/docs/#/displaying/format/


2
Z字符表示时区,不能直接使用。 - Baryon Lee
19
moment().toISOString() // 2013-02-04T22:44:30.652Z翻译:moment().toISOString() // 2013年02月04日22点44分30.652秒(格林威治标准时间) - Baryon Lee
如果语言本身提供了某些功能,使用第三方库应该是最后的选择。 - Trenton D. Adams

3

使用 date-fns,这非常优雅:

import { formatRFC3339 } from 'date-fns'

const result = formatRFC3339(new Date(2019, 8, 18, 19, 0, 52))
//=> '2019-09-18T19:00:52Z'

来源:


对我来说很好用,这里有文档:https://date-fns.org/v2.23.0/docs/formatRFC3339 - dkocich

3

1

试试这个:

Date.prototype.setRFC3339 = function(dString) {
    var utcOffset, offsetSplitChar;
    var offsetMultiplier = 1;
    var dateTime = dString.split("T");
    var date = dateTime[0].split("-");
    var time = dateTime[1].split(":");
    var offsetField = time[time.length - 1];
    var offsetString;
    offsetFieldIdentifier = offsetField.charAt(offsetField.length - 1);
    if (offsetFieldIdentifier == "Z") {
        utcOffset = 0;
        time[time.length - 1] = offsetField.substr(0, offsetField.length - 2);
    } else {
        if (offsetField[offsetField.length - 1].indexOf("+") != -1) {
            offsetSplitChar = "+";
            offsetMultiplier = 1;
        } else {
            offsetSplitChar = "-";
            offsetMultiplier = -1;
        }
        offsetString = offsetField.split(offsetSplitChar);
        time[time.length - 1] == offsetString[0];
        offsetString = offsetString[1].split(":");
        utcOffset = (offsetString[0] * 60) + offsetString[1];
        utcOffset = utcOffset * 60 * 1000;
    }

    this.setTime(Date.UTC(date[0], date[1] - 1, date[2], time[0], time[1], time[2]) + (utcOffset * offsetMultiplier));
    return this;
};

来源: http://blog.toppingdesign.com/2009/08/13/fast-rfc-3339-date-processing-in-javascript/


1

第一个日期后面的Z表示它是UTC(协调世界时)时间,如果没有Z,则使用本地(计算机)时间,这可能会相差数个时区。

请参见:http://en.wikipedia.org/wiki/UTC


-4

看起来更漂亮: new Date().toISOString().split('.')[0] + 'Z'


2
他们要求 RFC 输出,而不是一些模糊的“漂亮”输出定义;因此这是离题的。 - Trenton D. Adams

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接