Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement request - would love to go back further to ~ 500 BC #180

Open
madmax25 opened this issue Jan 21, 2022 · 7 comments
Open

Enhancement request - would love to go back further to ~ 500 BC #180

madmax25 opened this issue Jan 21, 2022 · 7 comments

Comments

@madmax25
Copy link

java.lang.IllegalArgumentException: A Jewish date earlier than 18 Teves, 3761 (1/1/1 Gregorian) can't be set. 3317, 13, 6 is invalid.

@Sternbach-Software
Copy link
Contributor

Sternbach-Software commented Nov 30, 2022

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.

@KosherJava
Copy link
Owner

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

@Sternbach-Software
Copy link
Contributor

Sternbach-Software commented Dec 2, 2022

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.

@Sternbach-Software
Copy link
Contributor

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.

@Sternbach-Software
Copy link
Contributor

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.

@madmax25
Copy link
Author

madmax25 commented Feb 2, 2023

Julian calendar is also not accurate due to https://en.wikipedia.org/wiki/Julian_calendar#Leap_year_error. Accuracy is necessary

@Sternbach-Software
Copy link
Contributor

Sternbach-Software commented Apr 23, 2023

@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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants