1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-31 20:02:42 +00:00

(calendar-location-name, calendar-latitude)

(calendar-longitude, solar-setup, solar-sin-degrees)
(solar-cosine-degrees, solar-tangent-degrees, solar-xy-to-quadrant)
(solar-degrees-to-quadrant, solar-atn2, solar-arccos)
(solar-sunrise-and-sunset, solar-moment, solar-daylight)
(solar-exact-local-noon, solar-julian-ut-centuries)
(solar-ephemeris-time, solar-date-next-longitude)
(solar-horizontal-coordinates, solar-equatorial-coordinates)
(solar-ecliptic-coordinates, solar-data-list, solar-longitude)
(solar-ephemeris-correction, solar-sidereal-time, solar-date-to-et)
(sunrise-sunset, solar-seasons-data, solar-equinoxes/solstices):
Doc fixes.
(solar-horizontal-coordinates, solar-equatorial-coordinates)
(solar-ecliptic-coordinates): Rename argument `for-sunrise-sunset'.
(solar-ecliptic-coordinates): Use unless.
(calendar-sunrise-sunset, diary-sunrise-sunset, diary-sabbath-candles):
Use or.
This commit is contained in:
Glenn Morris 2008-03-08 23:07:56 +00:00
parent f0a51f2a94
commit a603b7dbaa
2 changed files with 120 additions and 113 deletions

View File

@ -157,6 +157,24 @@
* calendar/cal-hebrew.el, calendar/holidays.el, calendar/lunar.el: * calendar/cal-hebrew.el, calendar/holidays.el, calendar/lunar.el:
* calendar/solar.el: Unquote lambda functions. * calendar/solar.el: Unquote lambda functions.
* calendar/solar.el (calendar-location-name, calendar-latitude)
(calendar-longitude, solar-setup, solar-sin-degrees)
(solar-cosine-degrees, solar-tangent-degrees, solar-xy-to-quadrant)
(solar-degrees-to-quadrant, solar-atn2, solar-arccos)
(solar-sunrise-and-sunset, solar-moment, solar-daylight)
(solar-exact-local-noon, solar-julian-ut-centuries)
(solar-ephemeris-time, solar-date-next-longitude)
(solar-horizontal-coordinates, solar-equatorial-coordinates)
(solar-ecliptic-coordinates, solar-data-list, solar-longitude)
(solar-ephemeris-correction, solar-sidereal-time, solar-date-to-et)
(sunrise-sunset, solar-seasons-data, solar-equinoxes/solstices):
Doc fixes.
(solar-horizontal-coordinates, solar-equatorial-coordinates)
(solar-ecliptic-coordinates): Rename argument `for-sunrise-sunset'.
(solar-ecliptic-coordinates): Use unless.
(calendar-sunrise-sunset, diary-sunrise-sunset, diary-sabbath-candles):
Use or.
* calendar/todo-mode.el: Remove un-needed eval-when-compile. * calendar/todo-mode.el: Remove un-needed eval-when-compile.
* textmodes/org.el (list-diary-entries-hook): Declare for compiler. * textmodes/org.el (list-diary-entries-hook): Declare for compiler.

View File

@ -55,7 +55,6 @@
;;; Code: ;;; Code:
(defvar date)
(defvar displayed-month) (defvar displayed-month)
(defvar displayed-year) (defvar displayed-year)
@ -87,7 +86,6 @@ would give military-style times like `21:07 (UTC)'."
(defcustom calendar-latitude nil (defcustom calendar-latitude nil
"Latitude of `calendar-location-name' in degrees. "Latitude of `calendar-location-name' in degrees.
The value can be either a decimal fraction (one place of accuracy is The value can be either a decimal fraction (one place of accuracy is
sufficient), + north, - south, such as 40.7 for New York City, or the value sufficient), + north, - south, such as 40.7 for New York City, or the value
can be a vector [degrees minutes north/south] such as [40 50 north] for New can be a vector [degrees minutes north/south] such as [40 50 north] for New
@ -106,7 +104,6 @@ This variable should be set in `site-start'.el."
(defcustom calendar-longitude nil (defcustom calendar-longitude nil
"Longitude of `calendar-location-name' in degrees. "Longitude of `calendar-location-name' in degrees.
The value can be either a decimal fraction (one place of accuracy is The value can be either a decimal fraction (one place of accuracy is
sufficient), + east, - west, such as -73.9 for New York City, or the value sufficient), + east, - west, such as -73.9 for New York City, or the value
can be a vector [degrees minutes east/west] such as [73 55 west] for New can be a vector [degrees minutes east/west] such as [73 55 west] for New
@ -140,9 +137,9 @@ This variable should be set in `site-start'.el."
(if (numberp calendar-longitude) (if (numberp calendar-longitude)
(if (> calendar-longitude 0) "E" "W") (if (> calendar-longitude 0) "E" "W")
(if (equal (aref calendar-longitude 2) 'east) "E" "W")))) (if (equal (aref calendar-longitude 2) 'east) "E" "W"))))
"Expression evaluating to name of `calendar-longitude', `calendar-latitude'. "Expression evaluating to the name of the calendar location.
For example, \"New York City\". Default value is just the latitude, longitude For example, \"New York City\". The default value is just the
pair. variable `calendar-latitude' paired with the variable `calendar-longitude'.
This variable should be set in `site-start'.el." This variable should be set in `site-start'.el."
:type 'sexp :type 'sexp
@ -191,7 +188,7 @@ Needed for polar areas, in order to know whether the day lasts 0 or 24 hours.")
(defsubst calendar-latitude () (defsubst calendar-latitude ()
"Convert calendar-latitude to a signed decimal fraction, if needed." "Ensure the variable `calendar-latitude' is a signed decimal fraction."
(if (numberp calendar-latitude) (if (numberp calendar-latitude)
calendar-latitude calendar-latitude
(let ((lat (+ (aref calendar-latitude 0) (let ((lat (+ (aref calendar-latitude 0)
@ -201,7 +198,7 @@ Needed for polar areas, in order to know whether the day lasts 0 or 24 hours.")
(- lat))))) (- lat)))))
(defsubst calendar-longitude () (defsubst calendar-longitude ()
"Convert calendar-longitude to a signed decimal fraction, if needed." "Ensure the variable `calendar-longitude' is a signed decimal fraction."
(if (numberp calendar-longitude) (if (numberp calendar-longitude)
calendar-longitude calendar-longitude
(let ((long (+ (aref calendar-longitude 0) (let ((long (+ (aref calendar-longitude 0)
@ -211,7 +208,7 @@ Needed for polar areas, in order to know whether the day lasts 0 or 24 hours.")
(- long))))) (- long)))))
(defun solar-setup () (defun solar-setup ()
"Prompt user for latitude, longitude, and time zone." "Prompt for `calendar-longitude', `calendar-latitude', `calendar-time-zone'."
(beep) (beep)
(or calendar-longitude (or calendar-longitude
(setq calendar-longitude (setq calendar-longitude
@ -235,22 +232,25 @@ Returns nil if nothing was entered."
(string-to-number x)))) (string-to-number x))))
(defun solar-sin-degrees (x) (defun solar-sin-degrees (x)
"Return sin of X degrees."
(sin (degrees-to-radians (mod x 360.0)))) (sin (degrees-to-radians (mod x 360.0))))
(defun solar-cosine-degrees (x) (defun solar-cosine-degrees (x)
"Return cosine of X degrees."
(cos (degrees-to-radians (mod x 360.0)))) (cos (degrees-to-radians (mod x 360.0))))
(defun solar-tangent-degrees (x) (defun solar-tangent-degrees (x)
"Return tangent of X degrees."
(tan (degrees-to-radians (mod x 360.0)))) (tan (degrees-to-radians (mod x 360.0))))
(defun solar-xy-to-quadrant (x y) (defun solar-xy-to-quadrant (x y)
"Determines the quadrant of the point X, Y." "Determine the quadrant of the point X, Y."
(if (> x 0) (if (> x 0)
(if (> y 0) 1 4) (if (> y 0) 1 4)
(if (> y 0) 2 3))) (if (> y 0) 2 3)))
(defun solar-degrees-to-quadrant (angle) (defun solar-degrees-to-quadrant (angle)
"Determines the quadrant of ANGLE." "Determine the quadrant of ANGLE degrees."
(1+ (floor (mod angle 360) 90))) (1+ (floor (mod angle 360) 90)))
(defun solar-arctan (x quad) (defun solar-arctan (x quad)
@ -262,13 +262,13 @@ Returns nil if nothing was entered."
(t deg)))) (t deg))))
(defun solar-atn2 (x y) (defun solar-atn2 (x y)
"Arctan of point X, Y." "Arctangent of point X, Y."
(if (zerop x) (if (zerop x)
(if (> y 0) 90 270) (if (> y 0) 90 270)
(solar-arctan (/ y x) (solar-xy-to-quadrant x y)))) (solar-arctan (/ y x) (solar-xy-to-quadrant x y))))
(defun solar-arccos (x) (defun solar-arccos (x)
"Arcos of X." "Arccosine of X."
(let ((y (sqrt (- 1 (* x x))))) (let ((y (sqrt (- 1 (* x x)))))
(solar-atn2 x y))) (solar-atn2 x y)))
@ -307,11 +307,11 @@ Parameters are the midday TIME and the LATITUDE, LONGITUDE of the location.
TIME is a pair with the first component being the number of Julian centuries TIME is a pair with the first component being the number of Julian centuries
elapsed at 0 Universal Time, and the second component being the universal elapsed at 0 Universal Time, and the second component being the universal
time. For instance, the pair corresponding to November 28, 1995 at 16 UT is time. For instance, the pair corresponding to November 28, 1995 at 16 UT is
\(-0.040945 16), -0.040945 being the number of julian centuries elapsed between \(-0.040945 16), -0.040945 being the number of Julian centuries elapsed between
Jan 1, 2000 at 12 UT and November 28, 1995 at 0 UT. Jan 1, 2000 at 12 UT and November 28, 1995 at 0 UT.
HEIGHT is the angle the center of the sun has over the horizon for the contact HEIGHT is the angle the center of the sun has over the horizon for the contact
we are trying to find. For sunrise and sunset, it is usually -0.61 degrees, we are trying to find. For sunrise and sunset, it is usually -0.61 degrees,
accounting for the edge of the sun being on the horizon. accounting for the edge of the sun being on the horizon.
Coordinates are included because this function is called with latitude=1 Coordinates are included because this function is called with latitude=1
@ -339,11 +339,11 @@ being TIME.
TIME is a pair with the first component being the number of Julian centuries TIME is a pair with the first component being the number of Julian centuries
elapsed at 0 Universal Time, and the second component being the universal elapsed at 0 Universal Time, and the second component being the universal
time. For instance, the pair corresponding to November 28, 1995 at 16 UT is time. For instance, the pair corresponding to November 28, 1995 at 16 UT is
\(-0.040945 16), -0.040945 being the number of julian centuries elapsed between \(-0.040945 16), -0.040945 being the number of Julian centuries elapsed between
Jan 1, 2000 at 12 UT and November 28, 1995 at 0 UT. Jan 1, 2000 at 12 UT and November 28, 1995 at 0 UT.
HEIGHT is the angle the center of the sun has over the horizon for the contact HEIGHT is the angle the center of the sun has over the horizon for the contact
we are trying to find. For sunrise and sunset, it is usually -0.61 degrees, we are trying to find. For sunrise and sunset, it is usually -0.61 degrees,
accounting for the edge of the sun being on the horizon. accounting for the edge of the sun being on the horizon.
Uses binary search." Uses binary search."
@ -395,14 +395,13 @@ Format used is given by `calendar-time-display-form'."
(defun solar-daylight (time) (defun solar-daylight (time)
"Printable form for time expressed in hours." "Printable form for TIME expressed in hours."
(format "%d:%02d" (format "%d:%02d"
(floor time) (floor time)
(floor (* 60 (- time (floor time)))))) (floor (* 60 (- time (floor time))))))
(defun solar-exact-local-noon (date) (defun solar-exact-local-noon (date)
"Date and Universal Time of local noon at *local date* date. "Date and Universal Time of local noon at *local date* DATE.
The date may be different from the one asked for, but it will be the right The date may be different from the one asked for, but it will be the right
local date. The second component of date should be an integer." local date. The second component of date should be an integer."
(let* ((nd date) (let* ((nd date)
@ -426,7 +425,6 @@ local date. The second component of date should be an integer."
(defun solar-sunrise-sunset (date) (defun solar-sunrise-sunset (date)
"List of *local* times of sunrise, sunset, and daylight on Gregorian DATE. "List of *local* times of sunrise, sunset, and daylight on Gregorian DATE.
Corresponding value is nil if there is no sunrise/sunset." Corresponding value is nil if there is no sunrise/sunset."
;; First, get the exact moment of local noon. ;; First, get the exact moment of local noon.
(let* ((exact-local-noon (solar-exact-local-noon date)) (let* ((exact-local-noon (solar-exact-local-noon date))
@ -478,21 +476,20 @@ Corresponding value is nil if there is no sunrise/sunset."
(car (cdr (cdr l)))))) (car (cdr (cdr l))))))
(defun solar-julian-ut-centuries (date) (defun solar-julian-ut-centuries (date)
"Number of Julian centuries elapsed since 1 Jan, 2000 at noon U.T. for Gregorian DATE." "Number of Julian centuries since 1 Jan, 2000 at noon UT for Gregorian DATE."
(/ (- (calendar-absolute-from-gregorian date) (/ (- (calendar-absolute-from-gregorian date)
(calendar-absolute-from-gregorian '(1 1.5 2000))) (calendar-absolute-from-gregorian '(1 1.5 2000)))
36525.0)) 36525.0))
(defun solar-ephemeris-time(time) (defun solar-ephemeris-time (time)
"Ephemeris Time at moment TIME. "Ephemeris Time at moment TIME.
TIME is a pair with the first component being the number of Julian centuries TIME is a pair with the first component being the number of Julian centuries
elapsed at 0 Universal Time, and the second component being the universal elapsed at 0 Universal Time, and the second component being the universal
time. For instance, the pair corresponding to November 28, 1995 at 16 UT is time. For instance, the pair corresponding to November 28, 1995 at 16 UT is
\(-0.040945 16), -0.040945 being the number of julian centuries elapsed between \(-0.040945 16), -0.040945 being the number of Julian centuries elapsed between
Jan 1, 2000 at 12 UT and November 28, 1995 at 0 UT. Jan 1, 2000 at 12 UT and November 28, 1995 at 0 UT.
Result is in julian centuries of ephemeris time." Result is in Julian centuries of ephemeris time."
(let* ((t0 (car time)) (let* ((t0 (car time))
(ut (car (cdr time))) (ut (car (cdr time)))
(t1 (+ t0 (/ (/ ut 24.0) 36525))) (t1 (+ t0 (/ (/ ut 24.0) 36525)))
@ -501,18 +498,14 @@ Result is in julian centuries of ephemeris time."
(+ t1 (/ (/ dt 86400) 36525)))) (+ t1 (/ (/ dt 86400) 36525))))
(defun solar-date-next-longitude (d l) (defun solar-date-next-longitude (d l)
"First moment on or after Julian day number D when sun's longitude is a "First time after day D when solar longitude is a multiple of L degrees.
multiple of L degrees at calendar-location-name with that location's D is a Julian day number. L must be an integer divisor of 360.
local time (including any daylight saving rules). The result is for `calendar-location-name', and is in local time
\(including any daylight saving rules) expressed in astronomical (Julian)
L must be an integer divisor of 360. day numbers. The values of `calendar-daylight-savings-starts',
`calendar-daylight-savings-starts-time', `calendar-daylight-savings-ends',
Result is in local time expressed astronomical (Julian) day numbers. `calendar-daylight-savings-ends-time', `calendar-daylight-time-offset',
and `calendar-time-zone' are used to interpret local time."
The values of calendar-daylight-savings-starts,
calendar-daylight-savings-starts-time, calendar-daylight-savings-ends,
calendar-daylight-savings-ends-time, calendar-daylight-time-offset, and
calendar-time-zone are used to interpret local time."
(let* ((long) (let* ((long)
(start d) (start d)
(start-long (solar-longitude d)) (start-long (solar-longitude d))
@ -536,24 +529,23 @@ calendar-time-zone are used to interpret local time."
(setq end-long long))) (setq end-long long)))
(/ (+ start end) 2.0))) (/ (+ start end) 2.0)))
(defun solar-horizontal-coordinates (defun solar-horizontal-coordinates (time latitude longitude sunrise-flag)
(time latitude longitude for-sunrise-sunset)
"Azimuth and height of the sun at TIME, LATITUDE, and LONGITUDE. "Azimuth and height of the sun at TIME, LATITUDE, and LONGITUDE.
TIME is a pair with the first component being the number of
TIME is a pair with the first component being the number of Julian centuries Julian centuries elapsed at 0 Universal Time, and the second
elapsed at 0 Universal Time, and the second component being the universal component being the universal time. For instance, the pair
time. For instance, the pair corresponding to November 28, 1995 at 16 UT is corresponding to November 28, 1995 at 16 UT is (-0.040945 16),
\(-0.040945 16), -0.040945 being the number of julian centuries elapsed between -0.040945 being the number of Julian centuries elapsed between
Jan 1, 2000 at 12 UT and November 28, 1995 at 0 UT. Jan 1, 2000 at 12 UT and November 28, 1995 at 0 UT. SUNRISE-FLAG
is passed to `solar-ecliptic-coordinates'. Azimuth and
The azimuth is given in degrees as well as the height (between -180 and 180)." height (between -180 and 180) are both in degrees."
(let* ((ut (car (cdr time))) (let* ((ut (cadr time))
(ec (solar-equatorial-coordinates time for-sunrise-sunset)) (ec (solar-equatorial-coordinates time sunrise-flag))
(st (+ solar-sidereal-time-greenwich-midnight (st (+ solar-sidereal-time-greenwich-midnight
(* ut 1.00273790935))) (* ut 1.00273790935)))
;; Hour angle (in degrees). ;; Hour angle (in degrees).
(ah (- (* st 15) (* 15 (car ec)) (* -1 (calendar-longitude)))) (ah (- (* st 15) (* 15 (car ec)) (* -1 (calendar-longitude))))
(de (car (cdr ec))) (de (cadr ec))
(azimuth (solar-atn2 (- (* (solar-cosine-degrees ah) (azimuth (solar-atn2 (- (* (solar-cosine-degrees ah)
(solar-sin-degrees latitude)) (solar-sin-degrees latitude))
(* (solar-tangent-degrees de) (* (solar-tangent-degrees de)
@ -567,24 +559,26 @@ The azimuth is given in degrees as well as the height (between -180 and 180)."
(if (> height 180) (setq height (- height 360))) (if (> height 180) (setq height (- height 360)))
(list azimuth height))) (list azimuth height)))
(defun solar-equatorial-coordinates (time for-sunrise-sunset) (defun solar-equatorial-coordinates (time sunrise-flag)
"Right ascension (in hours) and declination (in degrees) of the sun at TIME. "Right ascension (in hours) and declination (in degrees) of the sun at TIME.
TIME is a pair with the first component being the number of
TIME is a pair with the first component being the number of Julian centuries Julian centuries elapsed at 0 Universal Time, and the second
elapsed at 0 Universal Time, and the second component being the universal component being the universal time. For instance, the pair
time. For instance, the pair corresponding to November 28, 1995 at 16 UT is corresponding to November 28, 1995 at 16 UT is (-0.040945 16),
\(-0.040945 16), -0.040945 being the number of julian centuries elapsed between -0.040945 being the number of Julian centuries elapsed between
Jan 1, 2000 at 12 UT and November 28, 1995 at 0 UT." Jan 1, 2000 at 12 UT and November 28, 1995 at 0 UT. SUNRISE-FLAG is passed
to `solar-ecliptic-coordinates'."
(let* ((tm (solar-ephemeris-time time)) (let* ((tm (solar-ephemeris-time time))
(ec (solar-ecliptic-coordinates tm for-sunrise-sunset))) (ec (solar-ecliptic-coordinates tm sunrise-flag)))
(list (solar-right-ascension (car ec) (car (cdr ec))) (list (solar-right-ascension (car ec) (car (cdr ec)))
(solar-declination (car ec) (car (cdr ec)))))) (solar-declination (car ec) (car (cdr ec))))))
(defun solar-ecliptic-coordinates (time for-sunrise-sunset) (defun solar-ecliptic-coordinates (time sunrise-flag)
"Apparent longitude of the sun, ecliptic inclination, (both in degrees) "Return solar longitude, ecliptic inclination, equation of time, nutation.
equation of time (in hours) and nutation in longitude (in seconds) Values are for TIME in Julian centuries of Ephemeris Time since
at moment `time', expressed in julian centuries of Ephemeris Time January 1st, 2000, at 12 ET. Longitude and inclination are in
since January 1st, 2000, at 12 ET." degrees, equation of time in hours, and nutation in seconds of longitude.
If SUNRISE-FLAG is non-nil, only calculate longitude and inclination."
(let* ((l (+ 280.46645 (let* ((l (+ 280.46645
(* 36000.76983 time) (* 36000.76983 time)
(* 0.0003032 time time))) ; sun mean longitude (* 0.0003032 time time))) ; sun mean longitude
@ -610,35 +604,31 @@ since January 1st, 2000, at 12 ET."
(omega (+ 125.04 (omega (+ 125.04
(* -1934.136 time))) (* -1934.136 time)))
;; nut = nutation in longitude, measured in seconds of angle. ;; nut = nutation in longitude, measured in seconds of angle.
(nut (if (not for-sunrise-sunset) (nut (unless sunrise-flag
(+ (* -17.20 (solar-sin-degrees omega)) (+ (* -17.20 (solar-sin-degrees omega))
(* -1.32 (solar-sin-degrees (* 2 l))) (* -1.32 (solar-sin-degrees (* 2 l)))
(* -0.23 (solar-sin-degrees (* 2 ml))) (* -0.23 (solar-sin-degrees (* 2 ml)))
(* 0.21 (solar-sin-degrees (* 2 omega)))) (* 0.21 (solar-sin-degrees (* 2 omega))))))
nil)) (ecc (unless sunrise-flag ; eccentricity of earth's orbit
(ecc (if (not for-sunrise-sunset) (+ 0.016708617
(+ 0.016708617 (* -0.000042037 time)
(* -0.000042037 time) (* -0.0000001236 time time))))
(* -0.0000001236 time time)) ; eccentricity of earth's orbit (app (+ L ; apparent longitude of sun
nil))
(app (+ L
-0.00569 -0.00569
(* -0.00478 (* -0.00478
(solar-sin-degrees omega)))) ; apparent longitude of sun (solar-sin-degrees omega))))
(y (if (not for-sunrise-sunset) (y (unless sunrise-flag
(* (solar-tangent-degrees (/ i 2)) (* (solar-tangent-degrees (/ i 2))
(solar-tangent-degrees (/ i 2))) (solar-tangent-degrees (/ i 2)))))
nil))
;; Equation of time, in hours. ;; Equation of time, in hours.
(time-eq (if (not for-sunrise-sunset) (time-eq (unless sunrise-flag
(/ (* 12 (+ (* y (solar-sin-degrees (* 2 l))) (/ (* 12 (+ (* y (solar-sin-degrees (* 2 l)))
(* -2 ecc (solar-sin-degrees m)) (* -2 ecc (solar-sin-degrees m))
(* 4 ecc y (solar-sin-degrees m) (* 4 ecc y (solar-sin-degrees m)
(solar-cosine-degrees (* 2 l))) (solar-cosine-degrees (* 2 l)))
(* -0.5 y y (solar-sin-degrees (* 4 l))) (* -0.5 y y (solar-sin-degrees (* 4 l)))
(* -1.25 ecc ecc (solar-sin-degrees (* 2 m))))) (* -1.25 ecc ecc (solar-sin-degrees (* 2 m)))))
3.1415926535) 3.1415926535))))
nil)))
(list app i time-eq nut))) (list app i time-eq nut)))
(defconst solar-data-list (defconst solar-data-list
@ -691,16 +681,16 @@ since January 1st, 2000, at 12 ET."
(10 2.21 46941.14) (10 2.21 46941.14)
(10 3.59 -68.29) (10 3.59 -68.29)
(10 1.50 21463.25) (10 1.50 21463.25)
(10 2.55 157208.40))) (10 2.55 157208.40))
"Data used for calculation of solar longitude.")
(defun solar-longitude (d) (defun solar-longitude (d)
"Longitude of sun on astronomical (Julian) day number D. "Longitude of sun on astronomical (Julian) day number D.
Accurary is about 0.0006 degree (about 365.25*24*60*0.0006/360 = 1 minutes). Accuracy is about 0.0006 degree (about 365.25*24*60*0.0006/360 = 1 minutes).
The values of `calendar-daylight-savings-starts',
The values of calendar-daylight-savings-starts, `calendar-daylight-savings-starts-time', `calendar-daylight-savings-ends',
calendar-daylight-savings-starts-time, calendar-daylight-savings-ends, `calendar-daylight-savings-ends-time', `calendar-daylight-time-offset', and
calendar-daylight-savings-ends-time, calendar-daylight-time-offset, and `calendar-time-zone' are used to interpret local time."
calendar-time-zone are used to interpret local time."
(let* ((a-d (calendar-absolute-from-astro d)) (let* ((a-d (calendar-absolute-from-astro d))
;; Get Universal Time. ;; Get Universal Time.
(date (calendar-astro-from-absolute (date (calendar-astro-from-absolute
@ -736,11 +726,9 @@ calendar-time-zone are used to interpret local time."
(mod (radians-to-degrees (+ longitude aberration nutation)) 360.0))) (mod (radians-to-degrees (+ longitude aberration nutation)) 360.0)))
(defun solar-ephemeris-correction (year) (defun solar-ephemeris-correction (year)
"Ephemeris time minus Universal Time during Gregorian year. "Ephemeris time minus Universal Time during Gregorian YEAR.
Result is in days. Result is in days. For the years 1800-1987, the maximum error is
1.9 seconds. For the other years, the maximum error is about 30 seconds."
For the years 1800-1987, the maximum error is 1.9 seconds.
For the other years, the maximum error is about 30 seconds."
(cond ((and (<= 1988 year) (< year 2020)) (cond ((and (<= 1988 year) (< year 2020))
(/ (+ year -2000 67.0) 60.0 60.0 24.0)) (/ (+ year -2000 67.0) 60.0 60.0 24.0))
((and (<= 1900 year) (< year 1988)) ((and (<= 1900 year) (< year 1988))
@ -797,9 +785,7 @@ For the other years, the maximum error is about 30 seconds."
(/ second 60.0 60.0 24.0))))) (/ second 60.0 60.0 24.0)))))
(defun solar-sidereal-time (t0) (defun solar-sidereal-time (t0)
"Sidereal time (in hours) in Greenwich. "Sidereal time (in hours) in Greenwich at T0 Julian centuries.
At T0=Julian centuries of universal time.
T0 must correspond to 0 hours UT." T0 must correspond to 0 hours UT."
(let* ((mean-sid-time (+ 6.6973746 (let* ((mean-sid-time (+ 6.6973746
(* 2400.051337 t0) (* 2400.051337 t0)
@ -822,17 +808,16 @@ T0 must correspond to 0 hours UT."
(defun solar-date-to-et (date ut) (defun solar-date-to-et (date ut)
"Ephemeris Time at Gregorian DATE at Universal Time UT (in hours). "Ephemeris Time at Gregorian DATE at Universal Time UT (in hours).
Expressed in julian centuries of Ephemeris Time." Expressed in Julian centuries of Ephemeris Time."
(let ((t0 (solar-julian-ut-centuries date))) (let ((t0 (solar-julian-ut-centuries date)))
(solar-ephemeris-time (list t0 ut)))) (solar-ephemeris-time (list t0 ut))))
;;;###autoload ;;;###autoload
(defun sunrise-sunset (&optional arg) (defun sunrise-sunset (&optional arg)
"Local time of sunrise and sunset for today. Accurate to a few seconds. "Local time of sunrise and sunset for today. Accurate to a few seconds.
If called with an optional prefix argument, prompt for date. If called with an optional prefix argument ARG, prompt for date.
If called with an optional double prefix argument, prompt for
If called with an optional double prefix argument, prompt for longitude, longitude, latitude, time zone, and date, and always use standard time.
latitude, time zone, and date, and always use standard time.
This function is suitable for execution in a .emacs file." This function is suitable for execution in a .emacs file."
(interactive "p") (interactive "p")
@ -896,33 +881,38 @@ This function is suitable for execution in a .emacs file."
(if pop-up-windows (if pop-up-windows
"Type \\[delete-other-windows] to remove temp window." "Type \\[delete-other-windows] to remove temp window."
"Type \\[switch-to-buffer] RET to remove temp window.") "Type \\[switch-to-buffer] RET to remove temp window.")
"Type \\[switch-to-buffer-other-window] RET to restore old contents of temp window.")))))) "Type \\[switch-to-buffer-other-window] RET to restore old \
contents of temp window."))))))
(defun calendar-sunrise-sunset () (defun calendar-sunrise-sunset ()
"Local time of sunrise and sunset for date under cursor. "Local time of sunrise and sunset for date under cursor.
Accurate to a few seconds." Accurate to a few seconds."
(interactive) (interactive)
(if (not (and calendar-latitude calendar-longitude calendar-time-zone)) (or (and calendar-latitude calendar-longitude calendar-time-zone)
(solar-setup)) (solar-setup))
(let ((date (calendar-cursor-to-date t))) (let ((date (calendar-cursor-to-date t)))
(message "%s: %s" (message "%s: %s"
(calendar-date-string date t t) (calendar-date-string date t t)
(solar-sunrise-sunset-string date)))) (solar-sunrise-sunset-string date))))
(defvar date)
;; To be called from list-sexp-diary-entries, where DATE is bound.
(defun diary-sunrise-sunset () (defun diary-sunrise-sunset ()
"Local time of sunrise and sunset as a diary entry. "Local time of sunrise and sunset as a diary entry.
Accurate to a few seconds." Accurate to a few seconds."
(if (not (and calendar-latitude calendar-longitude calendar-time-zone)) (or (and calendar-latitude calendar-longitude calendar-time-zone)
(solar-setup)) (solar-setup))
(solar-sunrise-sunset-string date)) (solar-sunrise-sunset-string date))
;; To be called from list-sexp-diary-entries, where DATE is bound.
(defun diary-sabbath-candles (&optional mark) (defun diary-sabbath-candles (&optional mark)
"Local time of candle lighting diary entry--applies if date is a Friday. "Local time of candle lighting diary entry--applies if date is a Friday.
No diary entry if there is no sunset on that date. No diary entry if there is no sunset on that date.
An optional parameter MARK specifies a face or single-character string to An optional parameter MARK specifies a face or single-character string to
use when highlighting the day in the calendar." use when highlighting the day in the calendar."
(if (not (and calendar-latitude calendar-longitude calendar-time-zone)) (or (and calendar-latitude calendar-longitude calendar-time-zone)
(solar-setup)) (solar-setup))
(if (= (% (calendar-absolute-from-gregorian date) 7) 5) ; Friday (if (= (% (calendar-absolute-from-gregorian date) 7) 5) ; Friday
(let* ((sunset (car (cdr (solar-sunrise-sunset date)))) (let* ((sunset (car (cdr (solar-sunrise-sunset date))))
@ -960,15 +950,14 @@ use when highlighting the day in the calendar."
(12 287.11 31931.756) (12 287.11 31931.756)
(12 320.81 34777.259) (12 320.81 34777.259)
(9 227.73 1222.114) (9 227.73 1222.114)
(8 15.45 16859.074))) (8 15.45 16859.074))
"Data for solar equinox/solstice calculations.")
(defun solar-equinoxes/solstices (k year) (defun solar-equinoxes/solstices (k year)
"Date of equinox/solstice K for YEAR. "Date of equinox/solstice K for YEAR.
K=0, spring equinox; K=1, summer solstice; K=2, fall equinox; K=0, spring equinox; K=1, summer solstice; K=2, fall equinox;
K=3, winter solstice. K=3, winter solstice. RESULT is a Gregorian local date.
RESULT is a gregorian local date. Accurate to within a minute between 1951 and 2050."
Accurate to less than a minute between 1951 and 2050."
(let* ((JDE0 (solar-mean-equinoxes/solstices k year)) (let* ((JDE0 (solar-mean-equinoxes/solstices k year))
(T (/ (- JDE0 2451545.0) 36525)) (T (/ (- JDE0 2451545.0) 36525))
(W (- (* 35999.373 T) 2.47)) (W (- (* 35999.373 T) 2.47))