# HG changeset patch # User Edward M. Reingold # Date 783185654 0 # Node ID c14b023ca6fe0e1d80375025b7cc9264492be241 # Parent d62e29b1d7a2eb82552635cec959e6a9a24d3b1c Allow vector form of latitude/longitude. Fix documentation. diff -r d62e29b1d7a2 -r c14b023ca6fe lisp/calendar/solar.el --- a/lisp/calendar/solar.el Wed Oct 26 15:32:51 1994 +0000 +++ b/lisp/calendar/solar.el Wed Oct 26 15:34:14 1994 +0000 @@ -25,8 +25,8 @@ ;;; Commentary: -;; This collection of functions implements the features of calendar.el and -;; diary.el that deal with times of day, sunrise/sunset, and +;; This collection of functions implements the features of calendar.el, +;; diary.el, and holiday.el that deal with times of day, sunrise/sunset, and ;; eqinoxes/solstices. ;; Based on the ``Almanac for Computers 1984,'' prepared by the Nautical @@ -54,7 +54,7 @@ (if (fboundp 'atan) (require 'lisp-float-type) - (error "Solar calculations impossible since floating point is unavailable.")) + (error "Solar/lunar calculations impossible since floating point is unavailable.")) (require 'cal-dst) @@ -77,32 +77,69 @@ ;;;###autoload (defvar calendar-latitude nil - "*Latitude of `calendar-location-name' in degrees, + north, - south. -For example, 40.7 for New York City. -It may not be a good idea to set this in advance for your site; -if there may be users running Emacs at your site -who are physically located elsewhere, they would get the wrong -value and might not know how to override it.") + "*Latitude of `calendar-location-name' in degrees. + +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 +can be a vector [degrees minutes north/south] such as [40 50 north] for New +York City. + +This variable should be set in site-local.el.") ;;;###autoload (defvar calendar-longitude nil - "*Longitude of `calendar-location-name' in degrees, + east, - west. -For example, -74.0 for New York City. -It may not be a good idea to set this in advance for your site; -if there may be users running Emacs at your site -who are physically located elsewhere, they would get the wrong -value and might not know how to override it.") + "*Longitude of `calendar-location-name' in degrees. + +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 +can be a vector [degrees minutes east/west] such as [73 55 west] for New +York City. + +This variable should be set in site-local.el.") + +(defsubst calendar-latitude () + "Convert calendar-latitude to a signed decimal fraction, if needed." + (if (numberp calendar-latitude) + calendar-latitude + (let ((lat (+ (aref calendar-latitude 0) + (/ (aref calendar-latitude 1) 60.0)))) + (if (equal (aref calendar-latitude 2) 'north) + lat + (- lat))))) + +(defsubst calendar-longitude () + "Convert calendar-longitude to a signed decimal fraction, if needed." + (if (numberp calendar-longitude) + calendar-longitude + (let ((long (+ (aref calendar-longitude 0) + (/ (aref calendar-longitude 1) 60.0)))) + (if (equal (aref calendar-longitude 2) 'east) + long + (- long))))) ;;;###autoload (defvar calendar-location-name '(let ((float-output-format "%.1f")) (format "%s%s, %s%s" - (abs calendar-latitude) - (if (> calendar-latitude 0) "N" "S") - (abs calendar-longitude) - (if (> calendar-longitude 0) "E" "W"))) + (if (numberp calendar-latitude) + (abs calendar-latitude) + (+ (aref calendar-latitude 0) + (/ (aref calendar-latitude 1) 60.0))) + (if (numberp calendar-latitude) + (if (> calendar-latitude 0) "N" "S") + (if (equal (aref calendar-latitude 2) 'north) "N" "S")) + (if (numberp calendar-longitude) + (abs calendar-longitude) + (+ (aref calendar-longitude 0) + (/ (aref calendar-longitude 1) 60.0))) + (if (numberp calendar-longitude) + (if (> calendar-longitude 0) "E" "W") + (if (equal (aref calendar-latitude 2) 'east) "E" "W")))) "*Expression evaluating to name of `calendar-longitude', calendar-latitude'. -Default value is just the latitude, longitude pair.") +For example, \"New York City\". Default value is just the latitude, longitude +pair. + +This variable should be set in site-local.el.") (defvar solar-n-hemi-seasons '("Vernal Equinox" "Summer Solstice" "Autumnal Equinox" "Winter Solstice") @@ -135,10 +172,10 @@ (if (not (string-equal x "")) (string-to-int x)))) -(defun solar-sin-degrees (x) +(defsubst solar-sin-degrees (x) (sin (degrees-to-radians x))) -(defun solar-cosine-degrees (x) +(defsubst solar-cosine-degrees (x) (cos (degrees-to-radians x))) (defun solar-tangent-degrees (x) @@ -182,11 +219,11 @@ (defconst solar-earth-orbit-eccentricity 0.016718 "Eccentricity of orbit of the earth around the sun.") -(defmacro solar-degrees-to-hours (deg) - (list '/ deg 15.0)) +(defsubst solar-degrees-to-hours (deg) + (/ deg 15.0)) -(defmacro solar-hours-to-days (hour) - (list '/ hour 24.0)) +(defsubst solar-hours-to-days (hour) + (/ hour 24.0)) (defun solar-longitude-of-sun (day) "Longitude of the sun at DAY in the year." @@ -221,7 +258,7 @@ (approx-sunrise (+ day-of-year (solar-hours-to-days - (- 6 (solar-degrees-to-hours calendar-longitude))))) + (- 6 (solar-degrees-to-hours (calendar-longitude)))))) (solar-longitude-of-sun-at-sunrise (solar-longitude-of-sun approx-sunrise)) (solar-right-ascension-at-sunrise @@ -231,9 +268,9 @@ (cos-local-sunrise (/ (- (solar-cosine-degrees (+ 90 (/ 50.0 60.0))) (* (solar-sin-degrees solar-declination-at-sunrise) - (solar-sin-degrees calendar-latitude))) + (solar-sin-degrees (calendar-latitude)))) (* (solar-cosine-degrees solar-declination-at-sunrise) - (solar-cosine-degrees calendar-latitude))))) + (solar-cosine-degrees (calendar-latitude)))))) (if (<= (abs cos-local-sunrise) 1);; otherwise, no sunrise that day (let* ((local-sunrise (solar-degrees-to-hours (- 360 (solar-arccos cos-local-sunrise)))) @@ -242,7 +279,7 @@ (+ (* 0.065710 approx-sunrise) 6.622)) 24))) - (+ (- local-mean-sunrise (solar-degrees-to-hours calendar-longitude)) + (+ (- local-mean-sunrise (solar-degrees-to-hours (calendar-longitude))) (/ calendar-time-zone 60.0)))))) (defun solar-sunset (date) @@ -256,7 +293,7 @@ (approx-sunset (+ day-of-year (solar-hours-to-days - (- 18 (solar-degrees-to-hours calendar-longitude))))) + (- 18 (solar-degrees-to-hours (calendar-longitude)))))) (solar-longitude-of-sun-at-sunset (solar-longitude-of-sun approx-sunset)) (solar-right-ascension-at-sunset @@ -266,9 +303,9 @@ (cos-local-sunset (/ (- (solar-cosine-degrees (+ 90 (/ 50.0 60.0))) (* (solar-sin-degrees solar-declination-at-sunset) - (solar-sin-degrees calendar-latitude))) + (solar-sin-degrees (calendar-latitude)))) (* (solar-cosine-degrees solar-declination-at-sunset) - (solar-cosine-degrees calendar-latitude))))) + (solar-cosine-degrees (calendar-latitude)))))) (if (<= (abs cos-local-sunset) 1);; otherwise, no sunset that day (let* ((local-sunset (solar-degrees-to-hours (solar-arccos cos-local-sunset))) @@ -276,7 +313,7 @@ (mod (- (+ local-sunset solar-right-ascension-at-sunset) (+ (* 0.065710 approx-sunset) 6.622)) 24))) - (+ (- local-mean-sunset (solar-degrees-to-hours calendar-longitude)) + (+ (- local-mean-sunset (solar-degrees-to-hours (calendar-longitude))) (/ calendar-time-zone 60.0)))))) (defun solar-adj-time-for-dst (date time &optional style) @@ -441,10 +478,21 @@ (if (< arg 16) calendar-location-name (let ((float-output-format "%.1f")) (format "%s%s, %s%s" - (abs calendar-latitude) - (if (> calendar-latitude 0) "N" "S") - (abs calendar-longitude) - (if (> calendar-longitude 0) "E" "W"))))) + (if (numberp calendar-latitude) + (abs calendar-latitude) + (+ (aref calendar-latitude 0) + (/ (aref calendar-latitude 1) 60.0))) + (if (numberp calendar-latitude) + (if (> calendar-latitude 0) "N" "S") + (if (equal (aref calendar-latitude 2) 'north) "N" "S")) + (if (numberp calendar-longitude) + (abs calendar-longitude) + (+ (aref calendar-longitude 0) + (/ (aref calendar-longitude 1) 60.0))) + (if (numberp calendar-longitude) + (if (> calendar-longitude 0) "E" "W") + (if (equal (aref calendar-latitude 2) 'east) + "E" "W")))))) (calendar-standard-time-zone-name (if (< arg 16) calendar-standard-time-zone-name (cond ((= calendar-time-zone 0) "UTC") @@ -522,7 +570,7 @@ (calendar-time-zone (if calendar-time-zone calendar-time-zone 0)) (k (1- (/ m 3))) (date (solar-equinoxes/solstices k y)) - (s-hemi (and calendar-latitude (< calendar-latitude 0))) + (s-hemi (and calendar-latitude (< (calendar-latitude) 0))) (day (extract-calendar-day date)) (adj (solar-adj-time-for-dst (list (extract-calendar-month date)