有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

《时代》杂志称0年是闰年,但0年从未存在过

我正在为一些正在更新的方便方法编写一些测试用例,并决定看看如果在0年使用LocalDateisLeapYear()方法会发生什么。据我所知,公元前0年并不存在:公元前1年是公元前1年。(这篇文章是根据我多年前读到的一篇文章写成的,我早已忘记了它的来源。)令我大吃一惊的是,我的测试表明0年是闰年

我意识到java.time.LocalDate类实现了ISO-8601,但ISO-8601真的表明0年存在吗?我不太愿意相信那些测试过LocalDate的人会错过这个测试用例,但我也不愿意相信像ISO-8601这样的国际标准会犯这样一个明显的错误

另一种可能是我读的那篇文章完全错了。(或者当时是正确的,但后来又被重新考虑过。)

这并不十分重要,但我很想知道错误在哪里:ISO-8601,Java的LocalDate类,或者我对时间如何计算的理解


共 (2) 个答案

  1. # 1 楼答案

    Wikipedia

    ...there is a year zero in astronomical year numbering (where it coincides with the Julian year 1 BC) and in ISO 8601:2004 (where it coincides with the Gregorian year 1 BC)

  2. # 2 楼答案

    TL;DR:LocalDate正在按照国际标准(ISO 8601)执行文件中规定的任务。这是否“正确”是一个完全不同的问题

    {a1}本身包括以下警告:

    It is equivalent to the proleptic Gregorian calendar system, in which today's rules for leap years are applied for all time. For most applications written today, the ISO-8601 rules are entirely suitable. However, any application that makes use of historical dates, and requires them to be accurate will find the ISO-8601 approach unsuitable.

    维基百科有更多关于proleptic Gregorian calendar的信息。其中包括:

    Mathematically, it is more convenient to include a year 0 and represent earlier years as negative, for the specific purpose of facilitating the calculation of the number of years between a negative (BC) year and a positive (AD) year. This is the convention used in astronomical year numbering and in the international standard date system, ISO 8601. In these systems, the year 0 is a leap year.

    请原谅,我暂时偏离了这一切的历史背景

    西方历法中的年份表面上是从耶稣基督诞生算起的,但这样做的想法始于六世纪,而我们目前的历法是基于十六世纪的计算。由于罗马数字既不表示零,也不表示负数,所以年份要么是“在耶稣之后”(公元前,表示“在基督之前”)要么是“在耶稣之前”(公元前,表示“在基督之前”)。因此,传统上,公元前1年之后是公元1年,其间没有零年

    然而,在第一个世纪,没有人以这种方式计算年份;作为比较,路加福音描述了耶稣开始他的事工的那一年

    in the fifteenth year of the reign of Tiberius Caesar, Pontius Pilate being governor of Judaea, and Herod being tetrarch of Galilee, and his brother Philip tetrarch of Ituraea and of the region of Trachonitis, and Lysanias the tetrarch of Abilene,

    从表面上看,这应该是公元30年,因为路加描述耶稣当时“大约30岁”。但现代历史学家普遍认为,狄奥尼修斯·埃西古斯(Dionysius Exiguus)在公元525年提出了anno domini制度,但他错了,因此年份的编号至少减少了一到两年。(确切日期仍有争议;如需了解更多详情,请参阅Wikipedia。)

    但现在修复已经太迟了;即使是从朱利安历法到格里高利历法的过渡(相差不到两周),也遇到了广泛的政治阻力,因为在几个世纪的时间里,这一转变发生在整个欧洲。你可以想象,现在年份编号的改变会有多大的破坏性

    那么,这段历史与今天的软件有什么关系呢?不幸的是,由于历史上有无数种计算和记录日期的方式,你要么需要放弃在日历上以一致的方式前进和后退,要么你必须放弃计算日期,因为这些日期与当时真实的人们会使用的日期有任何对应关系。分歧发生的速度比你想象的要快:不到100年前,许多欧洲国家仍在使用儒略历法,与欧洲其他国家相差近两周


    可以理解的是,LocalDate摆脱了这种混乱,只以我们今天使用的方式实现日历。重申Javadoc所说的:“对于今天编写的大多数应用程序,ISO-8601规则是完全合适的。但是,任何使用历史日期并要求其准确的应用程序都会发现ISO-8601方法不合适。”