Bob
Bob

Reputation: 497

Year 0000 in java

When I parse a date with the year 0000 it appears to be stored as the year 0001.

See below for code:

String dateStr = "00000102";
System.out.println(dateStr);
DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
Date date = dateFormat.parse("00000102");
String convertedStr = dateFormat.format(date);
System.out.println(convertedStr);

The output is as per below:

00000102
00010102

Is there a way to represent the year 0000 in Java using the standard Java API?

Upvotes: 3

Views: 7737

Answers (4)

Anonymous
Anonymous

Reputation: 86282

java.time

I recommend that you use java.time, the modern Java date and time API, for your date work.

As others have said, the Julian/Gregorian calendar that the old Date and SimpleDateFormat classes used does not have a year zero. Before year one in the current era (CE also known as AD) came year 1 before the current era (BCE also known as BC).

A side effect of using java.time is that you do get a year zero! That’s right. java.time uses the proleptic Gregorian calendar, a modern inventions that not only extends the rules of the Gregorian back into times before the Gregorian calendar was invented, but also includes a year 0 before year 1, and a year -1 (minus one) before that. You may say that year 0 corresponds to 1 BCE and -1 to 2 BCE, etc.

So parsing your string is no problem. There’s even a built-in formatter for it.

    String dateStr = "00000102";
    LocalDate date = LocalDate.parse(dateStr, DateTimeFormatter.BASIC_ISO_DATE);
    System.out.println("Parsed date is " + date);
    String convertedStr = date.format(DateTimeFormatter.BASIC_ISO_DATE);
    System.out.println(convertedStr);

Output:

Parsed date is 0000-01-02
00000102

We see that in both output lines year 0000 is printed back as expected.

What went wrong in your code?

When we all agree that there was no year 0, we should have expected your parsing to fail with an exception because of the invalid year. Why didn’t it? It’s one of the many problems with the old SimpleDateFormat class: with default settings it just extrapolates and takes year 0000 to mean the year before year 0001, so year 1 BCE. And falsely pretends that all is well. This explains why year 0001 was printed back: it meant year 1 BCE, but since you didn’t print the era too, this was really hard to tell.

Links

Upvotes: 1

Jon Newmuis
Jon Newmuis

Reputation: 26502

I don't believe it's possible, since java.util.Date is based on UTC, which is based on the Gregorian calendar, and the Gregorian calendar has no year zero.

...the traditional proleptic Gregorian calendar (like the Julian calendar) does not have a year 0 and instead uses the ordinal numbers 1, 2, … both for years AD and BC. Thus the traditional time line is 2 BC, 1 BC, AD 1, and AD 2.

(Source: The Wikipedia article on the Gregorian calendar)

Upvotes: 11

Thilo
Thilo

Reputation: 262494

I don't think the calendar is zero-based. Before 1 AD there was 1 BC. No 0.

Also: what kind of application are you building that needs to handle dates from that era? And if you need to cover that area, consider this: "Dates obtained using GregorianCalendar are historically accurate only from March 1, 4 AD onward, when modern Julian calendar rules were adopted. Before this date, leap year rules were applied irregularly, and before 45 BC the Julian calendar did not even exist."

Upvotes: 2

BalusC
BalusC

Reputation: 1108712

Year 0 does not exist in the Gregorian calendar. From Year 0 at Wikipedia:

"Year zero" does not exist in the widely used Gregorian calendar or in its predecessor, the Julian calendar. Under those systems, the year 1 BC is followed by AD 1.

...

The absence of a year 0 leads to some confusion concerning the boundaries of longer decimal intervals, such as decades and centuries. For example, the third millennium of the Gregorian calendar began on Monday, 1 January, 2001, rather than the widely celebrated Saturday, 1 January, 2000. Likewise, the 20th century began on 1 January 1901.

...

Upvotes: 1

Related Questions