【问题标题】:Why does js subtract a day from a Date object with a certain format?为什么js会从一定格式的Date对象中减去一天?
【发布时间】:2015-02-05 12:48:54
【问题描述】:

我以这种格式从数据库中获取日期:

yyyy-mm-dd

当我使用此字符串创建 javascript Date 对象时,它会在日期前一天构建。

您可以在控制台中进行测试:

var d = new Date("2015-02-01"); 
d

您将在 1 月 31 日收到!我测试了很多理论,但没有一个能回答这个问题。

  • 日期不是从零开始的,否则会给出 2 月 00 日,而不是 1 月 31 日
  • 它不是在执行数学方程式,而是从月和/或年中减去天
    • 日期 (2015-02-01) = 1969 年 12 月 31 日,星期三
    • 日期(“2015-01”)= 2014 年 12 月 31 日,星期三
  • 不会混淆当月的日期
    • 日期(“2015-08-02”)= 2015 年 8 月 1 日星期六
    • 如果这是真的,那么日期应该是 2015 年 2 月 8 日
  • 如果您使用不同的格式创建日期,它可以正常工作
    • 日期(“02/01/2015”)= 2015 年 2 月 1 日

我的结论是 js 是有目的的这么做的。我曾尝试研究“为什么”,但找不到解释。 为什么 js 会这样构建日期,但只能使用这种格式? 有没有办法绕过它,还是我必须构建日期,然后将其设置为第二天?

PS:“如何从数据库更改日期的格式”不是我要问的,这就是为什么我没有在这里放任何数据库信息的原因。

【问题讨论】:

  • 我不确定,但这可能是时区问题吗?
  • 你的最后一个问题和你的PS相互矛盾。我只是将数据库结果转换为支持格式并将其用于日期。不要添加或删除天数。至于为什么这样做......也许是这样:给定日期字符串“2014 年 3 月 7 日”,parse() 假定为本地时区,但给定 ISO 格式,例如“2014-03-07”,它将假定UTC 的时区。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
  • Chrome 工作正常。 new Date("2015-02-01"); --> Sun Feb 01 2015 03:00:00 GMT+0300 (MSK)
  • @gorpacrate 不适合我。新日期(“2015-02-01)-> 2015 年 1 月 31 日星期六。
  • 哈,有趣。那是在我的mac上。刚刚在 chrome for windows 中尝试过 - 是的,现在是 2015 年 1 月 31 日星期六。

标签: javascript date


【解决方案1】:

有些浏览器将部分日期字符串解析为 UTC,有些则解析为本地时间,

所以当您阅读它时,本地化时间可能会因一个浏览器而异

按时区偏移量。

您可以强制日期为 UTC 并添加本地偏移量,如果您

希望时间保证在本地:

1. set UTC time:    

var D= new Date("2015-02-01"+'T00:00:00Z');


2. adjust for local:

D.setMinutes(D.getMinutes()+D.getTimezoneOffset());

D 的值:(本地日期) 2015 年 2 月 1 日星期日 00:00:00 GMT-0500(东部标准时间)

偏移量将是当地时间。

Some differences between browsers when time zone is not specified in a parsed string:

(tested on Eastern Standard Time location)

(new Date("2015-02-01T00:00:00")).toUTCString();


Firefox 35: Sun, 01 Feb 2015 05:00:00 GMT

Chrome 40: Sun, 01 Feb 2015 00:00:00 GMT

Opera 27: Sun, 01 Feb 2015 00:00:00 GMT

IE 11: Sun, 01 Feb 2015 05:00:00 GMT

IE and Firefox set the Date as if it was local, Chrome and Opera as if it was UTC. 

【讨论】:

  • 我不认为浏览器在这里不一致。如果您没有在 iso 8601 日期字符串中给出时间,则假定为 00:00:00。如果您未在 iso 8601 日期字符串中提供时区部分,则假定为 UTC。 Js 只是将日期存储为自 1970 年 1 月 1 日 00:00:00 UTC 以来的毫秒数。控制台输出的差异与再次记录日期时使用的不同操作系统时区有关。那是使用本地时区的时候。
【解决方案2】:

在 javascript 中,Date 对象在内部表示为自 1970 年 1 月 1 日 00:00:00 UTC 以来的毫秒数。因此,不要将其视为通常意义上的“日期”,请尝试将 Date 对象视为由整数表示的“时间点”(无时区)。

使用字符串构造 Date 对象时,实际上只是调用了parse function。大多数日期时间格式 (including ISO 8601) 允许您降低日期字符串的精度。

为了降低精度,可以从任意值中删除任意数量的值 日期和时间表示,但从最少的顺序 到最重要的。

例如2015-02-01 代表 2015 年 2 月 1 日

这会导致 javascript 进退两难,因为 Date 对象总是精确到毫秒。 Javascript 无法存储精度降低的日期,因为它只是自 1970 年 1 月 1 日以来的毫秒整数。因此,如果未指定,它会假设午夜 (00:00:00) 的时间和时区如果未指定,则为 UTC。

所有有效的 javascript 实现都应该给出相同的结果 for this:

var d = new Date("2015-02-01");
alert(d.getTime());

1422748800000

将日期输出到某些(通常不清楚的)调试器或使用 getter 方法时会出现 1 天外的问题,因为使用的是本地时区。在浏览器中,这将是您的操作系统时区。 Greenwich Mean Time 的“西”任何人都可能会看到这个问题,因为他们的 UTC 偏移量为负。请注意,UTC equivalent functions 也使用 UTC 时区,如果您真的只是对表示日期而不是时间点感兴趣。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 2012-08-06
    • 2020-01-14
    • 1970-01-01
    • 2018-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多