Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs
This commit is contained in:
commit
abd3fdf7b8
15 changed files with 344 additions and 311 deletions
|
@ -1478,23 +1478,23 @@ Although @code{(time-convert nil nil)} is equivalent to
|
|||
@end example
|
||||
@end defun
|
||||
|
||||
@defun decode-time &optional time zone
|
||||
@defun decode-time &optional time zone form
|
||||
This function converts a time value into calendrical information. If
|
||||
you don't specify @var{time}, it decodes the current time, and similarly
|
||||
@var{zone} defaults to the current time zone rule. @xref{Time Zone Rules}.
|
||||
The return value is a list of ten elements, as follows:
|
||||
The @var{form} argument controls the form of the returned
|
||||
@var{seconds} element, as described below.
|
||||
The return value is a list of nine elements, as follows:
|
||||
|
||||
@example
|
||||
(@var{seconds} @var{minutes} @var{hour} @var{day} @var{month} @var{year}
|
||||
@var{dow} @var{dst} @var{utcoff} @var{subsec})
|
||||
(@var{seconds} @var{minutes} @var{hour} @var{day} @var{month} @var{year} @var{dow} @var{dst} @var{utcoff})
|
||||
@end example
|
||||
|
||||
Here is what the elements mean:
|
||||
|
||||
@table @var
|
||||
@item seconds
|
||||
The number of seconds past the minute, as an integer between 0 and 59.
|
||||
On some operating systems, this is 60 for leap seconds.
|
||||
The number of seconds past the minute, with form described below.
|
||||
@item minutes
|
||||
The number of minutes past the hour, as an integer between 0 and 59.
|
||||
@item hour
|
||||
|
@ -1514,22 +1514,33 @@ in effect, and @minus{}1 if this information is not available.
|
|||
@item utcoff
|
||||
An integer indicating the Universal Time offset in seconds, i.e., the number of
|
||||
seconds east of Greenwich.
|
||||
@item subsec
|
||||
The number of subseconds past the second, as either 0 or a Lisp
|
||||
timestamp @code{(@var{ticks} . @var{hz})} representing a nonnegative
|
||||
fraction less than 1.
|
||||
@end table
|
||||
|
||||
The @var{seconds} element is a Lisp timestamp that is nonnegative and
|
||||
less than 61; it is less than 60 except during positive leap seconds
|
||||
(assuming the operating system supports leap seconds). If the
|
||||
optional @var{form} argument is @code{t}, @var{seconds} uses the same
|
||||
precision as @var{time}; if @var{form} is @code{integer},
|
||||
@var{seconds} is truncated to an integer. For example, if @var{time}
|
||||
is the timestamp @code{(1566009571321 . 1000)}, which represents
|
||||
2019-08-17 02:39:31.321 UTC on typical systems that lack leap seconds,
|
||||
then @code{(decode-time @var{time} t t)} returns @code{((31321 . 1000)
|
||||
39 2 17 8 2019 6 nil 0)}, whereas @code{(decode-time @var{time} t
|
||||
'integer)} returns @code{(31 39 2 17 8 2019 6 nil 0)}. If @var{form}
|
||||
is omitted or @code{nil}, it currently defaults to @code{integer} but
|
||||
this default may change in future Emacs releases, so callers requiring
|
||||
a particular form should specify @var{form}.
|
||||
|
||||
@strong{Common Lisp Note:} Common Lisp has different meanings for
|
||||
@var{dow} and @var{utcoff}, and lacks @var{subsec}.
|
||||
@var{dow} and @var{utcoff}, and its @var{second} is an integer between
|
||||
0 and 59 inclusive.
|
||||
|
||||
To access (or alter) the elements in the time value, the
|
||||
@code{decoded-time-second}, @code{decoded-time-minute},
|
||||
@code{decoded-time-hour}, @code{decoded-time-day},
|
||||
@code{decoded-time-month}, @code{decoded-time-year},
|
||||
@code{decoded-time-weekday}, @code{decoded-time-dst},
|
||||
@code{decoded-time-zone} and @code{decoded-time-subsec}
|
||||
accessors can be used.
|
||||
@code{decoded-time-weekday}, @code{decoded-time-dst} and
|
||||
@code{decoded-time-zone} accessors can be used.
|
||||
|
||||
For instance, to increase the year in a decoded time, you could say:
|
||||
|
||||
|
@ -1551,7 +1562,7 @@ For instance, if you want ``same time next month'', you
|
|||
could say:
|
||||
|
||||
@lisp
|
||||
(let ((time (decode-time))
|
||||
(let ((time (decode-time nil nil t))
|
||||
(delta (make-decoded-time :month 2)))
|
||||
(encode-time (decoded-time-add time delta)))
|
||||
@end lisp
|
||||
|
@ -1585,22 +1596,21 @@ It can act as the inverse of @code{decode-time}.
|
|||
|
||||
Ordinarily the first argument is a list
|
||||
@code{(@var{second} @var{minute} @var{hour} @var{day} @var{month}
|
||||
@var{year} @var{ignored} @var{dst} @var{zone} @var{subsec})} that specifies a
|
||||
@var{year} @var{ignored} @var{dst} @var{zone})} that specifies a
|
||||
decoded time in the style of @code{decode-time}, so that
|
||||
@code{(encode-time (decode-time ...))} works. For the meanings of
|
||||
these list members, see the table under @code{decode-time}.
|
||||
|
||||
As an obsolescent calling convention, this function can be given six
|
||||
through ten arguments. The first six arguments @var{second},
|
||||
or more arguments. The first six arguments @var{second},
|
||||
@var{minute}, @var{hour}, @var{day}, @var{month}, and @var{year}
|
||||
specify most of the components of a decoded time. If there are seven
|
||||
through nine arguments the @emph{last} argument is used as @var{zone},
|
||||
and if there are ten arguments the ninth specifies @var{zone} and the
|
||||
tenth specifies @var{subsec}; in either case any other extra arguments
|
||||
are ignored, so that @code{(apply #'encode-time (decode-time ...))}
|
||||
works. In this obsolescent convention, @var{zone} defaults to the
|
||||
current time zone rule (@pxref{Time Zone Rules}), @var{subsec}
|
||||
defaults to 0, and @var{dst} is treated as if it was @minus{}1.
|
||||
specify most of the components of a decoded time. If there are more
|
||||
than six arguments the @emph{last} argument is used as @var{zone} and
|
||||
any other extra arguments are ignored, so that @code{(apply
|
||||
#'encode-time (decode-time ...))} works. In this obsolescent
|
||||
convention, @var{zone} defaults to the current time zone rule
|
||||
(@pxref{Time Zone Rules}), and @var{dst} is treated as if it was
|
||||
@minus{}1.
|
||||
|
||||
Year numbers less than 100 are not treated specially. If you want them
|
||||
to stand for years above 1900, or years above 2000, you must alter them
|
||||
|
@ -1615,9 +1625,8 @@ the latter to the former as follows:
|
|||
@end example
|
||||
|
||||
You can perform simple date arithmetic by using out-of-range values for
|
||||
@var{seconds}, @var{minutes}, @var{hour}, @var{day}, @var{month}, and
|
||||
@var{subsec}; for example, day 0 means the day preceding the given
|
||||
month.
|
||||
@var{seconds}, @var{minutes}, @var{hour}, @var{day}, and @var{month};
|
||||
for example, day 0 means the day preceding the given month.
|
||||
|
||||
The operating system puts limits on the range of possible time values;
|
||||
if the limits are exceeded while encoding the time, an error results.
|
||||
|
|
|
@ -1535,7 +1535,7 @@ Here's a bunch of time/date/second/day examples:
|
|||
|
||||
@example
|
||||
(parse-time-string "Sat Sep 12 12:21:54 1998 +0200")
|
||||
@result{} (54 21 12 12 9 1998 6 -1 7200 0)
|
||||
@result{} (54 21 12 12 9 1998 6 -1 7200)
|
||||
|
||||
(time-convert
|
||||
(date-to-time "Sat Sep 12 12:21:54 1998 +0200")
|
||||
|
|
22
etc/NEWS
22
etc/NEWS
|
@ -2116,10 +2116,20 @@ probing the innards of a timestamp directly, or creating a timestamp
|
|||
by hand.
|
||||
|
||||
+++
|
||||
*** Decoded (calendrical) timestamps now have a new subsecond member.
|
||||
This affects functions like decode-time and parse-time-string that
|
||||
generate these timestamps, and functions like encode-time that accept
|
||||
them.
|
||||
*** Decoded (calendrical) timestamps now have subsecond resolution.
|
||||
This affects decode-time, which generates these timestamps, as well as
|
||||
functions like encode-time that accept them. The subsecond info is
|
||||
present as a (TICKS . HZ) value in the seconds element of a decoded
|
||||
timestamp, and decode-time has a new optional FORM argument specifying
|
||||
the form of the seconds member. For example, if X is the timestamp
|
||||
(1566009571321878186 . 1000000000), which represents 2019-08-17
|
||||
02:39:31.321878186 UTC, (decode-time X t t) returns ((31321878186
|
||||
. 1000000000) 39 2 17 8 2019 6 nil 0) instead of the traditional (31
|
||||
39 2 17 8 2019 6 nil 0) returned by plain (decode-time X t). Although
|
||||
the default FORM is currently 'integer', which truncates the seconds
|
||||
to an integer and is the traditional behavior, this default may change
|
||||
in future Emacs versions, so callers requiring an integer should
|
||||
specify FORM explicitly.
|
||||
|
||||
+++
|
||||
*** 'encode-time' supports a new API '(encode-time TIME)'.
|
||||
|
@ -2152,8 +2162,8 @@ with POSIX.1-2017.
|
|||
*** To access (or alter) the elements a decoded time value, the
|
||||
'decoded-time-second', 'decoded-time-minute', 'decoded-time-hour',
|
||||
'decoded-time-day', 'decoded-time-month', 'decoded-time-year',
|
||||
'decoded-time-weekday', 'decoded-time-dst', 'decoded-time-zone',
|
||||
and 'decoded-time-subsec' accessors can be used.
|
||||
'decoded-time-weekday', 'decoded-time-dst' and 'decoded-time-zone'
|
||||
accessors can be used.
|
||||
|
||||
*** The new functions 'date-days-in-month' (which will say how many
|
||||
days there are in a month in a specific year), 'date-ordinal-to-time'
|
||||
|
|
|
@ -644,7 +644,7 @@ FIXME: multiple comma-separated values should be allowed!"
|
|||
;; create the decoded date-time
|
||||
;; FIXME!?!
|
||||
(let ((decoded-time (list second minute hour day month year
|
||||
nil -1 zone 0)))
|
||||
nil -1 zone)))
|
||||
(condition-case nil
|
||||
(decode-time (encode-time decoded-time))
|
||||
(error
|
||||
|
|
|
@ -129,8 +129,7 @@ well as variants like \"2008W32\" (week number) and
|
|||
(let ((time (iso8601-parse-time time-string)))
|
||||
(setf (decoded-time-hour date) (decoded-time-hour time))
|
||||
(setf (decoded-time-minute date) (decoded-time-minute time))
|
||||
(setf (decoded-time-second date) (decoded-time-second time))
|
||||
(setf (decoded-time-subsec date) (decoded-time-subsec time))))
|
||||
(setf (decoded-time-second date) (decoded-time-second time))))
|
||||
;; The time zone is optional.
|
||||
(when zone-string
|
||||
(setf (decoded-time-zone date)
|
||||
|
@ -237,8 +236,6 @@ well as variants like \"2008W32\" (week number) and
|
|||
(iso8601--decoded-time :hour hour
|
||||
:minute (or minute 0)
|
||||
:second (or second 0)
|
||||
;; FIXME: Support subsec.
|
||||
:subsec 0
|
||||
:zone (and zone
|
||||
(* 60 (iso8601-parse-zone
|
||||
zone)))))))))
|
||||
|
@ -277,9 +274,7 @@ Return the number of minutes."
|
|||
:day (or (match-string 3 string) 0)
|
||||
:hour (or (match-string 5 string) 0)
|
||||
:minute (or (match-string 6 string) 0)
|
||||
:second (or (match-string 7 string) 0)
|
||||
;; FIXME: Support subsec.
|
||||
:subsec 0))
|
||||
:second (or (match-string 7 string) 0)))
|
||||
;; PnW: Weeks.
|
||||
((iso8601--match iso8601--duration-week-match string)
|
||||
(let ((weeks (string-to-number (match-string 1 string))))
|
||||
|
@ -341,7 +336,7 @@ Return the number of minutes."
|
|||
|
||||
(cl-defun iso8601--decoded-time (&key second minute hour
|
||||
day month year
|
||||
dst zone subsec)
|
||||
dst zone)
|
||||
(list (iso8601--value second)
|
||||
(iso8601--value minute)
|
||||
(iso8601--value hour)
|
||||
|
@ -350,8 +345,7 @@ Return the number of minutes."
|
|||
(iso8601--value year)
|
||||
nil
|
||||
dst
|
||||
zone
|
||||
subsec))
|
||||
zone))
|
||||
|
||||
(defun iso8601--encode-time (time)
|
||||
"Like `encode-time', but fill in nil values in TIME."
|
||||
|
|
|
@ -148,7 +148,7 @@ letters, digits, plus or minus signs or colons."
|
|||
|
||||
;;;###autoload
|
||||
(defun parse-time-string (string)
|
||||
"Parse the time in STRING into (SEC MIN HOUR DAY MON YEAR DOW DST TZ SUBSEC).
|
||||
"Parse the time in STRING into (SEC MIN HOUR DAY MON YEAR DOW DST TZ).
|
||||
STRING should be something resembling an RFC 822 (or later) date-time, e.g.,
|
||||
\"Fri, 25 Mar 2016 16:24:56 +0100\", but this function is
|
||||
somewhat liberal in what format it accepts, and will attempt to
|
||||
|
@ -156,7 +156,7 @@ return a \"likely\" value even for somewhat malformed strings.
|
|||
The values returned are identical to those of `decode-time', but
|
||||
any unknown values other than DST are returned as nil, and an
|
||||
unknown DST value is returned as -1."
|
||||
(let ((time (list nil nil nil nil nil nil nil -1 nil nil))
|
||||
(let ((time (list nil nil nil nil nil nil nil -1 nil))
|
||||
(temp (parse-time-tokenize (downcase string))))
|
||||
(while temp
|
||||
(let ((parse-time-elt (pop temp))
|
||||
|
@ -193,10 +193,6 @@ unknown DST value is returned as -1."
|
|||
(funcall this)))
|
||||
parse-time-val)))
|
||||
(setf (nth (pop slots) time) new-val))))))))
|
||||
;; FIXME: Currently parse-time-string does not parse subseconds.
|
||||
;; So if seconds were found, set subseconds to zero.
|
||||
(when (nth 0 time)
|
||||
(setf (nth 9 time) 0))
|
||||
time))
|
||||
|
||||
(defun parse-iso8601-time-string (date-string)
|
||||
|
|
|
@ -420,26 +420,13 @@ changes in daylight saving time are not taken into account."
|
|||
|
||||
;; Do the time part, which is pretty simple (except for leap
|
||||
;; seconds, I guess).
|
||||
(setq seconds (+ (* (or (decoded-time-hour delta) 0) 3600)
|
||||
(* (or (decoded-time-minute delta) 0) 60)
|
||||
(or (decoded-time-second delta) 0)))
|
||||
(when (decoded-time-subsec delta)
|
||||
(let* ((subsec (time-convert (time-add (decoded-time-subsec time)
|
||||
(decoded-time-subsec delta))
|
||||
t))
|
||||
(s (time-convert subsec 'integer)))
|
||||
(setq seconds (+ seconds s))
|
||||
(setf (decoded-time-subsec time) (time-subtract subsec s))))
|
||||
|
||||
;; Time zone adjustments are basically the same as time adjustments.
|
||||
(setq seconds (+ seconds (or (decoded-time-zone delta) 0)))
|
||||
|
||||
(cond
|
||||
((> seconds 0)
|
||||
(decoded-time--alter-second time seconds t))
|
||||
((< seconds 0)
|
||||
(decoded-time--alter-second time (abs seconds) nil)))
|
||||
(setq seconds (time-add (+ (* (or (decoded-time-hour delta) 0) 3600)
|
||||
(* (or (decoded-time-minute delta) 0) 60)
|
||||
(or (decoded-time-zone delta) 0))
|
||||
(or (decoded-time-second delta) 0)))
|
||||
|
||||
(decoded-time--alter-second time seconds)
|
||||
time))
|
||||
|
||||
(defun decoded-time--alter-month (time increase)
|
||||
|
@ -472,38 +459,31 @@ changes in daylight saving time are not taken into account."
|
|||
(date-days-in-month (decoded-time-year time)
|
||||
(decoded-time-month time))))))
|
||||
|
||||
(defun decoded-time--alter-second (time seconds increase)
|
||||
"Increase or decrease the time in TIME by SECONDS."
|
||||
(let ((old (+ (* (or (decoded-time-hour time) 0) 3600)
|
||||
(* (or (decoded-time-minute time) 0) 60)
|
||||
(or (decoded-time-second time) 0))))
|
||||
|
||||
(if increase
|
||||
(progn
|
||||
(setq old (+ old seconds))
|
||||
(setf (decoded-time-second time) (% old 60)
|
||||
(decoded-time-minute time) (% (/ old 60) 60)
|
||||
(decoded-time-hour time) (% (/ old 3600) 24))
|
||||
;; Hm... DST...
|
||||
(let ((days (/ old (* 60 60 24))))
|
||||
(while (> days 0)
|
||||
(decoded-time--alter-day time t)
|
||||
(cl-decf days))))
|
||||
(setq old (abs (- old seconds)))
|
||||
(setf (decoded-time-second time) (% old 60)
|
||||
(decoded-time-minute time) (% (/ old 60) 60)
|
||||
(decoded-time-hour time) (% (/ old 3600) 24))
|
||||
;; Hm... DST...
|
||||
(let ((days (/ old (* 60 60 24))))
|
||||
(while (> days 0)
|
||||
(decoded-time--alter-day time nil)
|
||||
(cl-decf days))))))
|
||||
(defun decoded-time--alter-second (time seconds)
|
||||
"Increase the time in TIME by SECONDS."
|
||||
(let* ((secsperday 86400)
|
||||
(old (time-add (+ (* 3600 (or (decoded-time-hour time) 0))
|
||||
(* 60 (or (decoded-time-minute time) 0)))
|
||||
(or (decoded-time-second time) 0)))
|
||||
(new (time-add old seconds)))
|
||||
;; Hm... DST...
|
||||
(while (time-less-p new 0)
|
||||
(decoded-time--alter-day time nil)
|
||||
(setq new (time-add new secsperday)))
|
||||
(while (not (time-less-p new secsperday))
|
||||
(decoded-time--alter-day time t)
|
||||
(setq new (time-subtract new secsperday)))
|
||||
(let ((sec (time-convert new 'integer)))
|
||||
(setf (decoded-time-second time) (time-add (% sec 60)
|
||||
(time-subtract new sec))
|
||||
(decoded-time-minute time) (% (/ sec 60) 60)
|
||||
(decoded-time-hour time) (/ sec 3600)))))
|
||||
|
||||
(cl-defun make-decoded-time (&key second minute hour
|
||||
day month year
|
||||
dst zone subsec)
|
||||
dst zone)
|
||||
"Return a `decoded-time' structure with only the keywords given filled out."
|
||||
(list second minute hour day month year nil dst zone subsec))
|
||||
(list second minute hour day month year nil dst zone))
|
||||
|
||||
(defun decoded-time-set-defaults (time &optional default-zone)
|
||||
"Set any nil values in `decoded-time' TIME to default values.
|
||||
|
@ -533,9 +513,6 @@ TIME is modified and returned."
|
|||
(when (and (not (decoded-time-zone time))
|
||||
default-zone)
|
||||
(setf (decoded-time-zone time) 0))
|
||||
|
||||
(unless (decoded-time-subsec time)
|
||||
(setf (decoded-time-subsec time) 0))
|
||||
time)
|
||||
|
||||
(provide 'time-date)
|
||||
|
|
|
@ -561,8 +561,8 @@ gMonthDay, gDay or gMonth.
|
|||
Return a list in a format (SEC MINUTE HOUR DAY MONTH YEAR
|
||||
SEC-FRACTION DATATYPE ZONE). This format is meant to be similar
|
||||
to that returned by `decode-time' (and compatible with
|
||||
`encode-time'). The differences are the SUBSEC (fractional
|
||||
seconds) field is omitted, the DOW (day-of-week) field
|
||||
`encode-time'). The differences are the SEC (seconds)
|
||||
field is always an integer, the DOW (day-of-week) field
|
||||
is replaced with SEC-FRACTION, a float representing the
|
||||
fractional seconds, and the DST (daylight savings time) field is
|
||||
replaced with DATATYPE, a symbol representing the XSD primitive
|
||||
|
|
|
@ -17775,12 +17775,14 @@ NODEFAULT, hour and minute fields will be nil if not given."
|
|||
(string-to-number (match-string 4 s))
|
||||
(string-to-number (match-string 3 s))
|
||||
(string-to-number (match-string 2 s))
|
||||
nil nil nil 0))
|
||||
nil nil nil))
|
||||
((string-match "^<[^>]+>$" s)
|
||||
;; FIXME: `decode-time' needs to be called with ZONE as its
|
||||
;; second argument. However, this requires at least Emacs
|
||||
;; 25.1. We can do it when we switch to this version as our
|
||||
;; minimal requirement.
|
||||
;; FIXME: decode-time needs to be called with t as its
|
||||
;; third argument, but this requires at least Emacs 27.
|
||||
(decode-time (org-matcher-time s)))
|
||||
(t (error "Not a standard Org time string: %s" s))))
|
||||
|
||||
|
|
|
@ -9082,8 +9082,9 @@ to capitalize ARG words."
|
|||
(:copier nil)
|
||||
(:type list))
|
||||
(second nil :documentation "\
|
||||
This is an integer between 0 and 60 (inclusive). (60 is a leap
|
||||
second, which only some operating systems support.)")
|
||||
This is an integer or a Lisp timestamp (TICKS . HZ) representing a nonnegative
|
||||
number of seconds less than 61. (If not less than 60, it is a leap second,
|
||||
which only some operating systems support.)")
|
||||
(minute nil :documentation "This is an integer between 0 and 59 (inclusive).")
|
||||
(hour nil :documentation "This is an integer between 0 and 23 (inclusive).")
|
||||
(day nil :documentation "This is an integer between 1 and 31 (inclusive).")
|
||||
|
@ -9099,9 +9100,6 @@ available.")
|
|||
(zone nil :documentation "\
|
||||
This is an integer indicating the UTC offset in seconds, i.e.,
|
||||
the number of seconds east of Greenwich.")
|
||||
(subsec nil :documentation "\
|
||||
This is 0, or is an integer pair (TICKS . HZ) indicating TICKS/HZ seconds,
|
||||
where HZ is positive and TICKS is nonnegative and less than HZ.")
|
||||
)
|
||||
|
||||
|
||||
|
|
189
src/timefns.c
189
src/timefns.c
|
@ -1090,11 +1090,14 @@ time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
|
|||
}
|
||||
|
||||
/* Return an integer if the timestamp resolution is 1,
|
||||
otherwise the (TICKS . HZ) form if either argument is that way,
|
||||
otherwise the (HI LO US PS) form for backward compatibility. */
|
||||
otherwise the (TICKS . HZ) form if !CURRENT_TIME_LIST or if
|
||||
either input form supports timestamps that cannot be expressed
|
||||
exactly in (HI LO US PS) form, otherwise the (HI LO US PS) form
|
||||
for backward compatibility. */
|
||||
return (EQ (hz, make_fixnum (1))
|
||||
? ticks
|
||||
: timeform_sub_ps_p (aform) || timeform_sub_ps_p (bform)
|
||||
: (!CURRENT_TIME_LIST
|
||||
|| timeform_sub_ps_p (aform) || timeform_sub_ps_p (bform))
|
||||
? Fcons (ticks, hz)
|
||||
: ticks_hz_list4 (ticks, hz));
|
||||
}
|
||||
|
@ -1374,8 +1377,8 @@ usage: (format-time-string FORMAT-STRING &optional TIME ZONE) */)
|
|||
t, zone, &tm);
|
||||
}
|
||||
|
||||
DEFUN ("decode-time", Fdecode_time, Sdecode_time, 0, 2, 0,
|
||||
doc: /* Decode a time value as (SEC MINUTE HOUR DAY MONTH YEAR DOW DST UTCOFF SUBSEC).
|
||||
DEFUN ("decode-time", Fdecode_time, Sdecode_time, 0, 3, 0,
|
||||
doc: /* Decode a time value as (SEC MINUTE HOUR DAY MONTH YEAR DOW DST UTCOFF).
|
||||
The optional TIME is the time value to convert. See
|
||||
`format-time-string' for the various forms of a time value.
|
||||
|
||||
|
@ -1385,29 +1388,33 @@ the TZ environment variable. It can also be a list (as from
|
|||
`current-time-zone') or an integer (the UTC offset in seconds) applied
|
||||
without consideration for daylight saving time.
|
||||
|
||||
The optional FORM specifies the form of the SEC member. If `integer',
|
||||
SEC is an integer; if t, SEC uses the same resolution as TIME. An
|
||||
omitted or nil FORM is currently treated like `integer', but this may
|
||||
change in future Emacs versions.
|
||||
|
||||
To access (or alter) the elements in the time value, the
|
||||
`decoded-time-second', `decoded-time-minute', `decoded-time-hour',
|
||||
`decoded-time-day', `decoded-time-month', `decoded-time-year',
|
||||
`decoded-time-weekday', `decoded-time-dst', `decoded-time-zone' and
|
||||
`decoded-time-subsec' accessors can be used.
|
||||
`decoded-time-weekday', `decoded-time-dst' and `decoded-time-zone'
|
||||
accessors can be used.
|
||||
|
||||
The list has the following ten members: SEC is an integer between 0
|
||||
and 60; SEC is 60 for a leap second, which only some operating systems
|
||||
support. MINUTE is an integer between 0 and 59. HOUR is an integer
|
||||
The list has the following nine members: SEC is an integer or
|
||||
Lisp timestamp representing a nonnegative value less than 60
|
||||
\(or less than 61 if the operating system supports leap seconds).
|
||||
MINUTE is an integer between 0 and 59. HOUR is an integer
|
||||
between 0 and 23. DAY is an integer between 1 and 31. MONTH is an
|
||||
integer between 1 and 12. YEAR is an integer indicating the
|
||||
four-digit year. DOW is the day of week, an integer between 0 and 6,
|
||||
where 0 is Sunday. DST is t if daylight saving time is in effect,
|
||||
nil if it is not in effect, and -1 if daylight saving information is
|
||||
not available. UTCOFF is an integer indicating the UTC offset in
|
||||
seconds, i.e., the number of seconds east of Greenwich. SUBSEC is
|
||||
is either 0 or (TICKS . HZ) where HZ is a positive integer clock
|
||||
resolution and TICKS is a nonnegative integer less than HZ. (Note
|
||||
that Common Lisp has different meanings for DOW and UTCOFF, and lacks
|
||||
SUBSEC.)
|
||||
seconds, i.e., the number of seconds east of Greenwich. (Note that
|
||||
Common Lisp has different meanings for DOW and UTCOFF, and its
|
||||
SEC is always an integer between 0 and 59.)
|
||||
|
||||
usage: (decode-time &optional TIME ZONE) */)
|
||||
(Lisp_Object specified_time, Lisp_Object zone)
|
||||
usage: (decode-time &optional TIME ZONE FORM) */)
|
||||
(Lisp_Object specified_time, Lisp_Object zone, Lisp_Object form)
|
||||
{
|
||||
struct lisp_time lt = lisp_time_struct (specified_time, 0);
|
||||
struct timespec ts = lisp_to_timespec (lt);
|
||||
|
@ -1439,8 +1446,35 @@ usage: (decode-time &optional TIME ZONE) */)
|
|||
year = make_integer_mpz ();
|
||||
}
|
||||
|
||||
Lisp_Object hz = lt.hz, sec;
|
||||
if (EQ (hz, make_fixnum (1)) || !EQ (form, Qt))
|
||||
sec = make_fixnum (local_tm.tm_sec);
|
||||
else
|
||||
{
|
||||
Lisp_Object ticks; /* hz * tm_sec + mod (lt.ticks, hz) */
|
||||
intmax_t n;
|
||||
if (FASTER_TIMEFNS && FIXNUMP (lt.ticks) && FIXNUMP (hz)
|
||||
&& !INT_MULTIPLY_WRAPV (XFIXNUM (hz), local_tm.tm_sec, &n)
|
||||
&& ! (INT_ADD_WRAPV
|
||||
(n, (XFIXNUM (lt.ticks) % XFIXNUM (hz)
|
||||
+ (XFIXNUM (lt.ticks) % XFIXNUM (hz) < 0
|
||||
? XFIXNUM (hz) : 0)),
|
||||
&n)))
|
||||
ticks = make_int (n);
|
||||
else
|
||||
{
|
||||
mpz_fdiv_r (mpz[0],
|
||||
*bignum_integer (&mpz[0], lt.ticks),
|
||||
*bignum_integer (&mpz[1], hz));
|
||||
mpz_addmul_ui (mpz[0], *bignum_integer (&mpz[1], hz),
|
||||
local_tm.tm_sec);
|
||||
ticks = make_integer_mpz ();
|
||||
}
|
||||
sec = Fcons (ticks, hz);
|
||||
}
|
||||
|
||||
return CALLN (Flist,
|
||||
make_fixnum (local_tm.tm_sec),
|
||||
sec,
|
||||
make_fixnum (local_tm.tm_min),
|
||||
make_fixnum (local_tm.tm_hour),
|
||||
make_fixnum (local_tm.tm_mday),
|
||||
|
@ -1453,10 +1487,7 @@ usage: (decode-time &optional TIME ZONE) */)
|
|||
? make_fixnum (tm_gmtoff (&local_tm))
|
||||
: gmtime_r (&time_spec, &gmt_tm)
|
||||
? make_fixnum (tm_diff (&local_tm, &gmt_tm))
|
||||
: Qnil),
|
||||
(EQ (lt.hz, make_fixnum (1))
|
||||
? make_fixnum (0)
|
||||
: Fcons (integer_mod (lt.ticks, lt.hz), lt.hz)));
|
||||
: Qnil));
|
||||
}
|
||||
|
||||
/* Return OBJ - OFFSET, checking that OBJ is a valid integer and that
|
||||
|
@ -1487,7 +1518,7 @@ check_tm_member (Lisp_Object obj, int offset)
|
|||
DEFUN ("encode-time", Fencode_time, Sencode_time, 1, MANY, 0,
|
||||
doc: /* Convert TIME to a timestamp.
|
||||
|
||||
TIME is a list (SECOND MINUTE HOUR DAY MONTH YEAR IGNORED DST ZONE SUBSEC).
|
||||
TIME is a list (SECOND MINUTE HOUR DAY MONTH YEAR IGNORED DST ZONE).
|
||||
in the style of `decode-time', so that (encode-time (decode-time ...)) works.
|
||||
In this list, ZONE can be nil for Emacs local time, t for Universal
|
||||
Time, `wall' for system wall clock time, or a string as in the TZ
|
||||
|
@ -1496,23 +1527,16 @@ environment variable. It can also be a list (as from
|
|||
without consideration for daylight saving time. If ZONE specifies a
|
||||
time zone with daylight-saving transitions, DST is t for daylight
|
||||
saving time, nil for standard time, and -1 to cause the daylight
|
||||
saving flag to be guessed. SUBSEC is either 0 or a Lisp timestamp
|
||||
in (TICKS . HZ) form.
|
||||
saving flag to be guessed.
|
||||
|
||||
As an obsolescent calling convention, if this function is called with
|
||||
6 through 10 arguments, the first 6 arguments are SECOND, MINUTE,
|
||||
HOUR, DAY, MONTH, and YEAR, and specify the components of a decoded
|
||||
time. If there are 7 through 9 arguments the *last* argument
|
||||
specifies ZONE, and if there are 10 arguments the 9th specifies ZONE
|
||||
and the 10th specifies SUBSEC; in either case any other extra
|
||||
arguments are ignored, so that (apply #\\='encode-time (decode-time
|
||||
...)) works. In this obsolescent convention, DST, ZONE, and SUBSEC
|
||||
default to -1, nil and 0 respectively.
|
||||
|
||||
Out-of-range values for SECOND, MINUTE, HOUR, DAY, or MONTH are allowed;
|
||||
for example, a DAY of 0 means the day preceding the given month.
|
||||
Year numbers less than 100 are treated just like other year numbers.
|
||||
If you want them to stand for years in this century, you must do that yourself.
|
||||
6 or more arguments, the first 6 arguments are SECOND, MINUTE, HOUR,
|
||||
DAY, MONTH, and YEAR, and specify the components of a decoded time,
|
||||
where DST assumed to be -1 and FORM is omitted. If there are more
|
||||
than 6 arguments the *last* argument is used as ZONE and any other
|
||||
extra arguments are ignored, so that (apply #\\='encode-time
|
||||
(decode-time ...)) works. In this obsolescent convention, DST and
|
||||
ZONE default to -1 and nil respectively.
|
||||
|
||||
Years before 1970 are not guaranteed to work. On some systems,
|
||||
year values as low as 1901 do work.
|
||||
|
@ -1521,27 +1545,27 @@ usage: (encode-time TIME &rest OBSOLESCENT-ARGUMENTS) */)
|
|||
(ptrdiff_t nargs, Lisp_Object *args)
|
||||
{
|
||||
struct tm tm;
|
||||
Lisp_Object zone = Qnil, subsec = make_fixnum (0);
|
||||
Lisp_Object zone = Qnil;
|
||||
Lisp_Object a = args[0];
|
||||
Lisp_Object secarg, minarg, hourarg, mdayarg, monarg, yeararg;
|
||||
tm.tm_isdst = -1;
|
||||
|
||||
if (nargs == 1)
|
||||
{
|
||||
Lisp_Object tail = a;
|
||||
for (int i = 0; i < 10; i++, tail = XCDR (tail))
|
||||
for (int i = 0; i < 9; i++, tail = XCDR (tail))
|
||||
CHECK_CONS (tail);
|
||||
tm.tm_sec = check_tm_member (XCAR (a), 0); a = XCDR (a);
|
||||
tm.tm_min = check_tm_member (XCAR (a), 0); a = XCDR (a);
|
||||
tm.tm_hour = check_tm_member (XCAR (a), 0); a = XCDR (a);
|
||||
tm.tm_mday = check_tm_member (XCAR (a), 0); a = XCDR (a);
|
||||
tm.tm_mon = check_tm_member (XCAR (a), 1); a = XCDR (a);
|
||||
tm.tm_year = check_tm_member (XCAR (a), TM_YEAR_BASE); a = XCDR (a);
|
||||
secarg = XCAR (a); a = XCDR (a);
|
||||
minarg = XCAR (a); a = XCDR (a);
|
||||
hourarg = XCAR (a); a = XCDR (a);
|
||||
mdayarg = XCAR (a); a = XCDR (a);
|
||||
monarg = XCAR (a); a = XCDR (a);
|
||||
yeararg = XCAR (a); a = XCDR (a);
|
||||
a = XCDR (a);
|
||||
Lisp_Object dstflag = XCAR (a); a = XCDR (a);
|
||||
zone = XCAR (a); a = XCDR (a);
|
||||
zone = XCAR (a);
|
||||
if (SYMBOLP (dstflag) && !FIXNUMP (zone) && !CONSP (zone))
|
||||
tm.tm_isdst = !NILP (dstflag);
|
||||
subsec = XCAR (a);
|
||||
}
|
||||
else if (nargs < 6)
|
||||
xsignal2 (Qwrong_number_of_arguments, Qencode_time, make_fixnum (nargs));
|
||||
|
@ -1549,19 +1573,38 @@ usage: (encode-time TIME &rest OBSOLESCENT-ARGUMENTS) */)
|
|||
{
|
||||
if (6 < nargs)
|
||||
zone = args[nargs - 1];
|
||||
if (9 < nargs)
|
||||
{
|
||||
zone = args[8];
|
||||
subsec = args[9];
|
||||
}
|
||||
tm.tm_sec = check_tm_member (a, 0);
|
||||
tm.tm_min = check_tm_member (args[1], 0);
|
||||
tm.tm_hour = check_tm_member (args[2], 0);
|
||||
tm.tm_mday = check_tm_member (args[3], 0);
|
||||
tm.tm_mon = check_tm_member (args[4], 1);
|
||||
tm.tm_year = check_tm_member (args[5], TM_YEAR_BASE);
|
||||
secarg = a;
|
||||
minarg = args[1];
|
||||
hourarg = args[2];
|
||||
mdayarg = args[3];
|
||||
monarg = args[4];
|
||||
yeararg = args[5];
|
||||
}
|
||||
|
||||
struct lisp_time lt;
|
||||
decode_lisp_time (secarg, 0, <, 0);
|
||||
Lisp_Object hz = lt.hz, sec, subsecticks;
|
||||
if (FASTER_TIMEFNS && EQ (hz, make_fixnum (1)))
|
||||
{
|
||||
sec = lt.ticks;
|
||||
subsecticks = make_fixnum (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
mpz_fdiv_qr (mpz[0], mpz[1],
|
||||
*bignum_integer (&mpz[0], lt.ticks),
|
||||
*bignum_integer (&mpz[1], hz));
|
||||
sec = make_integer_mpz ();
|
||||
mpz_swap (mpz[0], mpz[1]);
|
||||
subsecticks = make_integer_mpz ();
|
||||
}
|
||||
tm.tm_sec = check_tm_member (sec, 0);
|
||||
tm.tm_min = check_tm_member (minarg, 0);
|
||||
tm.tm_hour = check_tm_member (hourarg, 0);
|
||||
tm.tm_mday = check_tm_member (mdayarg, 0);
|
||||
tm.tm_mon = check_tm_member (monarg, 1);
|
||||
tm.tm_year = check_tm_member (yeararg, TM_YEAR_BASE);
|
||||
|
||||
timezone_t tz = tzlookup (zone, false);
|
||||
tm.tm_wday = -1;
|
||||
time_t value = mktime_z (tz, &tm);
|
||||
|
@ -1571,25 +1614,17 @@ usage: (encode-time TIME &rest OBSOLESCENT-ARGUMENTS) */)
|
|||
if (tm.tm_wday < 0)
|
||||
time_error (mktime_errno);
|
||||
|
||||
if (CONSP (subsec))
|
||||
{
|
||||
Lisp_Object subsecticks = XCAR (subsec);
|
||||
if (INTEGERP (subsecticks))
|
||||
{
|
||||
struct lisp_time val1 = { INT_TO_INTEGER (value), make_fixnum (1) };
|
||||
Lisp_Object
|
||||
hz = XCDR (subsec),
|
||||
secticks = lisp_time_hz_ticks (val1, hz),
|
||||
ticks = lispint_arith (secticks, subsecticks, false);
|
||||
return Fcons (ticks, hz);
|
||||
}
|
||||
}
|
||||
else if (INTEGERP (subsec))
|
||||
return (CURRENT_TIME_LIST && EQ (subsec, make_fixnum (0))
|
||||
if (EQ (hz, make_fixnum (1)))
|
||||
return (CURRENT_TIME_LIST
|
||||
? list2 (hi_time (value), lo_time (value))
|
||||
: lispint_arith (INT_TO_INTEGER (value), subsec, false));
|
||||
|
||||
xsignal2 (Qerror, build_string ("Invalid subsec"), subsec);
|
||||
: INT_TO_INTEGER (value));
|
||||
else
|
||||
{
|
||||
struct lisp_time val1 = { INT_TO_INTEGER (value), make_fixnum (1) };
|
||||
Lisp_Object secticks = lisp_time_hz_ticks (val1, hz);
|
||||
Lisp_Object ticks = lispint_arith (secticks, subsecticks, false);
|
||||
return Fcons (ticks, hz);
|
||||
}
|
||||
}
|
||||
|
||||
DEFUN ("time-convert", Ftime_convert, Stime_convert, 1, 2, 0,
|
||||
|
|
|
@ -477,18 +477,18 @@ END:VEVENT
|
|||
|
||||
;; testcase: no time zone in input -> keep time as is
|
||||
;; 1 Jan 2013 10:00
|
||||
(should (equal '(0 0 10 1 1 2013 2 nil 7200 0)
|
||||
(should (equal '(0 0 10 1 1 2013 2 nil 7200)
|
||||
(icalendar--decode-isodatetime "20130101T100000")))
|
||||
;; 1 Aug 2013 10:00 (DST)
|
||||
(should (equal '(0 0 10 1 8 2013 4 t 10800 0)
|
||||
(should (equal '(0 0 10 1 8 2013 4 t 10800)
|
||||
(icalendar--decode-isodatetime "20130801T100000")))
|
||||
|
||||
;; testcase: UTC time zone specifier in input -> convert to local time
|
||||
;; 31 Dec 2013 23:00 UTC -> 1 Jan 2013 01:00 EET
|
||||
(should (equal '(0 0 1 1 1 2014 3 nil 7200 0)
|
||||
(should (equal '(0 0 1 1 1 2014 3 nil 7200)
|
||||
(icalendar--decode-isodatetime "20131231T230000Z")))
|
||||
;; 1 Aug 2013 10:00 UTC -> 1 Aug 2013 13:00 EEST
|
||||
(should (equal '(0 0 13 1 8 2013 4 t 10800 0)
|
||||
(should (equal '(0 0 13 1 8 2013 4 t 10800)
|
||||
(icalendar--decode-isodatetime "20130801T100000Z")))
|
||||
|
||||
)
|
||||
|
|
|
@ -24,65 +24,65 @@
|
|||
|
||||
(ert-deftest test-iso8601-date-years ()
|
||||
(should (equal (iso8601-parse-date "1985")
|
||||
'(nil nil nil nil nil 1985 nil nil nil nil)))
|
||||
'(nil nil nil nil nil 1985 nil nil nil)))
|
||||
(should (equal (iso8601-parse-date "-0003")
|
||||
'(nil nil nil nil nil -4 nil nil nil nil)))
|
||||
'(nil nil nil nil nil -4 nil nil nil)))
|
||||
(should (equal (iso8601-parse-date "+1985")
|
||||
'(nil nil nil nil nil 1985 nil nil nil nil))))
|
||||
'(nil nil nil nil nil 1985 nil nil nil))))
|
||||
|
||||
(ert-deftest test-iso8601-date-dates ()
|
||||
(should (equal (iso8601-parse-date "1985-03-14")
|
||||
'(nil nil nil 14 3 1985 nil nil nil nil)))
|
||||
'(nil nil nil 14 3 1985 nil nil nil)))
|
||||
(should (equal (iso8601-parse-date "19850314")
|
||||
'(nil nil nil 14 3 1985 nil nil nil nil)))
|
||||
'(nil nil nil 14 3 1985 nil nil nil)))
|
||||
(should (equal (iso8601-parse-date "1985-02")
|
||||
'(nil nil nil nil 2 1985 nil nil nil nil))))
|
||||
'(nil nil nil nil 2 1985 nil nil nil))))
|
||||
|
||||
(ert-deftest test-iso8601-date-obsolete ()
|
||||
(should (equal (iso8601-parse-date "--02-01")
|
||||
'(nil nil nil 1 2 nil nil nil nil nil)))
|
||||
'(nil nil nil 1 2 nil nil nil nil)))
|
||||
(should (equal (iso8601-parse-date "--0201")
|
||||
'(nil nil nil 1 2 nil nil nil nil nil))))
|
||||
'(nil nil nil 1 2 nil nil nil nil))))
|
||||
|
||||
(ert-deftest test-iso8601-date-weeks ()
|
||||
(should (equal (iso8601-parse-date "2008W39-6")
|
||||
'(nil nil nil 27 9 2008 nil nil nil nil)))
|
||||
'(nil nil nil 27 9 2008 nil nil nil)))
|
||||
(should (equal (iso8601-parse-date "2009W01-1")
|
||||
'(nil nil nil 29 12 2008 nil nil nil nil)))
|
||||
'(nil nil nil 29 12 2008 nil nil nil)))
|
||||
(should (equal (iso8601-parse-date "2009W53-7")
|
||||
'(nil nil nil 3 1 2010 nil nil nil nil))))
|
||||
'(nil nil nil 3 1 2010 nil nil nil))))
|
||||
|
||||
(ert-deftest test-iso8601-date-ordinals ()
|
||||
(should (equal (iso8601-parse-date "1981-095")
|
||||
'(nil nil nil 5 4 1981 nil nil nil nil))))
|
||||
'(nil nil nil 5 4 1981 nil nil nil))))
|
||||
|
||||
(ert-deftest test-iso8601-time ()
|
||||
(should (equal (iso8601-parse-time "13:47:30")
|
||||
'(30 47 13 nil nil nil nil nil nil 0)))
|
||||
'(30 47 13 nil nil nil nil nil nil)))
|
||||
(should (equal (iso8601-parse-time "134730")
|
||||
'(30 47 13 nil nil nil nil nil nil 0)))
|
||||
'(30 47 13 nil nil nil nil nil nil)))
|
||||
(should (equal (iso8601-parse-time "1347")
|
||||
'(0 47 13 nil nil nil nil nil nil 0))))
|
||||
'(0 47 13 nil nil nil nil nil nil))))
|
||||
|
||||
(ert-deftest test-iso8601-combined ()
|
||||
(should (equal (iso8601-parse "2008-03-02T13:47:30")
|
||||
'(30 47 13 2 3 2008 nil nil nil 0)))
|
||||
'(30 47 13 2 3 2008 nil nil nil)))
|
||||
(should (equal (iso8601-parse "2008-03-02T13:47:30Z")
|
||||
'(30 47 13 2 3 2008 nil nil 0 0)))
|
||||
'(30 47 13 2 3 2008 nil nil 0)))
|
||||
(should (equal (iso8601-parse "2008-03-02T13:47:30+01:00")
|
||||
'(30 47 13 2 3 2008 nil nil 3600 0)))
|
||||
'(30 47 13 2 3 2008 nil nil 3600)))
|
||||
(should (equal (iso8601-parse "2008-03-02T13:47:30-01")
|
||||
'(30 47 13 2 3 2008 nil nil -3600 0))))
|
||||
'(30 47 13 2 3 2008 nil nil -3600))))
|
||||
|
||||
(ert-deftest test-iso8601-duration ()
|
||||
(should (equal (iso8601-parse-duration "P3Y6M4DT12H30M5S")
|
||||
'(5 30 12 4 6 3 nil nil nil 0)))
|
||||
'(5 30 12 4 6 3 nil nil nil)))
|
||||
(should (equal (iso8601-parse-duration "P1M")
|
||||
'(0 0 0 0 1 0 nil nil nil 0)))
|
||||
'(0 0 0 0 1 0 nil nil nil)))
|
||||
(should (equal (iso8601-parse-duration "PT1M")
|
||||
'(0 1 0 0 0 0 nil nil nil 0)))
|
||||
'(0 1 0 0 0 0 nil nil nil)))
|
||||
(should (equal (iso8601-parse-duration "P0003-06-04T12:30:05")
|
||||
'(5 30 12 4 6 3 nil nil nil 0))))
|
||||
'(5 30 12 4 6 3 nil nil nil))))
|
||||
|
||||
(ert-deftest test-iso8601-invalid ()
|
||||
(should-not (iso8601-valid-p " 2008-03-02T13:47:30-01"))
|
||||
|
@ -94,149 +94,149 @@
|
|||
(ert-deftest test-iso8601-intervals ()
|
||||
(should (equal
|
||||
(iso8601-parse-interval "2007-03-01T13:00:00Z/2008-05-11T15:30:00Z")
|
||||
'((0 0 13 1 3 2007 nil nil 0 0)
|
||||
(0 30 15 11 5 2008 nil nil 0 0)
|
||||
'((0 0 13 1 3 2007 nil nil 0)
|
||||
(0 30 15 11 5 2008 nil nil 0)
|
||||
;; Hm... can't really use decode-time for time differences...
|
||||
(0 30 2 14 3 1971 0 nil 0 0))))
|
||||
(0 30 2 14 3 1971 0 nil 0))))
|
||||
(should (equal (iso8601-parse-interval "2007-03-01T13:00:00Z/P1Y2M10DT2H30M")
|
||||
'((0 0 13 1 3 2007 nil nil 0 0)
|
||||
(0 30 15 11 5 2008 nil nil 0 0)
|
||||
(0 30 2 10 2 1 nil nil nil 0))))
|
||||
'((0 0 13 1 3 2007 nil nil 0)
|
||||
(0 30 15 11 5 2008 nil nil 0)
|
||||
(0 30 2 10 2 1 nil nil nil))))
|
||||
(should (equal (iso8601-parse-interval "P1Y2M10DT2H30M/2008-05-11T15:30:00Z")
|
||||
'((0 0 13 1 3 2007 nil nil 0 0)
|
||||
(0 30 15 11 5 2008 nil nil 0 0)
|
||||
(0 30 2 10 2 1 nil nil nil 0)))))
|
||||
'((0 0 13 1 3 2007 nil nil 0)
|
||||
(0 30 15 11 5 2008 nil nil 0)
|
||||
(0 30 2 10 2 1 nil nil nil)))))
|
||||
|
||||
(ert-deftest standard-test-dates ()
|
||||
(should (equal (iso8601-parse-date "19850412")
|
||||
'(nil nil nil 12 4 1985 nil nil nil nil)))
|
||||
'(nil nil nil 12 4 1985 nil nil nil)))
|
||||
(should (equal (iso8601-parse-date "1985-04-12")
|
||||
'(nil nil nil 12 4 1985 nil nil nil nil)))
|
||||
'(nil nil nil 12 4 1985 nil nil nil)))
|
||||
|
||||
(should (equal (iso8601-parse-date "1985102")
|
||||
'(nil nil nil 12 4 1985 nil nil nil nil)))
|
||||
'(nil nil nil 12 4 1985 nil nil nil)))
|
||||
(should (equal (iso8601-parse-date "1985-102")
|
||||
'(nil nil nil 12 4 1985 nil nil nil nil)))
|
||||
'(nil nil nil 12 4 1985 nil nil nil)))
|
||||
|
||||
(should (equal (iso8601-parse-date "1985W155")
|
||||
'(nil nil nil 12 4 1985 nil nil nil nil)))
|
||||
'(nil nil nil 12 4 1985 nil nil nil)))
|
||||
(should (equal (iso8601-parse-date "1985-W15-5")
|
||||
'(nil nil nil 12 4 1985 nil nil nil nil)))
|
||||
'(nil nil nil 12 4 1985 nil nil nil)))
|
||||
|
||||
(should (equal (iso8601-parse-date "1985W15")
|
||||
'(nil nil nil 7 4 1985 nil nil nil nil)))
|
||||
'(nil nil nil 7 4 1985 nil nil nil)))
|
||||
(should (equal (iso8601-parse-date "1985-W15")
|
||||
'(nil nil nil 7 4 1985 nil nil nil nil)))
|
||||
'(nil nil nil 7 4 1985 nil nil nil)))
|
||||
|
||||
(should (equal (iso8601-parse-date "1985-04")
|
||||
'(nil nil nil nil 4 1985 nil nil nil nil)))
|
||||
'(nil nil nil nil 4 1985 nil nil nil)))
|
||||
|
||||
(should (equal (iso8601-parse-date "1985")
|
||||
'(nil nil nil nil nil 1985 nil nil nil nil)))
|
||||
'(nil nil nil nil nil 1985 nil nil nil)))
|
||||
|
||||
(should (equal (iso8601-parse-date "+1985-04-12")
|
||||
'(nil nil nil 12 4 1985 nil nil nil nil)))
|
||||
'(nil nil nil 12 4 1985 nil nil nil)))
|
||||
(should (equal (iso8601-parse-date "+19850412")
|
||||
'(nil nil nil 12 4 1985 nil nil nil nil))))
|
||||
'(nil nil nil 12 4 1985 nil nil nil))))
|
||||
|
||||
(ert-deftest standard-test-time-of-day-local-time ()
|
||||
(should (equal (iso8601-parse-time "152746")
|
||||
'(46 27 15 nil nil nil nil nil nil 0)))
|
||||
'(46 27 15 nil nil nil nil nil nil)))
|
||||
(should (equal (iso8601-parse-time "15:27:46")
|
||||
'(46 27 15 nil nil nil nil nil nil 0)))
|
||||
'(46 27 15 nil nil nil nil nil nil)))
|
||||
|
||||
(should (equal (iso8601-parse-time "1528")
|
||||
'(0 28 15 nil nil nil nil nil nil 0)))
|
||||
'(0 28 15 nil nil nil nil nil nil)))
|
||||
(should (equal (iso8601-parse-time "15:28")
|
||||
'(0 28 15 nil nil nil nil nil nil 0)))
|
||||
'(0 28 15 nil nil nil nil nil nil)))
|
||||
|
||||
(should (equal (iso8601-parse-time "15")
|
||||
'(0 0 15 nil nil nil nil nil nil 0))))
|
||||
'(0 0 15 nil nil nil nil nil nil))))
|
||||
|
||||
(ert-deftest standard-test-time-of-day-fractions ()
|
||||
;; decoded-time doesn't support sub-second times.
|
||||
;; (should (equal (iso8601-parse-time "152735,5")
|
||||
;; '(46 27 15 nil nil nil nil nil nil (5 . 10))))
|
||||
;; '(46 27 15 nil nil nil nil nil nil)))
|
||||
;; (should (equal (iso8601-parse-time "15:27:35,5")
|
||||
;; '(46 27 15 nil nil nil nil nil nil (5 . 10))))
|
||||
;; '(46 27 15 nil nil nil nil nil nil)))
|
||||
)
|
||||
|
||||
(ert-deftest standard-test-time-of-day-beginning-of-day ()
|
||||
(should (equal (iso8601-parse-time "000000")
|
||||
'(0 0 0 nil nil nil nil nil nil 0)))
|
||||
'(0 0 0 nil nil nil nil nil nil)))
|
||||
(should (equal (iso8601-parse-time "00:00:00")
|
||||
'(0 0 0 nil nil nil nil nil nil 0)))
|
||||
'(0 0 0 nil nil nil nil nil nil)))
|
||||
|
||||
(should (equal (iso8601-parse-time "0000")
|
||||
'(0 0 0 nil nil nil nil nil nil 0)))
|
||||
'(0 0 0 nil nil nil nil nil nil)))
|
||||
(should (equal (iso8601-parse-time "00:00")
|
||||
'(0 0 0 nil nil nil nil nil nil 0))))
|
||||
'(0 0 0 nil nil nil nil nil nil))))
|
||||
|
||||
(ert-deftest standard-test-time-of-day-utc ()
|
||||
(should (equal (iso8601-parse-time "232030Z")
|
||||
'(30 20 23 nil nil nil nil nil 0 0)))
|
||||
'(30 20 23 nil nil nil nil nil 0)))
|
||||
(should (equal (iso8601-parse-time "23:20:30Z")
|
||||
'(30 20 23 nil nil nil nil nil 0 0)))
|
||||
'(30 20 23 nil nil nil nil nil 0)))
|
||||
|
||||
(should (equal (iso8601-parse-time "2320Z")
|
||||
'(0 20 23 nil nil nil nil nil 0 0)))
|
||||
'(0 20 23 nil nil nil nil nil 0)))
|
||||
(should (equal (iso8601-parse-time "23:20Z")
|
||||
'(0 20 23 nil nil nil nil nil 0 0)))
|
||||
'(0 20 23 nil nil nil nil nil 0)))
|
||||
|
||||
(should (equal (iso8601-parse-time "23Z")
|
||||
'(0 0 23 nil nil nil nil nil 0 0))))
|
||||
'(0 0 23 nil nil nil nil nil 0))))
|
||||
|
||||
|
||||
(ert-deftest standard-test-time-of-day-zone ()
|
||||
(should (equal (iso8601-parse-time "152746+0100")
|
||||
'(46 27 15 nil nil nil nil nil 3600 0)))
|
||||
'(46 27 15 nil nil nil nil nil 3600)))
|
||||
(should (equal (iso8601-parse-time "15:27:46+0100")
|
||||
'(46 27 15 nil nil nil nil nil 3600 0)))
|
||||
'(46 27 15 nil nil nil nil nil 3600)))
|
||||
|
||||
(should (equal (iso8601-parse-time "152746+01")
|
||||
'(46 27 15 nil nil nil nil nil 3600 0)))
|
||||
'(46 27 15 nil nil nil nil nil 3600)))
|
||||
(should (equal (iso8601-parse-time "15:27:46+01")
|
||||
'(46 27 15 nil nil nil nil nil 3600 0)))
|
||||
'(46 27 15 nil nil nil nil nil 3600)))
|
||||
|
||||
(should (equal (iso8601-parse-time "152746-0500")
|
||||
'(46 27 15 nil nil nil nil nil -18000 0)))
|
||||
'(46 27 15 nil nil nil nil nil -18000)))
|
||||
(should (equal (iso8601-parse-time "15:27:46-0500")
|
||||
'(46 27 15 nil nil nil nil nil -18000 0)))
|
||||
'(46 27 15 nil nil nil nil nil -18000)))
|
||||
|
||||
(should (equal (iso8601-parse-time "152746-05")
|
||||
'(46 27 15 nil nil nil nil nil -18000 0)))
|
||||
'(46 27 15 nil nil nil nil nil -18000)))
|
||||
(should (equal (iso8601-parse-time "15:27:46-05")
|
||||
'(46 27 15 nil nil nil nil nil -18000 0))))
|
||||
'(46 27 15 nil nil nil nil nil -18000))))
|
||||
|
||||
(ert-deftest standard-test-date-and-time-of-day ()
|
||||
(should (equal (iso8601-parse "19850412T101530")
|
||||
'(30 15 10 12 4 1985 nil nil nil 0)))
|
||||
'(30 15 10 12 4 1985 nil nil nil)))
|
||||
(should (equal (iso8601-parse "1985-04-12T10:15:30")
|
||||
'(30 15 10 12 4 1985 nil nil nil 0)))
|
||||
'(30 15 10 12 4 1985 nil nil nil)))
|
||||
|
||||
(should (equal (iso8601-parse "1985102T235030Z")
|
||||
'(30 50 23 12 4 1985 nil nil 0 0)))
|
||||
'(30 50 23 12 4 1985 nil nil 0)))
|
||||
(should (equal (iso8601-parse "1985-102T23:50:30Z")
|
||||
'(30 50 23 12 4 1985 nil nil 0 0)))
|
||||
'(30 50 23 12 4 1985 nil nil 0)))
|
||||
|
||||
(should (equal (iso8601-parse "1985W155T235030")
|
||||
'(30 50 23 12 4 1985 nil nil nil 0)))
|
||||
'(30 50 23 12 4 1985 nil nil nil)))
|
||||
(should (equal (iso8601-parse "1985-W155T23:50:30")
|
||||
'(30 50 23 12 4 1985 nil nil nil 0))))
|
||||
'(30 50 23 12 4 1985 nil nil nil))))
|
||||
|
||||
(ert-deftest standard-test-interval ()
|
||||
;; A time interval starting at 20 minutes and 50 seconds past 23
|
||||
;; hours on 12 April 1985 and ending at 30 minutes past 10 hours on
|
||||
;; 25 June 1985.
|
||||
(should (equal (iso8601-parse-interval "19850412T232050Z/19850625T103000Z")
|
||||
'((50 20 23 12 4 1985 nil nil 0 0)
|
||||
(0 30 10 25 6 1985 nil nil 0 0)
|
||||
(10 9 11 15 3 1970 0 nil 0 0))))
|
||||
'((50 20 23 12 4 1985 nil nil 0)
|
||||
(0 30 10 25 6 1985 nil nil 0)
|
||||
(10 9 11 15 3 1970 0 nil 0))))
|
||||
(should (equal (iso8601-parse-interval
|
||||
"1985-04-12T23:20:50Z/1985-06-25T10:30:00Z")
|
||||
'((50 20 23 12 4 1985 nil nil 0 0)
|
||||
(0 30 10 25 6 1985 nil nil 0 0)
|
||||
(10 9 11 15 3 1970 0 nil 0 0))))
|
||||
'((50 20 23 12 4 1985 nil nil 0)
|
||||
(0 30 10 25 6 1985 nil nil 0)
|
||||
(10 9 11 15 3 1970 0 nil 0))))
|
||||
|
||||
;; A time interval starting at 12 April 1985 and ending on 25 June
|
||||
;; 1985.
|
||||
|
@ -251,41 +251,41 @@
|
|||
;; A time interval of 2 years, 10 months, 15 days, 10 hours, 20
|
||||
;; minutes and 30 seconds.
|
||||
(should (equal (iso8601-parse-duration "P2Y10M15DT10H20M30S")
|
||||
'(30 20 10 15 10 2 nil nil nil 0)))
|
||||
'(30 20 10 15 10 2 nil nil nil)))
|
||||
|
||||
(should (equal (iso8601-parse-duration "P00021015T102030")
|
||||
'(30 20 10 15 10 2 nil nil nil 0)))
|
||||
'(30 20 10 15 10 2 nil nil nil)))
|
||||
(should (equal (iso8601-parse-duration "P0002-10-15T10:20:30")
|
||||
'(30 20 10 15 10 2 nil nil nil 0)))
|
||||
'(30 20 10 15 10 2 nil nil nil)))
|
||||
|
||||
;; A time interval of 1 year and 6 months.
|
||||
(should (equal (iso8601-parse-duration "P1Y6M")
|
||||
'(0 0 0 0 6 1 nil nil nil 0)))
|
||||
'(0 0 0 0 6 1 nil nil nil)))
|
||||
(should (equal (iso8601-parse-duration "P0001-06")
|
||||
'(nil nil nil nil 6 1 nil nil nil nil)))
|
||||
'(nil nil nil nil 6 1 nil nil nil)))
|
||||
|
||||
;; A time interval of seventy-two hours.
|
||||
(should (equal (iso8601-parse-duration "PT72H")
|
||||
'(0 0 72 0 0 0 nil nil nil 0)))
|
||||
'(0 0 72 0 0 0 nil nil nil)))
|
||||
|
||||
;; Defined by start and duration
|
||||
;; A time interval of 1 year, 2 months, 15 days and 12 hours,
|
||||
;; beginning on 12 April 1985 at 20 minutes past 23 hours.
|
||||
(should (equal (iso8601-parse-interval "19850412T232000/P1Y2M15DT12H")
|
||||
'((0 20 23 12 4 1985 nil nil nil 0)
|
||||
(0 20 11 28 6 1986 nil nil nil 0)
|
||||
(0 0 12 15 2 1 nil nil nil 0))))
|
||||
'((0 20 23 12 4 1985 nil nil nil)
|
||||
(0 20 11 28 6 1986 nil nil nil)
|
||||
(0 0 12 15 2 1 nil nil nil))))
|
||||
(should (equal (iso8601-parse-interval "1985-04-12T23:20:00/P1Y2M15DT12H")
|
||||
'((0 20 23 12 4 1985 nil nil nil 0)
|
||||
(0 20 11 28 6 1986 nil nil nil 0)
|
||||
(0 0 12 15 2 1 nil nil nil 0))))
|
||||
'((0 20 23 12 4 1985 nil nil nil)
|
||||
(0 20 11 28 6 1986 nil nil nil)
|
||||
(0 0 12 15 2 1 nil nil nil))))
|
||||
|
||||
;; Defined by duration and end
|
||||
;; A time interval of 1 year, 2 months, 15 days and 12 hours, ending
|
||||
;; on 12 April 1985 at 20 minutes past 23 hour.
|
||||
(should (equal (iso8601-parse-interval "P1Y2M15DT12H/19850412T232000")
|
||||
'((0 20 11 28 1 1984 nil nil nil 0)
|
||||
(0 20 23 12 4 1985 nil nil nil 0)
|
||||
(0 0 12 15 2 1 nil nil nil 0)))))
|
||||
'((0 20 11 28 1 1984 nil nil nil)
|
||||
(0 20 23 12 4 1985 nil nil nil)
|
||||
(0 0 12 15 2 1 nil nil nil)))))
|
||||
|
||||
;;; iso8601-tests.el ends here
|
||||
|
|
|
@ -28,23 +28,23 @@
|
|||
|
||||
(ert-deftest parse-time-tests ()
|
||||
(should (equal (parse-time-string "Mon, 22 Feb 2016 19:35:42 +0100")
|
||||
'(42 35 19 22 2 2016 1 -1 3600 0)))
|
||||
'(42 35 19 22 2 2016 1 -1 3600)))
|
||||
(should (equal (parse-time-string "22 Feb 2016 19:35:42 +0100")
|
||||
'(42 35 19 22 2 2016 nil -1 3600 0)))
|
||||
'(42 35 19 22 2 2016 nil -1 3600)))
|
||||
(should (equal (parse-time-string "22 Feb 2016 +0100")
|
||||
'(nil nil nil 22 2 2016 nil -1 3600 nil)))
|
||||
'(nil nil nil 22 2 2016 nil -1 3600)))
|
||||
(should (equal (parse-time-string "Mon, 22 Feb 16 19:35:42 +0100")
|
||||
'(42 35 19 22 2 2016 1 -1 3600 0)))
|
||||
'(42 35 19 22 2 2016 1 -1 3600)))
|
||||
(should (equal (parse-time-string "Mon, 22 February 2016 19:35:42 +0100")
|
||||
'(42 35 19 22 2 2016 1 -1 3600 0)))
|
||||
'(42 35 19 22 2 2016 1 -1 3600)))
|
||||
(should (equal (parse-time-string "Mon, 22 feb 2016 19:35:42 +0100")
|
||||
'(42 35 19 22 2 2016 1 -1 3600 0)))
|
||||
'(42 35 19 22 2 2016 1 -1 3600)))
|
||||
(should (equal (parse-time-string "Monday, 22 february 2016 19:35:42 +0100")
|
||||
'(42 35 19 22 2 2016 1 -1 3600 0)))
|
||||
'(42 35 19 22 2 2016 1 -1 3600)))
|
||||
(should (equal (parse-time-string "Monday, 22 february 2016 19:35:42 PST")
|
||||
'(42 35 19 22 2 2016 1 nil -28800 0)))
|
||||
'(42 35 19 22 2 2016 1 nil -28800)))
|
||||
(should (equal (parse-time-string "Friday, 21 Sep 2018 13:47:58 PDT")
|
||||
'(58 47 13 21 9 2018 5 t -25200 0)))
|
||||
'(58 47 13 21 9 2018 5 t -25200)))
|
||||
(should (equal (format-time-string
|
||||
"%Y-%m-%d %H:%M:%S"
|
||||
(parse-iso8601-time-string "1998-09-12T12:21:54-0200") t)
|
||||
|
|
|
@ -40,25 +40,31 @@
|
|||
(7879679999900 . 100000)
|
||||
(78796799999999999999 . 1000000000000)))
|
||||
;; UTC.
|
||||
(let ((subsec (time-subtract (time-convert look t)
|
||||
(time-convert look 'integer))))
|
||||
(let ((sec (time-add 59 (time-subtract (time-convert look t)
|
||||
(time-convert look 'integer)))))
|
||||
(should (string-equal
|
||||
(format-time-string "%Y-%m-%d %H:%M:%S.%3N %z" look t)
|
||||
"1972-06-30 23:59:59.999 +0000"))
|
||||
(should (equal (decode-time look t)
|
||||
(list 59 59 23 30 6 1972 5 nil 0 subsec)))
|
||||
(should (equal (decode-time look t 'integer)
|
||||
'(59 59 23 30 6 1972 5 nil 0)))
|
||||
(should (equal (decode-time look t t)
|
||||
(list sec 59 23 30 6 1972 5 nil 0)))
|
||||
;; "UTC0".
|
||||
(should (string-equal
|
||||
(format-time-string format look "UTC0")
|
||||
"1972-06-30 23:59:59.999 +0000 (UTC)"))
|
||||
(should (equal (decode-time look "UTC0")
|
||||
(list 59 59 23 30 6 1972 5 nil 0 subsec)))
|
||||
(should (equal (decode-time look "UTC0" 'integer)
|
||||
'(59 59 23 30 6 1972 5 nil 0)))
|
||||
(should (equal (decode-time look "UTC0" t)
|
||||
(list sec 59 23 30 6 1972 5 nil 0)))
|
||||
;; Negative UTC offset, as a Lisp list.
|
||||
(should (string-equal
|
||||
(format-time-string format look '(-28800 "PST"))
|
||||
"1972-06-30 15:59:59.999 -0800 (PST)"))
|
||||
(should (equal (decode-time look '(-28800 "PST"))
|
||||
(list 59 59 15 30 6 1972 5 nil -28800 subsec)))
|
||||
(should (equal (decode-time look '(-28800 "PST") 'integer)
|
||||
'(59 59 15 30 6 1972 5 nil -28800)))
|
||||
(should (equal (decode-time look '(-28800 "PST") t)
|
||||
(list sec 59 15 30 6 1972 5 nil -28800)))
|
||||
;; Negative UTC offset, as a Lisp integer.
|
||||
(should (string-equal
|
||||
(format-time-string format look -28800)
|
||||
|
@ -67,14 +73,18 @@
|
|||
(if (eq system-type 'windows-nt)
|
||||
"1972-06-30 15:59:59.999 -0800 (ZZZ)"
|
||||
"1972-06-30 15:59:59.999 -0800 (-08)")))
|
||||
(should (equal (decode-time look -28800)
|
||||
(list 59 59 15 30 6 1972 5 nil -28800 subsec)))
|
||||
(should (equal (decode-time look -28800 'integer)
|
||||
'(59 59 15 30 6 1972 5 nil -28800)))
|
||||
(should (equal (decode-time look -28800 t)
|
||||
(list sec 59 15 30 6 1972 5 nil -28800)))
|
||||
;; Positive UTC offset that is not an hour multiple, as a string.
|
||||
(should (string-equal
|
||||
(format-time-string format look "IST-5:30")
|
||||
"1972-07-01 05:29:59.999 +0530 (IST)"))
|
||||
(should (equal (decode-time look "IST-5:30")
|
||||
(list 59 29 5 1 7 1972 6 nil 19800 subsec)))))))
|
||||
(should (equal (decode-time look "IST-5:30" 'integer)
|
||||
'(59 29 5 1 7 1972 6 nil 19800)))
|
||||
(should (equal (decode-time look "IST-5:30" t)
|
||||
(list sec 29 5 1 7 1972 6 nil 19800)))))))
|
||||
|
||||
(ert-deftest decode-then-encode-time ()
|
||||
(let ((time-values (list 0 -2 1 0.0 -0.0 -2.0 1.0
|
||||
|
@ -87,11 +97,13 @@
|
|||
(cons (1+ most-positive-fixnum) 1000000000000)
|
||||
(cons 1000000000000 (1+ most-positive-fixnum)))))
|
||||
(dolist (a time-values)
|
||||
(let* ((d (ignore-errors (decode-time a t)))
|
||||
(let* ((d (ignore-errors (decode-time a t t)))
|
||||
(d-integer (ignore-errors (decode-time a t 'integer)))
|
||||
(e (if d (encode-time d)))
|
||||
(diff (float-time (time-subtract a e))))
|
||||
(should (or (not d)
|
||||
(and (<= 0 diff) (< diff 1))))))))
|
||||
(e-integer (if d-integer (encode-time d-integer))))
|
||||
(should (or (not d) (time-equal-p a e)))
|
||||
(should (or (not d-integer) (time-equal-p (time-convert a 'integer)
|
||||
e-integer)))))))
|
||||
|
||||
;;; This should not dump core.
|
||||
(ert-deftest format-time-string-with-outlandish-zone ()
|
||||
|
@ -151,7 +163,7 @@
|
|||
(ert-deftest encode-time-dst-numeric-zone ()
|
||||
"Check for Bug#35502."
|
||||
(should (time-equal-p
|
||||
(encode-time '(29 31 17 30 4 2019 2 t 7200 0))
|
||||
(encode-time '(29 31 17 30 4 2019 2 t 7200))
|
||||
'(23752 27217))))
|
||||
|
||||
(ert-deftest float-time-precision ()
|
||||
|
|
Loading…
Add table
Reference in a new issue