Skip to content

Commit 5dd0df5

Browse files
authored
AstronomicalCalendar - solar midnight changes
- Fix incorrect documentation on getTemporalHour() and getTemporalHour(Date startOfDay, Date endOfDay) - Solar midnight is now the last zman of the day, not the first - If calculated for Feb 8, it will be the midnight boundary between Jan 8 and Jan 9. - Deprecate getSunLowerTransit() - use getSolarMidnight() instead (this is already done internally) - Changes to getSolarMidnight() to use the calculator implementations - Update JavaDocs to avoid warnings on recent JDKs and other tweaks
1 parent e0dd162 commit 5dd0df5

File tree

1 file changed

+53
-39
lines changed

1 file changed

+53
-39
lines changed

src/main/java/com/kosherjava/zmanim/AstronomicalCalendar.java

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Zmanim Java API
3-
* Copyright (C) 2004-2024 Eliyahu Hershfeld
3+
* Copyright (C) 2004-2025 Eliyahu Hershfeld
44
*
55
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
66
* Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option)
@@ -63,7 +63,7 @@
6363
* Date sunrise = ac.getSunrise();
6464
* </pre>
6565
*
66-
* @author &copy; Eliyahu Hershfeld 2004 - 2024
66+
* @author &copy; Eliyahu Hershfeld 2004 - 2025
6767
*/
6868
public class AstronomicalCalendar implements Cloneable {
6969

@@ -229,7 +229,8 @@ public Date getSunset() {
229229
* such as in the Arctic Circle where there is at least one day a year where the sun does not rise, and one
230230
* where it does not set, a <code>null</code> will be returned. See detailed explanation on top of the page.
231231
* @see AstronomicalCalendar#getSunset
232-
* @see AstronomicalCalendar#getUTCSeaLevelSunset 2see {@link #getSunset()}
232+
* @see AstronomicalCalendar#getUTCSeaLevelSunset
233+
* @see #getSunset()
233234
*/
234235
public Date getSeaLevelSunset() {
235236
double sunset = getUTCSeaLevelSunset(GEOMETRIC_ZENITH);
@@ -447,12 +448,12 @@ public double getUTCSeaLevelSunset(double zenith) {
447448
}
448449

449450
/**
450-
* A method that returns an {@link AstronomicalCalculator#getElevationAdjustment(double) elevation adjusted}
451-
* temporal (solar) hour. The day from {@link #getSunrise() sunrise} to {@link #getSunset() sunset} is split into 12
452-
* equal parts with each one being a temporal hour.
451+
* A method that returns a sea-level based temporal (solar) hour. The day from {@link #getSeaLevelSunrise()
452+
* sea-level sunrise} to {@link #getSeaLevelSunset() sea-level sunset} is split into 12 equal parts with each
453+
* one being a temporal hour.
453454
*
454-
* @see #getSunrise()
455-
* @see #getSunset()
455+
* @see #getSeaLevelSunrise()
456+
* @see #getSeaLevelSunset()
456457
* @see #getTemporalHour(Date, Date)
457458
*
458459
* @return the <code>long</code> millisecond length of a temporal hour. If the calculation can't be computed,
@@ -467,8 +468,8 @@ public long getTemporalHour() {
467468
/**
468469
* A utility method that will allow the calculation of a temporal (solar) hour based on the sunrise and sunset
469470
* passed as parameters to this method. An example of the use of this method would be the calculation of a
470-
* non-elevation adjusted temporal hour by passing in {@link #getSeaLevelSunrise() sea level sunrise} and
471-
* {@link #getSeaLevelSunset() sea level sunset} as parameters.
471+
* elevation adjusted temporal hour by passing in {@link #getSunrise() sunrise} and
472+
* {@link #getSunset() sunset} as parameters.
472473
*
473474
* @param startOfDay
474475
* The start of the day.
@@ -523,51 +524,58 @@ public Date getSunTransit() {
523524
* set} to use the {@link com.kosherjava.zmanim.util.NOAACalculator} (the default) it will calculate astronomical
524525
* midnight. If the calendar instance is to use the {@link com.kosherjava.zmanim.util.SunTimesCalculator}, that does not
525526
* have code to calculate astronomical noon, midnight is calculated as halfway between sea level sunrise and sea level
526-
* sunset on the other side of the world (180&deg; awa)y, which can be slightly off the real transit time due to changes
527+
* sunset on the other side of the world (180&deg; away), which can be slightly off the real transit time due to changes
527528
* in declination (the lengthening or shortening day). See <a href=
528529
* "https://kosherjava.com/2020/07/02/definition-of-chatzos/">The Definition of Chatzos</a> for details on the proper
529530
* definition of solar noon / midday.
530531
*
531-
* @return the <code>Date</code> representing Sun's lower transit. If the calculation can't be computed such as when using
532-
* the {@link com.kosherjava.zmanim.util.SunTimesCalculator USNO calculator} that does not support getting solar
533-
* midnight for the Arctic Circle (where there is at least one day a year where the sun does not rise, and one
534-
* where it does not set), a <code>null</code> will be returned. See detailed explanation on top of the page.
532+
* @deprecated This method was replaced by {@link #getSolarMidnight()} and will be removed in v3.0.
533+
*
534+
* @return the <code>Date</code> representing Sun's lower transit at the end of the current day. If the calculation can't
535+
* be computed such as when using the {@link com.kosherjava.zmanim.util.SunTimesCalculator USNO calculator} that
536+
* does not support getting solar noon or midnight for the Arctic Circle (where there is at least one day a year
537+
* where the sun does not rise, and one where it does not set), a <code>null</code> will be returned. This is not
538+
* relevant when using the {@link com.kosherjava.zmanim.util.NOAACalculator NOAA Calculator} that is never expected
539+
* to return <code>null</code>. See the detailed explanation on top of the page.
535540
*
536541
* @see #getSunTransit()
542+
* @see #getSolarMidnight()
537543
* @see com.kosherjava.zmanim.util.NOAACalculator#getUTCNoon(Calendar, GeoLocation)
538544
* @see com.kosherjava.zmanim.util.SunTimesCalculator#getUTCNoon(Calendar, GeoLocation)
539545
*/
546+
@Deprecated // (since="2.6", forRemoval=true)// add back once Java 9 is the minimum supported version
540547
public Date getSunLowerTransit() {
541-
Calendar cal = getAdjustedCalendar();
542-
GeoLocation lowerGeoLocation = (GeoLocation) getGeoLocation().clone();
543-
double meridian = lowerGeoLocation.getLongitude();
544-
double lowerMeridian = meridian + 180;
545-
if (lowerMeridian > 180){
546-
lowerMeridian = lowerMeridian - 360;
547-
cal.add(Calendar.DAY_OF_MONTH, -1);
548-
}
549-
lowerGeoLocation.setLongitude(lowerMeridian);
550-
double noon = getAstronomicalCalculator().getUTCNoon(cal, lowerGeoLocation);
551-
return getDateFromTime(noon, SolarEvent.MIDNIGHT);
548+
return getSolarMidnight();
552549
}
553550

554551
/**
555-
* A method that returns "solar" midnight, or the time when the sun is at its <a
556-
* href="https://en.wikipedia.org/wiki/Nadir">nadir</a>. The current calculation is halfway between today and
557-
* tomorrow's {@link #getSunTransit() sun transit}.
552+
* A method that returns solar midnight at the end of the current day (that may actually be after midnight of the day it
553+
* is being calculated for). It occurs when the Sun is <a href="https://en.wikipedia.org/wiki/Transit_%28astronomy%29"
554+
* >transiting</a> the lower <a href="https://en.wikipedia.org/wiki/Meridian_%28astronomy%29">celestial meridian</a>, or
555+
* when the sun is at it's <a href="https://en.wikipedia.org/wiki/Nadir">nadir</a>. The calculations used by this class
556+
* depend on the {@link AstronomicalCalculator} used. If this calendar instance is {@link
557+
* #setAstronomicalCalculator(AstronomicalCalculator) set} to use the {@link com.kosherjava.zmanim.util.NOAACalculator}
558+
* (the default) it will calculate astronomical midnight. If the calendar instance is to use the {@link
559+
* com.kosherjava.zmanim.util.SunTimesCalculator USNO Calculator}, that does not have code to calculate astronomical noon,
560+
* midnight is calculated as 12 hours after halfway between sea level sunrise and sea level sunset of that day. This can
561+
* be slightly off the real transit time due to changes in declination (the lengthening or shortening day). See <a href=
562+
* "https://kosherjava.com/2020/07/02/definition-of-chatzos/">The Definition of Chatzos</a> for details on the proper
563+
* definition of solar noon / midday.
564+
*
565+
* @return the <code>Date</code> representing Sun's lower transit at the end of the current day. If the calculation can't
566+
* be computed such as when using the {@link com.kosherjava.zmanim.util.SunTimesCalculator USNO calculator} that
567+
* does not support getting solar noon or midnight for the Arctic Circle (where there is at least one day a year
568+
* where the sun does not rise, and one where it does not set), a <code>null</code> will be returned. This is not
569+
* relevant when using the {@link com.kosherjava.zmanim.util.NOAACalculator NOAA Calculator} that is never expected
570+
* to return <code>null</code>. See the detailed explanation on top of the page.
558571
*
559-
* @return the <code>Date</code> of astronomical solar midnight. If the calculation can't be computed such as
560-
* when using the {@link com.kosherjava.zmanim.util.SunTimesCalculator USNO calculator} that does not
561-
* support getting solar noon for the Arctic Circle (where there is at least one day a year where the
562-
* sun does not rise, and one where it does not set), a <code>null</code> will be returned. See
563-
* detailed explanation on top of the page.
572+
* @see #getSunTransit()
564573
* @see com.kosherjava.zmanim.util.NOAACalculator#getUTCNoon(Calendar, GeoLocation)
565574
* @see com.kosherjava.zmanim.util.SunTimesCalculator#getUTCNoon(Calendar, GeoLocation)
566575
*/
567576
public Date getSolarMidnight() {
568-
AstronomicalCalendar clonedCal = (AstronomicalCalendar) clone();
569-
clonedCal.getCalendar().add(Calendar.DATE, 1);
570-
return getTimeOffset(getSunTransit(), (clonedCal.getSunTransit().getTime() - getSunTransit().getTime()) / 2);
577+
double noon = getAstronomicalCalculator().getUTCMidnight(getAdjustedCalendar(), getGeoLocation());
578+
return getDateFromTime(noon, SolarEvent.MIDNIGHT);
571579
}
572580

573581
/**
@@ -600,6 +608,7 @@ protected enum SolarEvent {
600608
/**SUNRISE A solar event related to sunrise*/SUNRISE, /**SUNSET A solar event related to sunset*/SUNSET,
601609
/**NOON A solar event related to noon*/NOON, /**MIDNIGHT A solar event related to midnight*/MIDNIGHT
602610
}
611+
603612
/**
604613
* A method that returns a <code>Date</code> from the time passed in as a parameter.
605614
*
@@ -636,8 +645,8 @@ protected Date getDateFromTime(double time, SolarEvent solarEvent) {
636645
cal.add(Calendar.DAY_OF_MONTH, -1);
637646
} else if (solarEvent == SolarEvent.SUNSET && localTimeHours + hours < 6) {
638647
cal.add(Calendar.DAY_OF_MONTH, 1);
639-
} else if (solarEvent == SolarEvent.MIDNIGHT && localTimeHours + hours > 12) {
640-
cal.add(Calendar.DAY_OF_MONTH, -1);
648+
} else if (solarEvent == SolarEvent.MIDNIGHT && localTimeHours + hours < 12) {
649+
cal.add(Calendar.DAY_OF_MONTH, 1);
641650
}
642651

643652
cal.set(Calendar.HOUR_OF_DAY, hours);
@@ -747,6 +756,8 @@ private Calendar getAdjustedCalendar(){
747756
}
748757

749758
/**
759+
* Returns an XML formatted representation of the class using the default output of the
760+
* {@link com.kosherjava.zmanim.util.ZmanimFormatter#toXML(AstronomicalCalendar) toXML} method.
750761
* @return an XML formatted representation of the class. It returns the default output of the
751762
* {@link com.kosherjava.zmanim.util.ZmanimFormatter#toXML(AstronomicalCalendar) toXML} method.
752763
* @see com.kosherjava.zmanim.util.ZmanimFormatter#toXML(AstronomicalCalendar)
@@ -757,6 +768,8 @@ public String toString() {
757768
}
758769

759770
/**
771+
* Returns a JSON formatted representation of the class using the default output of the
772+
* {@link com.kosherjava.zmanim.util.ZmanimFormatter#toJSON(AstronomicalCalendar) toJSON} method.
760773
* @return a JSON formatted representation of the class. It returns the default output of the
761774
* {@link com.kosherjava.zmanim.util.ZmanimFormatter#toJSON(AstronomicalCalendar) toJSON} method.
762775
* @see com.kosherjava.zmanim.util.ZmanimFormatter#toJSON(AstronomicalCalendar)
@@ -851,6 +864,7 @@ public Calendar getCalendar() {
851864
}
852865

853866
/**
867+
* Sets the Calendar object for us in this class.
854868
* @param calendar
855869
* The calendar to set.
856870
*/

0 commit comments

Comments
 (0)