Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java says the year 0 is a leap year but year 0 never existed

Tags:

java

time

I was writing some test cases for some convenience methods that I am updating and decided to see what would happen if I used LocalDate's isLeapYear() method on the year 0. As I understand it, year 0 never actually existed: the year before 1 AD was 1 BC. (This is based on an article I read many years ago whose source I have long forgotten.) Much to my surprise, my test indicated that the year 0 wa a leap year!

I realize that the java.time.LocalDate class implements ISO-8601 but does ISO-8601 really indicate that the year 0 existed? I'm reluctant to believe that the people who tested LocalDate would have missed this as a test case but I'm also reluctant to believe that an international standard like ISO-8601 would make such an obvious mistake.

The other possibility is that the article I read was just flat-out wrong. (Or it was correct then but was rethought later.)

This is not hugely important but I am curious to know where the mistake is: ISO-8601, Java's LocalDate class, or my understanding of how time is reckoned.

like image 651
Henry Avatar asked Oct 22 '18 00:10

Henry


People also ask

Was the year 0 a leap year?

Rules: Leap years occur on years where the second two digits (AD only) are divisible by 4. In the event of the last two digits being 00, the first two digits must also be divisible by 4 for the year to be a leap year. For BC, counting starts at 1, so there is no year 0.

Is 0 a valid year?

A year zero does not exist in the Anno Domini (AD) calendar year system commonly used to number years in the Gregorian calendar (nor in its predecessor, the Julian calendar); in this system, the year 1 BC is followed directly by year AD 1.

Is Java date a leap year?

Since Java 1.1, the GregorianCalendar class allows us to check if a year is a leap year: public boolean isLeapYear(int year); As we might expect, this method returns true if the given year is a leap year and false for non-leap years.

Why every 100th year is not a leap year?

A year in which is divisible by 4 and for century years it should be divisible by 400 not 100 then it is said to be leap year. For example 100 is not leap year even though it is divisible by 4 but as it is century year it should be divisible by 400. Hence 100,200,300 are not leap years.


2 Answers

TL;DR: LocalDate is doing what it is documented to do, following an international standard (ISO 8601). Whether this is "correct" or not is a whole different question.

The LocalDate Javadoc itself includes this caveat:

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.

Wikipedia has more information on the proleptic Gregorian calendar. Among other things, it says:

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.

Forgive me a moment while I digress into some historical context for all this.

Years in the Western calendar are ostensibly counted from the birth of Jesus Christ, but the idea of doing so started in the sixth century and our current calendar is based on calculations made in the sixteenth century. Since Roman numerals had no representation of zero nor of negative numbers, years were either counted "after Jesus" (AD, for anno domini) or "before Jesus" (BC, for "before Christ"). Thus, traditionally, 1 BC was followed by AD 1, with no year zero between.

However, in the first century, nobody counted years that way; for comparison, the Gospel of Luke describes the year when Jesus began his ministry as

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,

Ostensibly this would have been AD 30, since Luke describes Jesus as being "about thirty years of age" at the time. But modern historians generally agree that Dionysius Exiguus, who proposed the anno domini system in AD 525, got it wrong, and thus the numbering of years is off by at least one or two years. (The exact date is still somewhat controversial; see Wikipedia if you care for more detail.)

But it's too late to fix now; even the transition from the Julian to Gregorian calendar, which was a discrepancy of less than two weeks, was met with extensive political resistance as the changeover occurred throughout Europe over a period of several centuries -- you can imagine how disruptive a change of year numbering would be now!

So what does this history have to do with software today? Unfortunately, due to the myriad ways in which dates were calculated and written down throughout history, you either need to give up on the calendar behaving in a consistent way as you move forward and backward in time, or you have to give up on calculated dates having any correspondence to the dates that real people would have used at the time. The divergence happens more rapidly than you might think: many European countries were still using the Julian calendar less than 100 years ago, with a discrepancy of nearly two weeks from everyone else in Europe!


Understandably, LocalDate washes its hands of this mess and only implements the calendar the way we use it today. Reiterating what the Javadoc says: "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."

like image 78
Daniel Pryden Avatar answered Sep 22 '22 07:09

Daniel Pryden


From 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)

like image 38
Alex Taylor Avatar answered Sep 21 '22 07:09

Alex Taylor