cal-iso.el 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. ;;; cal-iso.el --- calendar functions for the ISO calendar
  2. ;; Copyright (C) 1995, 1997, 2001-2012 Free Software Foundation, Inc.
  3. ;; Author: Edward M. Reingold <reingold@cs.uiuc.edu>
  4. ;; Maintainer: Glenn Morris <rgm@gnu.org>
  5. ;; Keywords: calendar
  6. ;; Human-Keywords: ISO calendar, calendar, diary
  7. ;; Package: calendar
  8. ;; This file is part of GNU Emacs.
  9. ;; GNU Emacs is free software: you can redistribute it and/or modify
  10. ;; it under the terms of the GNU General Public License as published by
  11. ;; the Free Software Foundation, either version 3 of the License, or
  12. ;; (at your option) any later version.
  13. ;; GNU Emacs is distributed in the hope that it will be useful,
  14. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. ;; GNU General Public License for more details.
  17. ;; You should have received a copy of the GNU General Public License
  18. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  19. ;;; Commentary:
  20. ;; See calendar.el.
  21. ;;; Code:
  22. (require 'calendar)
  23. (defun calendar-iso-to-absolute (date)
  24. "The number of days elapsed between the Gregorian date 12/31/1 BC and DATE.
  25. The `ISO year' corresponds approximately to the Gregorian year, but
  26. weeks start on Monday and end on Sunday. The first week of the ISO year is
  27. the first such week in which at least 4 days are in a year. The ISO
  28. commercial DATE has the form (week day year) in which week is in the range
  29. 1..52 and day is in the range 0..6 (1 = Monday, 2 = Tuesday, ..., 0 =
  30. Sunday). The Gregorian date Sunday, December 31, 1 BC is imaginary."
  31. (let ((day (calendar-extract-day date)))
  32. (+ (calendar-dayname-on-or-before
  33. 1 (+ 3 (calendar-absolute-from-gregorian
  34. (list 1 1 (calendar-extract-year date)))))
  35. ;; ISO date is (week day year); normally (month day year).
  36. (* 7 (1- (calendar-extract-month date)))
  37. (if (zerop day) 6 (1- day)))))
  38. (define-obsolete-function-alias 'calendar-absolute-from-iso
  39. 'calendar-iso-to-absolute "23.1")
  40. ;;;###cal-autoload
  41. (defun calendar-iso-from-absolute (date)
  42. "Compute the `ISO commercial date' corresponding to the absolute DATE.
  43. The ISO year corresponds approximately to the Gregorian year, but weeks
  44. start on Monday and end on Sunday. The first week of the ISO year is the
  45. first such week in which at least 4 days are in a year. The ISO commercial
  46. date has the form (week day year) in which week is in the range 1..52 and
  47. day is in the range 0..6 (1 = Monday, 2 = Tuesday, ..., 0 = Sunday). The
  48. absolute date is the number of days elapsed since the (imaginary) Gregorian
  49. date Sunday, December 31, 1 BC."
  50. (let* ((approx (calendar-extract-year
  51. (calendar-gregorian-from-absolute (- date 3))))
  52. (year (+ approx
  53. (calendar-sum y approx
  54. (>= date (calendar-iso-to-absolute
  55. (list 1 1 (1+ y))))
  56. 1))))
  57. (list
  58. (1+ (/ (- date (calendar-iso-to-absolute (list 1 1 year))) 7))
  59. (% date 7)
  60. year)))
  61. ;;;###cal-autoload
  62. (defun calendar-iso-date-string (&optional date)
  63. "String of ISO date of Gregorian DATE, default today."
  64. (let* ((d (calendar-absolute-from-gregorian
  65. (or date (calendar-current-date))))
  66. (day (% d 7))
  67. (iso-date (calendar-iso-from-absolute d)))
  68. (format "Day %s of week %d of %d"
  69. (if (zerop day) 7 day)
  70. (calendar-extract-month iso-date)
  71. (calendar-extract-year iso-date))))
  72. ;;;###cal-autoload
  73. (defun calendar-iso-print-date ()
  74. "Show equivalent ISO date for the date under the cursor."
  75. (interactive)
  76. (message "ISO date: %s"
  77. (calendar-iso-date-string (calendar-cursor-to-date t))))
  78. (define-obsolete-function-alias 'calendar-print-iso-date
  79. 'calendar-iso-print-date "23.1")
  80. (defun calendar-iso-read-date (&optional dayflag)
  81. "Interactively read the arguments for an ISO date command.
  82. Reads a year and week, and if DAYFLAG is non-nil a day (otherwise
  83. taken to be 1)."
  84. (let* ((year (calendar-read
  85. "ISO calendar year (>0): "
  86. (lambda (x) (> x 0))
  87. (number-to-string (calendar-extract-year
  88. (calendar-current-date)))))
  89. (no-weeks (calendar-extract-month
  90. (calendar-iso-from-absolute
  91. (1-
  92. (calendar-dayname-on-or-before
  93. 1 (calendar-absolute-from-gregorian
  94. (list 1 4 (1+ year))))))))
  95. (week (calendar-read
  96. (format "ISO calendar week (1-%d): " no-weeks)
  97. (lambda (x) (and (> x 0) (<= x no-weeks)))))
  98. (day (if dayflag (calendar-read
  99. "ISO day (1-7): "
  100. (lambda (x) (and (<= 1 x) (<= x 7))))
  101. 1)))
  102. (list (list week day year))))
  103. (define-obsolete-function-alias 'calendar-iso-read-args
  104. 'calendar-iso-read-date "23.1")
  105. ;;;###cal-autoload
  106. (defun calendar-iso-goto-date (date &optional noecho)
  107. "Move cursor to ISO DATE; echo ISO date unless NOECHO is non-nil."
  108. (interactive (calendar-iso-read-date t))
  109. (calendar-goto-date (calendar-gregorian-from-absolute
  110. (calendar-iso-to-absolute date)))
  111. (or noecho (calendar-iso-print-date)))
  112. (define-obsolete-function-alias 'calendar-goto-iso-date
  113. 'calendar-iso-goto-date "23.1")
  114. ;;;###cal-autoload
  115. (defun calendar-iso-goto-week (date &optional noecho)
  116. "Move cursor to ISO DATE; echo ISO date unless NOECHO is non-nil.
  117. Interactively, goes to the first day of the specified week."
  118. (interactive (calendar-iso-read-date))
  119. (calendar-goto-date (calendar-gregorian-from-absolute
  120. (calendar-iso-to-absolute date)))
  121. (or noecho (calendar-iso-print-date)))
  122. (define-obsolete-function-alias 'calendar-goto-iso-week
  123. 'calendar-iso-goto-week "23.1")
  124. (defvar date)
  125. ;; To be called from diary-list-sexp-entries, where DATE is bound.
  126. ;;;###diary-autoload
  127. (defun diary-iso-date ()
  128. "ISO calendar equivalent of date diary entry."
  129. (format "ISO date: %s" (calendar-iso-date-string date)))
  130. (provide 'cal-iso)
  131. ;;; cal-iso.el ends here