为什么Date接受负值?

时间:2016-12-27 07:24:32

标签: javascript

根据MDN

"日期对象基于时间值,即自UTC时间1970年1月1日以来的毫秒数。"

那么为什么它接受负面价值呢?

即使在1970年1月1日之前它不应该是负值平均值吗?

new Date('0000', '00', '-1');   // "1899-12-30T05:00:00.000Z"
new Date('0000', '00', '00');   // "1899-12-31T05:00:00.000Z"
new Date('-9999', '99', '99');  // "-009991-07-08T04:00:00.000Z"

发生了什么事?

更新

对于某些正值,年份从1900年开始

new Date(100);                  // "1970-01-01T00:00:00.100Z"   // it says 100Z
new Date(0100);                 // "1970-01-01T00:00:00.064Z"   // it says 64Z
new Date("0006","06","06");     // "1906-07-06T04:00:00.000Z"

另请注意,在最后一个中,日期显示为4,这是错误的。

我怀疑这是某种Y2K错误?!!

4 个答案:

答案 0 :(得分:15)

  

这很难且不一致,是的。 JavaScript Date对象是{1.0}在Java 1.0中的based on,它是so bad Java redesigned一个全新的包。   JavaScript不是那么幸运。

  1. 日期是"基于" unix eopch,因为它是defined。它是内部的详细信息。
  2. 1st Jan 1970是此基线的实际时间。
  3. since是时间戳值的方向:+ v的前进,-ve的后退。
  4. 外部,Date构造函数有几种不同的用法,基于参数:
  5. 零参数=当前时间

    new Date()   // Current datetime. Every tutorial should teach this.
    
      

    时间是绝对的,但是显示了'时区可以是UTC或本地。

         

    为简单起见,此答案仅使用UTC。 测试时请记住时区。

    一个数字参数= timestamp @ 1970

    new Date(0)    // 0ms from 1970-01-01T00:00:00Z.
    new Date(100)  // 100ms from 1970 baseline.
    new Date(-10)  // -10ms from 1970 baseline.
    

    一个字符串参数= iso date string

    new Date('000')        // Short years are invalid, need at least four digits.
    new Date('0000')       // 0000-01-01.  Valid because there are four digits.
    new Date('1900')       // 1900-01-01.
    new Date('1900-01-01') // Same as above.
    new Date('1900-01-01T00:00:00') // Same as above.
    new Date('-000001')    // 2 BC, see below. Yes you need all those zeros.
    

    两个或多个参数=年,月,等等@ 1900或0000

    new Date(0,0)      // 1900-01-01T00:00:00Z.
    new Date(0,0,1)    // Same as above.  Date is 1 based.
    new Date(0,0,0)    // 1 day before 1900 = 1899-12-31.
    new Date(0,-1)     // 1 month before 1900 = 1899-12-01.
    new Date(0,-1,0)   // 1 month and 1 day before 1900 = 1899-11-30.
    new Date(0,-1,-1)  // 1 month and *2* days before 1900 = 1899-11-29.
    new Date('0','1')  // 1900-02-01. Two+ params always cast to year and month.
    new Date(100,0)    // 0100-01-01. Year > 99 use year 0 not 1900.
    new Date(1900,0)   // 1900-01-01. Same as new Date(0,0). So intuitive!
    

    负年= BC

    new Date(-1,0)    // 1 year before 0000-01-01 = 1 year before 1 BC = 2 BC.
    new Date(-1,0,-1) // 2 days before 2 BC.  Fun, yes?  I'll leave this as an exercise.
    
      

    没有0 AC。有1 AC和公元前1年的前一年。按惯例,Year 0是公元前1年。

         

    2 BC显示为年"-000001"。   额外的零是required,因为它超出正常范围(0000到9999)。   如果您new Date(12345,0),您也会获得"+012345-01-01"

         

    当然,早在1923年在欧洲采用的Gregorian calendar,在我们到达BC之前很久就不再有意义了。   事实上,学者accept that耶稣并非出生于公元前一世。   但随着the starsthe Earth按此比例移动,日历是您最不担心的。

    剩下的给定代码只是这些情况的变体。例如:

    new Date(0100)          // One number = epoch. 0100 (octal) = 64ms since 1970
    new Date('0100')        // One string = iso = 0100-01-01.
    new Date(-9999, 99, 99) // 9999 years before BC 1 and then add 99 months and 98 days
    

    希望你度过一段有趣的时光。请不要忘记投票。 :)

      

    要保持理智,请将所有日期保留在ISO 8601中并使用字符串构造函数。
      如果您需要处理时区,请将所有日期时间保留为UTC。

答案 1 :(得分:1)

嗯,首先,你传入的是字符串而不是整数,所以这可能与你的问题有关。

检查this out,它很好地解释了负面日期,并且您的确切示例有一个解释。

答案 2 :(得分:0)

请查看documentation

  

年份:从0到99的值映射到1900年到1999年

  1. 1970与适当的时区:新日期(0); // 1970年以来的MS
  2. 1900(或带有应用时区的1899):新日期(0,0)或新日期(0,0,1) - 日期为1基础,月份和年份为0
  3. 1899:新日期(0,0,-1)

答案 3 :(得分:0)

  

那为什么它接受负值?

您对使用构造函数所采用的参数内部存储数据的描述感到困惑。

  

即使在1970年1月1日之前它不应该是负值平均值吗?

不,由于上述原因。没有什么能阻止year, month or day from being negative。你最后会添加一个负数。

  

另请注意,在最后一个中,日期显示为4,这是错误的。

start with a 0 are expressed in octal,而不是小数的数字。 0100 === 64