【问题标题】:Javascript Date() in ReactJS: How to accept input as GMT/UTC and convert it into ISO string?ReactJS 中的 Javascript Date():如何接受输入为 GMT/UTC 并将其转换为 ISO 字符串?
【发布时间】:2017-04-28 00:08:12
【问题描述】:

当前输入是"12 09 2016 00:00:00",应该假设它是作为格林威治标准时间日期和时间输入的。但相反,它接受它作为本地并转换它。而当它转为ISOString()时,它会将其转换为GMT,并加上时差。

如何输入"12 09 2016 00:00:00" 格式,将其作为GMT/UTC,然后通过.toISOString() 将其转换为ISO 格式"2016-12-09T00:00:00.000Z"

var dateAndTime = new Date("12 09 2016 00:00:00")
//Returns: "Fri Dec 09 2016 00:00:00 GMT-0800 (PST)"
//Want it to return: "Fri Dec 09 2016 00:00:00 (GMT)"

var gmtDateAndTime = dateAndTime.toISOString();
//Returns: "2016-12-09T08:00:00.000Z"
//Want it to return: "2016-12-09T00:00:00.000Z"

谢谢你,一定会投票并接受答案。

【问题讨论】:

    标签: javascript date datetime reactjs


    【解决方案1】:

    您需要使用另一个 Date 构造函数。默认构造函数在您的本地时区创建时间。

    替换这个:

    var dateAndTime = new Date("12 09 2016 00:00:00")
    

    有了这个:

    var dateAndTime = new Date(Date.UTC(2016, 09, 12, 0, 0, 0));
    

    如果您无法手动将字符串 ("12 09 2016 00:00:00") 转换为单独的 UTC 参数,您可以使用它(但在 IE 中尤其不可靠):

    var utcDate = Date.parse("12 09 2016 00:00:00");
    

    【讨论】:

    • 不要使用 Date.parse(或 Date 构造函数)来解析字符串,因为它在很大程度上取决于实现。月份索引为零,因此应使用 new Date(Date.UTC(2016, 8, 12)) 转换“12 09 2016 00:00:00”。请注意,如果未提供时间值,它们默认为 0(因此毫秒默认为零,即使您没有提供值)。 ;-)
    • Date.parse("12 09 2016 00:00:00") 在 Safari 中返回 NaN。如果完全解析,它将返回一个数字,而不是日期,因此utcDate.getUTCFullYear() 将引发错误。
    • @RobG 那么有没有更好的选择,而无需手动将我的字符串转换为单独的 UTC 参数,并且只能接受 "12 09 2016 00:00:00" 作为输入?
    • 并非如此。日期字符串可以有许多不同的格式,因此如果您只是将其提供给解析器而不指定格式,那么您就只能靠运气了。您自己的函数只需要 3 行代码,或者您可以使用包含数千行代码的库(例如 fecha.jsmoment.js),但您必须指定格式。
    【解决方案2】:

    不要使用 Date 来解析偶然日期字符串。 Date.parse 仅在输入为 ISO8061 字符串时以明确定义的方式工作。

    来自 ECMA 5 标准中的“15.9.4.2 Date.parse”:

    函数首先尝试根据日期时间字符串格式(15.9.1.15)中调用的规则解析字符串的格式。如果字符串不符合该格式,则函数可能会退回到任何特定于实现的启发式或特定于实现的日期格式。

    从 15.9.1.15 开始,识别的字符串格式为

    YYYY-MM-DDTHH:mm:ss.sssZ

    它看起来很像你想要到达的 ISO 字符串,而不是开头。

    解决问题的其他选择可能包括:

    1. 编写您自己的函数来解析用户输入字符串。根据用户区域设置,“12 09 2016”可能表示“2016 年 12 月 9 日”或“2016 年 9 月 12 日”的问题。

    2. 使用日期和时间库。在关于此类库的 SO 答案中经常提到 Moment.js。

    3. 使用日期选择器的输出或数据库中经过验证的数据。避免与区域设置相关的格式问题。

    4. 如果输入字符串绝对保证为“mm dd yyyy hh:mm:ss”格式,则可以选择将硬代码转换为 ISO8061 格式无需解析,例如使用

      function isoFromZ( str) {
         return str.substr(6,4) + "-" +
                str.substr(0,2) + "-" +
                str.substr(3,2) + "T" + 
                str.substring(11) + ".000Z";
      }
      

    总之,在创建Date 对象之前 从自定义输入字符串中提取UTC 日期和时间组件。如果提取生成 ISO8061 日期字符串,则可以将其作为参数直接传递给 Date 构造函数。

    【讨论】:

      【解决方案3】:

      如何以“12 09 2016 00:00:00”格式输入,将其视为 GMT/UTC,并执行 .toISOString() 将其转换为 ISO 格式, “2016-12-09T00:00:00.000Z”?

      看来你只是想重新格式化字符串,所以就这样做吧:

      // Reformat string in MM DD YYYY HH:mm:ss format to 
      // ISO 8601 UTC
      function formatDateStringISO(s) {
        var b = s.split(/\D/);
        return b[2] + '-' + b[0] + '-' + b[1] +
               'T' + b[3] + ':' + b[4] + ':' + b[5] + '.000Z';
      }
      
      console.log(formatDateStringISO('12 09 2016 00:00:00'))

      如果要将字符串解析为 Date 然后输出 ISO 8601 格式字符串,请执行以下操作:

      // Parse string in MM DD YYYY HH:mm:ss format
      // If date string is invalid, returns an invalid Date
      function parseDateAsUTC(s) {
        var b = s.split(/\D/);
        var d = new Date(Date.UTC(b[2], --b[0], b[1], b[3], b[4], b[5]));
        // Validate date
        return d && d.getMonth() == b[0]? d : new Date(NaN);
      }
      
      // Valid date             Invalid date
      ['12 09 2016 00:00:00', '12 34 2016 00:00:00'].forEach(function(s) {
        var d = parseDateAsUTC(s);
        console.log(s + ' => ' + d[isNaN(d)? 'toString' : 'toISOString']());
      });

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-02
        • 1970-01-01
        相关资源
        最近更新 更多