3

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?

Bob
  • 457
  • 1
  • 5
  • 15
  • 5
    What is the "year 0"? (It doesn't exist in many calendar systems.) –  Dec 09 '11 at 02:58
  • This was on Seinfeld I believe. There is no year 0, so all those millennium parties held on new year's eve 1999 were in fact quite lame. – aroth Dec 09 '11 at 03:01
  • 1
    Our calendar is only 429 years old, we don't have a year 0, we started counting October 15th, 1582. – Incognito Dec 09 '11 at 03:49
  • 1
    The year before 1 AD was 1 BC, the number 0 wasn't in wide use in Europe in the middle ages, never mind previously. (Treated with suspicion since Muslims used it) The first century was retrospectively determined to be 1 AD to 100 AD, making the 20th century 1901 to 2000 and 21st century the years 2001 to 2100. – Peter Lawrey Dec 09 '11 at 08:18
  • [This answer](https://stackoverflow.com/a/65928023/10819573) can be helpful to understand how and why the date-time parsing/formatting API treats the year, ZERO. – Arvind Kumar Avinash May 22 '21 at 10:24
  • For new readers to this question I recommend you don’t use `SimpleDateFormat` and `Date`. Those classes are poorly designed and long outdated, the former in particular notoriously troublesome. Instead use `LocalDate` and `DateTimeFormatter`, both from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Sep 08 '21 at 16:56

4 Answers4

11

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)

Jon Newmuis
  • 25,722
  • 2
  • 45
  • 57
  • Now, to tie it up, what Calendar, if any, does `Date` use/imply/assume? Does it cover how AD/BC are handled or define operations around "year 0" or have a "minimum" year? What about `Calendar` or other alternatives such as Joda Time? –  Dec 09 '11 at 03:02
  • 1
    `java.util.Date` is based on [UTC](http://en.wikipedia.org/wiki/Coordinated_Universal_Time), which is based on the [Gregorian calendar](http://en.wikipedia.org/wiki/Gregorian_calendar). – Jon Newmuis Dec 09 '11 at 03:06
2

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."

Thilo
  • 257,207
  • 101
  • 511
  • 656
  • 2
    It doesn't really make sense for the application to store dates this early, so I think the best thing to do is to reject the date. – Bob Dec 09 '11 at 03:18
1

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

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
1

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.

...

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555