From 050839139d634150176b943d09953cd4cf511f5e Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Mon, 8 Jul 2019 03:13:28 +0200 Subject: Move some functions to time-date --- lisp/calendar/iso8601.el | 60 +++++++++++------------------------ lisp/calendar/time-date.el | 20 ++++++++++++ test/lisp/calendar/time-date-tests.el | 48 ++++++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 42 deletions(-) create mode 100644 test/lisp/calendar/time-date-tests.el diff --git a/lisp/calendar/iso8601.el b/lisp/calendar/iso8601.el index 3c2e31038eb..45004c46b4e 100644 --- a/lisp/calendar/iso8601.el +++ b/lisp/calendar/iso8601.el @@ -87,12 +87,12 @@ ;; Monday 29 December 2008 is written "2009-W01-1". ((< ordinal 1) (setq year (1- year) - ordinal (+ ordinal (iso8601-days-in-year year)))) + ordinal (+ ordinal (time-days-in-year year)))) ;; Sunday 3 January 2010 is written "2009-W53-7". ((> ordinal (iso8601-days-in-year year)) - (setq ordinal (- ordinal (iso8601-days-in-year year)) + (setq ordinal (- ordinal (time-days-in-year year)) year (1+ year)))) - (let ((month-day (iso8601-ordinal-to-date year ordinal))) + (let ((month-day (time-ordinal-to-date year ordinal))) (make-decoded-time :year year :month (car month-day) :day (cdr month-day))))) @@ -158,30 +158,6 @@ Return the number of minutes." (* (iso8601-parse-zone zone-string) 60))) date))) -(defun iso8601-days-in-year (year) - (if (and (zerop (% year 4)) - (if (zerop (% year 100)) - (not (zerop (% year 400))) - t)) - 366 - 365)) - -(defun iso8601-days-in-month (year month) - (if (= month 2) - (if (= (iso8601-days-in-year year) 365) - 28 - 29) - (if (memq month '(1 3 5 7 8 10 12)) - 31 - 30))) - -(defun iso8601-ordinal-to-date (year ordinal) - (let ((month 1)) - (while (> ordinal (iso8601-days-in-month year month)) - (setq ordinal (- ordinal (iso8601-days-in-month year month)) - month (1+ month))) - (cons month ordinal))) - (defun iso8601-parse-duration (string) "Parse ISO 8601 durations on the form P3Y6M4DT12H30M5S." (cond @@ -253,38 +229,38 @@ Return the number of minutes." ;; (format-time-string "%FT%T" (iso8601-parse-date "--0201")) ;; "0000-02-01T00:00:00" -;; (iso8601-days-in-year 1999) +;; (time-days-in-year 1999) ;; 365 -;; (iso8601-days-in-year 1900) +;; (time-days-in-year 1900) ;; 366 -;; (iso8601-days-in-year 1996) +;; (time-days-in-year 1996) ;; 366 -;; (iso8601-days-in-year 2000) +;; (time-days-in-year 2000) ;; 365 -;; (iso8601-days-in-month 2001 5) +;; (time-days-in-month 2001 5) ;; 31 -;; (iso8601-days-in-month 2004 2) +;; (time-days-in-month 2004 2) ;; 29 -;; (iso8601-days-in-month 2001 11) +;; (time-days-in-month 2001 11) ;; 30 -;; (iso8601-ordinal-to-date 2008 271) -;; (9 . 27) +;; (time-ordinal-to-date 2008 271) +;; (0 0 0 27 9 2008 nil nil nil) -;; (iso8601-ordinal-to-date 2008 1) -;; (1 . 1) +;; (time-ordinal-to-date 2008 1) +;; (0 0 0 1 1 2008 nil nil nil) -;; (iso8601-ordinal-to-date 2008 32) -;; (2 . 1) +;; (time-ordinal-to-date 2008 32) +;; (0 0 0 1 2 2008 nil nil nil) -;; (iso8601-ordinal-to-date 1981 095) -;; (4 . 5) +;; (time-ordinal-to-date 1981 095) +;; (0 0 0 5 4 1981 nil nil nil) ;; (format-time-string "%FT%T" (iso8601-parse-date "2008W39-6")) ;; "2008-09-27T01:00:00" diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el index 2c0280ccf3b..2535e972473 100644 --- a/lisp/calendar/time-date.el +++ b/lisp/calendar/time-date.el @@ -349,6 +349,26 @@ is output until the first non-zero unit is encountered." (<= (car here) delay))) (concat (format "%.2f" (/ delay (car (cddr here)))) (cadr here)))))) +(defun date-days-in-month (year month) + "The number of days in MONTH in YEAR." + (if (= month 2) + (if (date-leap-year-p year) + 29 + 28) + (if (memq month '(1 3 5 7 8 10 12)) + 31 + 30))) + +(defun time-ordinal-to-date (year ordinal) + "Convert a YEAR/ORDINAL to the equivalent `decoded-time' structure. +ORDINAL is the number of days since the start of the year, with +January 1st being 1." + (let ((month 1)) + (while (> ordinal (date-days-in-month year month)) + (setq ordinal (- ordinal (date-days-in-month year month)) + month (1+ month))) + (list 0 0 0 ordinal month year nil nil nil))) + (provide 'time-date) ;;; time-date.el ends here diff --git a/test/lisp/calendar/time-date-tests.el b/test/lisp/calendar/time-date-tests.el new file mode 100644 index 00000000000..803eaa1d80d --- /dev/null +++ b/test/lisp/calendar/time-date-tests.el @@ -0,0 +1,48 @@ +;;; time-date-tests.el --- tests for calendar/time-date.el -*- lexical-binding:t -*- + +;; Copyright (C) 2019 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Code: + +(require 'ert) +(require 'time-date) + +(ert-deftest test-leap-year () + (should-not (date-leap-year-p 1999)) + (should-not (date-leap-year-p 1900)) + (should (date-leap-year-p 2000)) + (should (date-leap-year-p 2004))) + +(ert-deftest test-days-in-month () + (should (= (date-days-in-month 2004 2) 29)) + (should (= (date-days-in-month 2004 3) 31)) + (should-not (= (date-days-in-month 1900 3) 28))) + +(ert-deftest test-ordinal () + (should (equal (time-ordinal-to-date 2008 271) + '(0 0 0 27 9 2008 nil nil nil))) + (should (equal (time-ordinal-to-date 2008 1) + '(0 0 0 1 1 2008 nil nil nil))) + (should (equal (time-ordinal-to-date 2008 32) + '(0 0 0 1 2 2008 nil nil nil))) + (should (equal (time-ordinal-to-date 1981 095) + '(0 0 0 5 4 1981 nil nil nil)))) + +(require 'ert) + +;;; time-date-tests.el ends here -- cgit v1.2.1