Open madmax25 opened 2 years ago
Where does that stacktrace start? Is this a JDK limitation or a KosherJava limitation? I might be interested in solving this, assuming the zmanim aspect of it isn't too complicated.
@Sternbach-Software , Did you not encounter a proper stacktrace? This shows exactly where the code is.
Exception in thread "main" java.lang.IllegalArgumentException: A Jewish date earlier than 18 Teves, 3761 (1/1/1 Gregorian) can't be set. 3761, 10, 17 is invalid.
at com.kosherjava.zmanim.hebrewcalendar.JewishDate.validateJewishDate(JewishDate.java:620)
at com.kosherjava.zmanim.hebrewcalendar.JewishDate.setJewishDate(JewishDate.java:1175)
at com.kosherjava.zmanim.hebrewcalendar.JewishDate.setJewishDate(JewishDate.java:1144)
at com.kosherjava.zmanim.hebrewcalendar.JewishDate.<init>(JewishDate.java:986)
at com.kosherjava.zmanim.hebrewcalendar.JewishCalendar.<init>(JewishCalendar.java:291)
at com.kosherjava.zmanim.test.ZmanimTester.BCEDateTester(ZmanimTester.java:106)
at com.kosherjava.zmanim.test.ZmanimTester.main(ZmanimTester.java:102)
please see https://github.com/KosherJava/zmanim/blob/master/src/main/java/com/kosherjava/zmanim/hebrewcalendar/JewishDate.java#L620 Code comments reference issues prior to that date. I do not recall all the issues, but keep the following in mind. Remember that there is no year zero in the Julian (and a retro Gregorian) calendars. It goes directly from 1 to -1., and there was no Julian/Gregorian calendar that long ago, so it is just a rough calculation. Also note that setting a Java Calendar year to a negative number does not work. It ignores the sign. You have to set the Calendar's ERA to Calendar.BC. Since it was not practical, I did not spend time reviewing it. Also note that the Java date formatters by default will format a BCE dates as AD dates. In short, it is a lot of pain for very little gain. Even if you get it working, it will be VERY confusing to users who do not realize that they now have to use a special formatter to see the BCE dates (it will look like AD dates unless they remember to properly format. Since people typically do not want to always see AD, they will have to implement two formatters and only use the BCE one when the ERA is detected as BCE. In short, play around (at first spend you time on the Java calendars before moving to make any PR), but I think you will see the futility of this.
What if there was a separate class (e.g. BCEJewishCalendar
) that took care of those complexities for the client? It could even implement the same API surface or a common interface. If there was a library that made this easier, would you be averse to introducing a new dependency? If averse, I think I'll still try to give it a shot.
A quote from JodaTime GJChronology javadoc
The Julian calendar has leap years every four years, whereas the Gregorian has special rules for 100 and 400 years. A meaningful result will thus be obtained for all input values. However before 8 CE, Julian leap years were irregular, and before 45 BCE there was no Julian calendar. ... To create a pure proleptic (extending indefinitely) Julian chronology, use JulianChronology, and to create a pure proleptic Gregorian chronology, use GregorianChronology.
Java GregorianCalendar
is proleptic also: (javadoc)
GregorianCalendar implements proleptic Gregorian and Julian calendars. That is, dates are computed by extrapolating the current rules indefinitely far backward and forward in time. As a result, GregorianCalendar may be used for all years to generate meaningful and consistent results. However, 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.
Julian calendar is also not accurate due to https://en.wikipedia.org/wiki/Julian_calendar#Leap_year_error. Accuracy is necessary
@KosherJava Am I inferring correctly from what you said that the only issue with calculating dates < 1/1/1 is in formatting the result and proper usage of the KosherJava API, but algorithmically, the code should output the best approximation possible given that Hillel II's calculations were done in 359 CE (as the class javadoc mentions)?
Also, it actually goes from 1 to 0 to -1.
LocalDate x = LocalDate.of(1,1,1);
LocalDate y = x.minusDays(1);
LocalDate z = y.minusYears(1L);
System.out.println(x);
System.out.println(y);
System.out.println(z);
0001-01-01
0000-12-31
-0001-12-31
java.lang.IllegalArgumentException: A Jewish date earlier than 18 Teves, 3761 (1/1/1 Gregorian) can't be set. 3317, 13, 6 is invalid.