Chrome和Firefox中的Date.toString和Date.toLocaleDateString是否不一致?

时间:2018-10-25 15:58:08

标签: javascript date datetime browser

所以我想显示一个日期,而不要特别注意一天中的时间。日期也没有任何混乱。我正在使用MacBook Pro。

如果我在Date构造函数中输入数字,则会显示以下内容。

例如,我想显示1993年4月28日。

var objDate = new Date(1993, 3, 28),
    dateString = objDate.toLocaleDateString(undefined, {
        weekday: "long",
        year: "numeric",
        month: "long",
        day: "numeric",
        hour: "numeric",
        timeZoneName: 'long'
    });

    console.log(dateString)
    //Chrome Outputs: "Wednesday, April 28, 1993, 12 AM Mountain Daylight Time"
    //Firefox Outpus: "Tuesday, April 27, 1993, 6 PM Mountain Daylight Time"

    let nowDate = new Date(1993, 3, 28);
    console.log(nowDate.toString())
    //Chrome Outputs: "Wed Apr 28 1993 00:00:00 GMT-0600 (Mountain Daylight Time)"
    //Firefox Outputs: "Wed Apr 28 1993 00:00:00 GMT+0000 (UTC)"

    console.log(nowDate.toLocaleString())
    //Chrome Outputs: "4/28/1993, 12:00:00 AM"
    //Firefox Outputs: "4/27/1993, 6:00:00 PM"

因此,现在的日期同时显示了27日和28日,尽管我希望它仅显示28日。

但是!如果我将数字更改为类似于以下代码的字符串格式。仍然不一致。

var objDate = new Date("1993-04-28"),
    dateString = objDate.toLocaleDateString(undefined, {
        weekday: "long",
        year: "numeric",
        month: "long",
        day: "numeric",
        hour: "numeric",
        timeZoneName: 'long'
    });

    console.log(dateString)
    //Chrome Outputs: "Wednesday, April 27, 1993, 12 AM Mountain Daylight Time"
    //Firefox Outpus: "Tuesday, April 27, 1993, 6 PM Mountain Daylight Time"

    let nowDate = new Date("1993-04-28");
    console.log(nowDate.toString())
    //Chrome Outputs: "Wed Apr 27 1993 00:00:00 GMT-0600 (Mountain Daylight Time)"
    //Firefox Outputs: "Wed Apr 28 1993 00:00:00 GMT+0000 (UTC)"

    console.log(nowDate.toLocaleString())
    //Chrome Outputs: "4/27/1993, 12:00:00 AM"
    //Firefox Outputs: "4/27/1993, 6:00:00 PM"

现在这是代码的最后一位。

如果我将一天中的某个时间输入为字符串格式(如中午),则可以很好地显示当天的时间。

编辑:我刚刚在Safari中检查了此方法,并且它输出了无效日期。

var objDate = new Date("1993-04-28 12:00"),
    dateString = objDate.toLocaleDateString(undefined, {
        weekday: "long",
        year: "numeric",
        month: "long",
        day: "numeric",
        hour: "numeric",
        timeZoneName: 'long'
    });

    console.log(dateString)
    //Chrome Outputs: "Wednesday, April 28, 1993, 12 PM Mountain Daylight Time"
    //Firefox Outpus: "Wednesday, April 28, 1993, 6 AM Mountain Daylight Time"

    let nowDate = new Date("1993-04-28");
    console.log(nowDate.toString())
    //Chrome Outputs: "Wed Apr 28 1993 12:00:00 GMT-0600 (Mountain Daylight Time)"
    //Firefox Outputs: "Wed Apr 28 1993 12:00:00 GMT+0000 (UTC)"

    console.log(nowDate.toLocaleString())
    //Chrome Outputs: "4/28/1993, 12:00:00 PM"
    //Firefox Outputs: "4/28/1993, 6:00:00 AM"

所以现在这里是特别的问题。

为什么输入日期的方法有时会设置不同的日期? 在列出的每种情况下,浏览器的行为有何不同?我认为我使用的每种方法都是基于本地的,而不是基于UTC的。

编辑: 我可能只需要使用其中一个库即可处理所有不一致问题。虽然有一个相当小的图书馆?我找到了dayjs,它看起来足够小。

codepen sources

2 个答案:

答案 0 :(得分:1)

日期字符串的解析与实现有关,这意味着在浏览器之间不一致。某些字符串格式通常被视为UTC,而不是本地。从JavaScript Date docs...

  

注意:使用Date构造函数(和Date.parse解析日期字符串,   它们是等效的),因此强烈建议不要使用浏览器   差异和矛盾之处。支持RFC 2822格式字符串   仅按照惯例。对ISO 8601格式的支持不同之处在于   仅日期的字符串(例如“ 1970-01-01”)被视为UTC,而不是本地字符串。

类似地,toString可能不会在浏览器中产生格式相似的日期字符串。从Date.prototype.toString docs(请注意,截至本答案发布之日起,ECMAScript 2018尚未在所有浏览器中完全实现)...

  

直到ECMAScript 2018(版本9),返回的字符串格式   Date.prototype.toString依赖于实现。因此它   不应依赖于指定的格式。

toLocaleString localesoptionsnot supported across all browsers

您已经注意到,Moment.js之类的许多库可以帮助解决此问题。

如果您只是想获取一致的日期字符串输入并将其重新格式化以显示,那么使用vanilla js可能并没有那么困难(但是困难很大程度上取决于您输入值的一致性)。例如:

const formatDate = (date) => {
  const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
  let [y, m, d] = date.split('-');
  return months[m - 1] + ' ' + d + ', ' + y;
}

let date = formatDate('1993-04-28');
console.log(date);
// April 28, 1993

答案 1 :(得分:0)

是的,浏览器之间存在很多不一致之处。 Tee最糟糕的是在IE和Safari上,其中new Date("2018-08-23 18:00:00")不是有效的日期格式:) 我发现最好的方法是将其转换为“ Zulu”时间,然后添加T作为时间,例如:new Date("2018-08-23T18:00:00Z")

只需使用yourDate.replace(" ", "T");添加T,然后简单地添加Z字符串即可。

对于任何问题,让我发表评论,谢谢。