emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master b06917a 2/2: decode-time now returns subsec too


From: Paul Eggert
Subject: [Emacs-diffs] master b06917a 2/2: decode-time now returns subsec too
Date: Mon, 5 Aug 2019 21:37:36 -0400 (EDT)

branch: master
commit b06917a4912a60402025286d07d4a195749245c4
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    decode-time now returns subsec too
    
    The list that decode-time returns now contains an extra
    trailing component that counts the subseconds part of the
    original timestamp (Bug#36549).
    This builds on a suggestion by Lars Ingebrigtsen in:
    https://lists.gnu.org/r/emacs-devel/2019-07/msg00734.html
    * doc/lispref/os.texi (Time Conversion):
    * doc/misc/emacs-mime.texi (time-date):
    * etc/NEWS: Document this.
    * lisp/calendar/icalendar.el (icalendar--decode-isodatetime):
    * lisp/calendar/iso8601.el (iso8601-parse)
    (iso8601-parse-time, iso8601-parse-duration)
    (iso8601--decoded-time):
    * lisp/calendar/parse-time.el (parse-time-string):
    * lisp/calendar/time-date.el (make-decoded-time)
    (decoded-time-set-defaults):
    * lisp/org/org.el (org-fix-decoded-time)
    (org-parse-time-string):
    * src/timefns.c (Fdecode_time):
    Generate subsec member for decoded time.
    * lisp/calendar/time-date.el (decoded-time-add)
    Add the decoded subsec too.
    * lisp/simple.el (decoded-time): New subsec member.
    * src/data.c (Frem): Simplify zero-check to match that of new Fmod.
    (integer_mod): New function, with most of the guts of the old Fmod.
    Remove redundant zero-check.
    (Fmod): Use it.
    * src/timefns.c (Fencode_time): Handle new subsec member
    or (with the obsolescent calling convention) subsec arg.
    It defaults to 0.
    * test/lisp/calendar/icalendar-tests.el:
    (icalendar--decode-isodatetime):
    * test/lisp/calendar/iso8601-tests.el (test-iso8601-date-years)
    (test-iso8601-date-dates, test-iso8601-date-obsolete)
    (test-iso8601-date-weeks, test-iso8601-date-ordinals)
    (test-iso8601-time, test-iso8601-combined)
    (test-iso8601-duration, test-iso8601-intervals)
    (standard-test-dates, standard-test-time-of-day-fractions)
    (standard-test-time-of-day-beginning-of-day)
    (standard-test-time-of-day-utc)
    (standard-test-time-of-day-zone)
    (standard-test-date-and-time-of-day, standard-test-interval):
    * test/lisp/calendar/parse-time-tests.el (parse-time-tests):
    * test/src/timefns-tests.el (format-time-string-with-zone)
    (encode-time-dst-numeric-zone):
    Adjust to match new behavior.
---
 doc/lispref/os.texi                    |  40 ++++---
 doc/misc/emacs-mime.texi               |   2 +-
 etc/NEWS                               |  10 +-
 lisp/calendar/icalendar.el             |   2 +-
 lisp/calendar/iso8601.el               |  14 ++-
 lisp/calendar/parse-time.el            |  10 +-
 lisp/calendar/time-date.el             |  14 ++-
 lisp/net/soap-client.el                |   3 +-
 lisp/org/org.el                        |   6 +-
 lisp/simple.el                         |   3 +
 src/data.c                             |  40 +++----
 src/lisp.h                             |   1 +
 src/timefns.c                          |  82 +++++++++-----
 test/lisp/calendar/icalendar-tests.el  |   8 +-
 test/lisp/calendar/iso8601-tests.el    | 190 ++++++++++++++++-----------------
 test/lisp/calendar/parse-time-tests.el |  18 ++--
 test/src/timefns-tests.el              |  14 +--
 17 files changed, 266 insertions(+), 191 deletions(-)

diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index b26d903..70ae39e 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -1482,10 +1482,11 @@ Although @code{(time-convert nil nil)} is equivalent to
 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 nine elements, as follows:
+The return value is a list of ten elements, as follows:
 
 @example
-(@var{seconds} @var{minutes} @var{hour} @var{day} @var{month} @var{year} 
@var{dow} @var{dst} @var{utcoff})
+(@var{seconds} @var{minutes} @var{hour} @var{day} @var{month} @var{year}
+ @var{dow} @var{dst} @var{utcoff} @var{subsec})
 @end example
 
 Here is what the elements mean:
@@ -1513,17 +1514,22 @@ 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
 
 @strong{Common Lisp Note:} Common Lisp has different meanings for
-@var{dow} and @var{utcoff}.
+@var{dow} and @var{utcoff}, and lacks @var{subsec}.
 
 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} and
-@code{decoded-time-zone} accessors can be used.
+@code{decoded-time-weekday}, @code{decoded-time-dst},
+@code{decoded-time-zone} and @code{decoded-time-subsec}
+accessors can be used.
 
 For instance, to increase the year in a decoded time, you could say:
 
@@ -1579,21 +1585,22 @@ 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})} that specifies a
+@var{year} @var{ignored} @var{dst} @var{zone} @var{subsec})} 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
-or more arguments.  The first six arguments @var{second},
+through ten 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 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; otherwise @var{zone} defaults
-to the current time zone rule (@pxref{Time Zone Rules}).  The decoded
-time's @var{dst} component is treated as if it was @minus{}1, and
-@var{form} takes its default value.
+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.
 
 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
@@ -1608,8 +1615,9 @@ 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}, and @var{month};
-for example, day 0 means the day preceding the given month.
+@var{seconds}, @var{minutes}, @var{hour}, @var{day}, @var{month}, and
+@var{subsec}; 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.
diff --git a/doc/misc/emacs-mime.texi b/doc/misc/emacs-mime.texi
index eb829b0..c411bf3 100644
--- a/doc/misc/emacs-mime.texi
+++ b/doc/misc/emacs-mime.texi
@@ -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)
+@result{} (54 21 12 12 9 1998 6 -1 7200 0)
 
 (time-convert
   (date-to-time "Sat Sep 12 12:21:54 1998 +0200")
diff --git a/etc/NEWS b/etc/NEWS
index 116bdb9..734d5fd 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2093,6 +2093,12 @@ 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.
+
++++
 *** 'encode-time' supports a new API '(encode-time TIME)'.
 The old 'encode-time' API is still supported.
 
@@ -2123,8 +2129,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' and 'decoded-time-zone'
-accessors can be used.
+'decoded-time-weekday', 'decoded-time-dst', 'decoded-time-zone',
+and 'decoded-time-subsec' 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'
diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el
index c268870..84f579a 100644
--- a/lisp/calendar/icalendar.el
+++ b/lisp/calendar/icalendar.el
@@ -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)))
+                                 nil -1 zone 0)))
          (condition-case nil
              (decode-time (encode-time decoded-time))
            (error
diff --git a/lisp/calendar/iso8601.el b/lisp/calendar/iso8601.el
index 30352c7..51f5dff 100644
--- a/lisp/calendar/iso8601.el
+++ b/lisp/calendar/iso8601.el
@@ -129,7 +129,8 @@ 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-second date) (decoded-time-second time))
+         (setf (decoded-time-subsec date) (decoded-time-subsec time))))
       ;; The time zone is optional.
       (when zone-string
         (setf (decoded-time-zone date)
@@ -236,6 +237,8 @@ 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)))))))))
@@ -274,7 +277,9 @@ 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)))
+                          :second (or (match-string 7 string) 0)
+                          ;; FIXME: Support subsec.
+                          :subsec 0))
    ;; PnW: Weeks.
    ((iso8601--match iso8601--duration-week-match string)
     (let ((weeks (string-to-number (match-string 1 string))))
@@ -336,7 +341,7 @@ Return the number of minutes."
 
 (cl-defun iso8601--decoded-time (&key second minute hour
                                       day month year
-                                      dst zone)
+                                      dst zone subsec)
   (list (iso8601--value second)
         (iso8601--value minute)
         (iso8601--value hour)
@@ -345,7 +350,8 @@ Return the number of minutes."
         (iso8601--value year)
         nil
         dst
-        zone))
+        zone
+       subsec))
 
 (defun iso8601--encode-time (time)
   "Like `encode-time', but fill in nil values in TIME."
diff --git a/lisp/calendar/parse-time.el b/lisp/calendar/parse-time.el
index e28df97..9af93b5 100644
--- a/lisp/calendar/parse-time.el
+++ b/lisp/calendar/parse-time.el
@@ -27,7 +27,7 @@
 ;; Emacs.  However, parsing time strings is still largely a matter of
 ;; heuristics and no common interface has been designed.
 
-;; `parse-time-string' parses a time in a string and returns a list of 9
+;; `parse-time-string' parses a time in a string and returns a list of
 ;; values, just like `decode-time', where unspecified elements in the
 ;; string are returned as nil (except unspecfied DST is returned as -1).
 ;; `encode-time' may be applied on these values to obtain an internal
@@ -148,7 +148,7 @@ letters, digits, plus or minus signs or colons."
 
 ;;;###autoload
 (defun parse-time-string (string)
-  "Parse the time-string STRING into (SEC MIN HOUR DAY MON YEAR DOW DST TZ).
+  "Parse the time in STRING into (SEC MIN HOUR DAY MON YEAR DOW DST TZ SUBSEC).
 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))
+  (let ((time (list nil nil nil nil nil nil nil -1 nil nil))
        (temp (parse-time-tokenize (downcase string))))
     (while temp
       (let ((parse-time-elt (pop temp))
@@ -193,6 +193,10 @@ 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)
diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el
index 7505332..c22f441 100644
--- a/lisp/calendar/time-date.el
+++ b/lisp/calendar/time-date.el
@@ -423,6 +423,13 @@ changes in daylight saving time are not taken into 
account."
     (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)))
@@ -494,9 +501,9 @@ changes in daylight saving time are not taken into account."
 
 (cl-defun make-decoded-time (&key second minute hour
                                   day month year
-                                  dst zone)
+                                  dst zone subsec)
   "Return a `decoded-time' structure with only the keywords given filled out."
-  (list second minute hour day month year nil dst zone))
+  (list second minute hour day month year nil dst zone subsec))
 
 (defun decoded-time-set-defaults (time &optional default-zone)
   "Set any nil values in `decoded-time' TIME to default values.
@@ -526,6 +533,9 @@ 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)
diff --git a/lisp/net/soap-client.el b/lisp/net/soap-client.el
index 95f208b..eb08511 100644
--- a/lisp/net/soap-client.el
+++ b/lisp/net/soap-client.el
@@ -561,7 +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 DOW (day-of-week) field
+`encode-time').  The differences are the SUBSEC (fractional
+seconds) field is omitted, 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
diff --git a/lisp/org/org.el b/lisp/org/org.el
index cbf085a..e4c075f 100644
--- a/lisp/org/org.el
+++ b/lisp/org/org.el
@@ -17292,10 +17292,10 @@ The command returns the inserted time stamp."
     (put-text-property beg end 'display str)))
 
 (defun org-fix-decoded-time (time)
-  "Set 0 instead of nil for the first 6 elements of time.
+  "Set 0 instead of nil for the time-related elements of time.
 Don't touch the rest."
   (let ((n 0))
-    (mapcar (lambda (x) (if (< (setq n (1+ n)) 7) (or x 0) x)) time)))
+    (mapcar (lambda (x) (if (or (< (setq n (1+ n)) 7) (= n 10)) (or x 0) x)) 
time)))
 
 (defun org-time-stamp-to-now (timestamp-string &optional seconds)
   "Difference between TIMESTAMP-STRING and now in days.
@@ -17779,7 +17779,7 @@ 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))
+              nil nil nil 0))
        ((string-match "^<[^>]+>$" s)
         ;; FIXME: `decode-time' needs to be called with ZONE as its
         ;; second argument.  However, this requires at least Emacs
diff --git a/lisp/simple.el b/lisp/simple.el
index 6f60004..26b8247 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -9089,6 +9089,9 @@ 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.")
   )
 
 
diff --git a/src/data.c b/src/data.c
index 46bd7e0..6db8ea1 100644
--- a/src/data.c
+++ b/src/data.c
@@ -3067,7 +3067,7 @@ Both must be integers or markers.  */)
   CHECK_INTEGER_COERCE_MARKER (y);
 
   /* A bignum can never be 0, so don't check that case.  */
-  if (FIXNUMP (y) && XFIXNUM (y) == 0)
+  if (EQ (y, make_fixnum (0)))
     xsignal0 (Qarith_error);
 
   if (FIXNUMP (x) && FIXNUMP (y))
@@ -3081,30 +3081,14 @@ Both must be integers or markers.  */)
     }
 }
 
-DEFUN ("mod", Fmod, Smod, 2, 2, 0,
-       doc: /* Return X modulo Y.
-The result falls between zero (inclusive) and Y (exclusive).
-Both X and Y must be numbers or markers.  */)
-  (register Lisp_Object x, Lisp_Object y)
+/* Return X mod Y.  Both must be integers and Y must be nonzero.  */
+Lisp_Object
+integer_mod (Lisp_Object x, Lisp_Object y)
 {
-  CHECK_NUMBER_COERCE_MARKER (x);
-  CHECK_NUMBER_COERCE_MARKER (y);
-
-  /* Note that a bignum can never be 0, so we don't need to check that
-     case.  */
-  if (FIXNUMP (y) && XFIXNUM (y) == 0)
-    xsignal0 (Qarith_error);
-
-  if (FLOATP (x) || FLOATP (y))
-    return fmod_float (x, y);
-
   if (FIXNUMP (x) && FIXNUMP (y))
     {
       EMACS_INT i1 = XFIXNUM (x), i2 = XFIXNUM (y);
 
-      if (i2 == 0)
-       xsignal0 (Qarith_error);
-
       i1 %= i2;
 
       /* If the "remainder" comes out with the wrong sign, fix it.  */
@@ -3128,6 +3112,22 @@ Both X and Y must be numbers or markers.  */)
     }
 }
 
+DEFUN ("mod", Fmod, Smod, 2, 2, 0,
+       doc: /* Return X modulo Y.
+The result falls between zero (inclusive) and Y (exclusive).
+Both X and Y must be numbers or markers.  */)
+  (Lisp_Object x, Lisp_Object y)
+{
+  CHECK_NUMBER_COERCE_MARKER (x);
+  CHECK_NUMBER_COERCE_MARKER (y);
+
+  /* A bignum can never be 0, so don't check that case.  */
+  if (EQ (y, make_fixnum (0)))
+    xsignal0 (Qarith_error);
+
+  return (FLOATP (x) || FLOATP (y) ? fmod_float : integer_mod) (x, y);
+}
+
 static Lisp_Object
 minmax_driver (ptrdiff_t nargs, Lisp_Object *args,
               enum Arith_Comparison comparison)
diff --git a/src/lisp.h b/src/lisp.h
index f437609..63baab5 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -3581,6 +3581,7 @@ extern void set_default_internal (Lisp_Object, 
Lisp_Object,
 extern Lisp_Object expt_integer (Lisp_Object, Lisp_Object);
 extern void syms_of_data (void);
 extern void swap_in_global_binding (struct Lisp_Symbol *);
+extern Lisp_Object integer_mod (Lisp_Object, Lisp_Object);
 
 /* Defined in cmds.c */
 extern void syms_of_cmds (void);
diff --git a/src/timefns.c b/src/timefns.c
index 4310409..953e246 100644
--- a/src/timefns.c
+++ b/src/timefns.c
@@ -1296,7 +1296,7 @@ usage: (format-time-string FORMAT-STRING &optional TIME 
ZONE)  */)
 }
 
 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).
+       doc: /* Decode a time value as (SEC MINUTE HOUR DAY MONTH YEAR DOW DST 
UTCOFF SUBSEC).
 The optional TIME is the time value to convert.  See
 `format-time-string' for the various forms of a time value.
 
@@ -1309,10 +1309,10 @@ without consideration for daylight saving time.
 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' and `decoded-time-zone'
-accessors can be used.
+`decoded-time-weekday', `decoded-time-dst', `decoded-time-zone' and
+`decoded-time-subsec' accessors can be used.
 
-The list has the following nine members: SEC is an integer between 0
+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
 between 0 and 23.  DAY is an integer between 1 and 31.  MONTH is an
@@ -1321,13 +1321,20 @@ 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.  (Note that
-Common Lisp has different meanings for DOW and UTCOFF.)
+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.)
 
 usage: (decode-time &optional TIME ZONE)  */)
   (Lisp_Object specified_time, Lisp_Object zone)
 {
-  time_t time_spec = lisp_seconds_argument (specified_time);
+  struct lisp_time lt = lisp_time_struct (specified_time, 0);
+  struct timespec ts = lisp_to_timespec (lt);
+  if (! timespec_valid_p (ts))
+    time_overflow ();
+  time_t time_spec = ts.tv_sec;
   struct tm local_tm, gmt_tm;
   timezone_t tz = tzlookup (zone, false);
   struct tm *tm = emacs_localtime_rz (tz, &time_spec, &local_tm);
@@ -1367,7 +1374,10 @@ 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));
+                : Qnil),
+               (EQ (lt.hz, make_fixnum (1))
+                ? make_fixnum (0)
+                : Fcons (integer_mod (lt.ticks, lt.hz), lt.hz)));
 }
 
 /* Return OBJ - OFFSET, checking that OBJ is a valid integer and that
@@ -1398,7 +1408,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).
+TIME is a list (SECOND MINUTE HOUR DAY MONTH YEAR IGNORED DST ZONE SUBSEC).
 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
@@ -1407,15 +1417,18 @@ 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.
+saving flag to be guessed.  SUBSEC is either 0 or a Lisp timestamp
+in (TICKS . HZ) form.
 
 As an obsolescent calling convention, if this function is called with
-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; otherwise ZONE is assumed to be nil.
+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.
@@ -1429,14 +1442,14 @@ usage: (encode-time TIME &rest OBSOLESCENT-ARGUMENTS)  
*/)
   (ptrdiff_t nargs, Lisp_Object *args)
 {
   struct tm tm;
-  Lisp_Object zone = Qnil;
+  Lisp_Object zone = Qnil, subsec = make_fixnum (0);
   Lisp_Object a = args[0];
   tm.tm_isdst = -1;
 
   if (nargs == 1)
     {
       Lisp_Object tail = a;
-      for (int i = 0; i < 9; i++, tail = XCDR (tail))
+      for (int i = 0; i < 10; 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);
@@ -1445,11 +1458,11 @@ usage: (encode-time TIME &rest OBSOLESCENT-ARGUMENTS)  
*/)
       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);
       a = XCDR (a);
-      Lisp_Object dstflag = XCAR (a);
-      a = XCDR (a);
-      zone = XCAR (a);
+      Lisp_Object dstflag = XCAR (a); a = XCDR (a);
+      zone = XCAR (a); a = XCDR (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));
@@ -1457,6 +1470,11 @@ 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);
@@ -1474,9 +1492,25 @@ usage: (encode-time TIME &rest OBSOLESCENT-ARGUMENTS)  
*/)
   if (tm.tm_wday < 0)
     time_error (mktime_errno);
 
-  return (CURRENT_TIME_LIST
-         ? list2 (hi_time (value), lo_time (value))
-         : INT_TO_INTEGER (value));
+  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))
+           ? list2 (hi_time (value), lo_time (value))
+           : lispint_arith (INT_TO_INTEGER (value), subsec, false));
+
+  xsignal2 (Qerror, build_string ("Invalid subsec"), subsec);
 }
 
 DEFUN ("time-convert", Ftime_convert, Stime_convert, 1, 2, 0,
diff --git a/test/lisp/calendar/icalendar-tests.el 
b/test/lisp/calendar/icalendar-tests.el
index baea480..060cd8c 100644
--- a/test/lisp/calendar/icalendar-tests.el
+++ b/test/lisp/calendar/icalendar-tests.el
@@ -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)
+          (should (equal '(0 0 10 1 1 2013 2 nil 7200 0)
                          (icalendar--decode-isodatetime "20130101T100000")))
           ;; 1 Aug 2013 10:00 (DST)
-          (should (equal '(0 0 10 1 8 2013 4 t 10800)
+          (should (equal '(0 0 10 1 8 2013 4 t 10800 0)
                          (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)
+          (should (equal '(0 0 1 1 1 2014 3 nil 7200 0)
                          (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)
+          (should (equal '(0 0 13 1 8 2013 4 t 10800 0)
                          (icalendar--decode-isodatetime "20130801T100000Z")))
 
           )
diff --git a/test/lisp/calendar/iso8601-tests.el 
b/test/lisp/calendar/iso8601-tests.el
index 35c319e..3f1149c 100644
--- a/test/lisp/calendar/iso8601-tests.el
+++ b/test/lisp/calendar/iso8601-tests.el
@@ -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 1985 nil nil nil nil)))
   (should (equal (iso8601-parse-date "-0003")
-                 '(nil nil nil nil nil -4 nil nil nil)))
+                 '(nil nil nil nil nil -4 nil nil nil nil)))
   (should (equal (iso8601-parse-date "+1985")
-                 '(nil nil nil nil nil 1985 nil nil nil))))
+                 '(nil nil nil nil nil 1985 nil 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 14 3 1985 nil nil nil nil)))
   (should (equal (iso8601-parse-date "19850314")
-                 '(nil nil nil 14 3 1985 nil nil nil)))
+                 '(nil nil nil 14 3 1985 nil nil nil nil)))
   (should (equal (iso8601-parse-date "1985-02")
-                 '(nil nil nil nil 2 1985 nil nil nil))))
+                 '(nil nil nil nil 2 1985 nil 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 1 2 nil nil nil nil nil)))
   (should (equal (iso8601-parse-date "--0201")
-                 '(nil nil nil 1 2 nil nil nil nil))))
+                 '(nil nil nil 1 2 nil 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 27 9 2008 nil nil nil nil)))
   (should (equal (iso8601-parse-date "2009W01-1")
-                 '(nil nil nil 29 12 2008 nil nil nil)))
+                 '(nil nil nil 29 12 2008 nil nil nil nil)))
   (should (equal (iso8601-parse-date "2009W53-7")
-                 '(nil nil nil 3 1 2010 nil nil nil))))
+                 '(nil nil nil 3 1 2010 nil 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 5 4 1981 nil 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)))
+                 '(30 47 13 nil nil nil nil nil nil 0)))
   (should (equal (iso8601-parse-time "134730")
-                 '(30 47 13 nil nil nil nil nil nil)))
+                 '(30 47 13 nil nil nil nil nil nil 0)))
   (should (equal (iso8601-parse-time "1347")
-                 '(0 47 13 nil nil nil nil nil nil))))
+                 '(0 47 13 nil nil nil nil nil nil 0))))
 
 (ert-deftest test-iso8601-combined ()
   (should (equal (iso8601-parse "2008-03-02T13:47:30")
-                 '(30 47 13 2 3 2008 nil nil nil)))
+                 '(30 47 13 2 3 2008 nil nil nil 0)))
   (should (equal (iso8601-parse "2008-03-02T13:47:30Z")
-                 '(30 47 13 2 3 2008 nil nil 0)))
+                 '(30 47 13 2 3 2008 nil nil 0 0)))
   (should (equal (iso8601-parse "2008-03-02T13:47:30+01:00")
-                 '(30 47 13 2 3 2008 nil nil 3600)))
+                 '(30 47 13 2 3 2008 nil nil 3600 0)))
   (should (equal (iso8601-parse "2008-03-02T13:47:30-01")
-                 '(30 47 13 2 3 2008 nil nil -3600))))
+                 '(30 47 13 2 3 2008 nil nil -3600 0))))
 
 (ert-deftest test-iso8601-duration ()
   (should (equal (iso8601-parse-duration "P3Y6M4DT12H30M5S")
-                 '(5 30 12 4 6 3 nil nil nil)))
+                 '(5 30 12 4 6 3 nil nil nil 0)))
   (should (equal (iso8601-parse-duration "P1M")
-                 '(0 0 0 0 1 0 nil nil nil)))
+                 '(0 0 0 0 1 0 nil nil nil 0)))
   (should (equal (iso8601-parse-duration "PT1M")
-                 '(0 1 0 0 0 0 nil nil nil)))
+                 '(0 1 0 0 0 0 nil nil nil 0)))
   (should (equal (iso8601-parse-duration "P0003-06-04T12:30:05")
-                 '(5 30 12 4 6 3 nil nil nil))))
+                 '(5 30 12 4 6 3 nil nil nil 0))))
 
 (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 30 15 11 5 2008 nil nil 0)
+           '((0 0 13 1 3 2007 nil nil 0 0)
+             (0 30 15 11 5 2008 nil nil 0 0)
              ;; Hm...  can't really use decode-time for time differences...
-             (0 30 2 14 3 1971 0 nil 0))))
+             (0 30 2 14 3 1971 0 nil 0 0))))
   (should (equal (iso8601-parse-interval "2007-03-01T13:00:00Z/P1Y2M10DT2H30M")
-                 '((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))))
+                 '((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))))
   (should (equal (iso8601-parse-interval "P1Y2M10DT2H30M/2008-05-11T15:30:00Z")
-                 '((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)))))
+                 '((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)))))
 
 (ert-deftest standard-test-dates ()
   (should (equal (iso8601-parse-date "19850412")
-                 '(nil nil nil 12 4 1985 nil nil nil)))
+                 '(nil nil nil 12 4 1985 nil nil nil nil)))
   (should (equal (iso8601-parse-date "1985-04-12")
-                 '(nil nil nil 12 4 1985 nil nil nil)))
+                 '(nil nil nil 12 4 1985 nil nil nil nil)))
 
   (should (equal (iso8601-parse-date "1985102")
-                 '(nil nil nil 12 4 1985 nil nil nil)))
+                 '(nil nil nil 12 4 1985 nil nil nil nil)))
   (should (equal (iso8601-parse-date "1985-102")
-                 '(nil nil nil 12 4 1985 nil nil nil)))
+                 '(nil nil nil 12 4 1985 nil nil nil nil)))
 
   (should (equal (iso8601-parse-date "1985W155")
-                 '(nil nil nil 12 4 1985 nil nil nil)))
+                 '(nil nil nil 12 4 1985 nil nil nil nil)))
   (should (equal (iso8601-parse-date "1985-W15-5")
-                 '(nil nil nil 12 4 1985 nil nil nil)))
+                 '(nil nil nil 12 4 1985 nil nil nil nil)))
 
   (should (equal (iso8601-parse-date "1985W15")
-                 '(nil nil nil 7 4 1985 nil nil nil)))
+                 '(nil nil nil 7 4 1985 nil nil nil nil)))
   (should (equal (iso8601-parse-date "1985-W15")
-                 '(nil nil nil 7 4 1985 nil nil nil)))
+                 '(nil nil nil 7 4 1985 nil nil nil nil)))
 
   (should (equal (iso8601-parse-date "1985-04")
-                 '(nil nil nil nil 4 1985 nil nil nil)))
+                 '(nil nil nil nil 4 1985 nil nil nil nil)))
 
   (should (equal (iso8601-parse-date "1985")
-                 '(nil nil nil nil nil 1985 nil nil nil)))
+                 '(nil nil nil nil nil 1985 nil nil nil nil)))
 
   (should (equal (iso8601-parse-date "+1985-04-12")
-                 '(nil nil nil 12 4 1985 nil nil nil)))
+                 '(nil nil nil 12 4 1985 nil nil nil nil)))
   (should (equal (iso8601-parse-date "+19850412")
-                 '(nil nil nil 12 4 1985 nil nil nil))))
+                 '(nil nil nil 12 4 1985 nil 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)))
+                 '(46 27 15 nil nil nil nil nil nil 0)))
   (should (equal (iso8601-parse-time "15:27:46")
-                 '(46 27 15 nil nil nil nil nil nil)))
+                 '(46 27 15 nil nil nil nil nil nil 0)))
 
   (should (equal (iso8601-parse-time "1528")
-                 '(0 28 15 nil nil nil nil nil nil)))
+                 '(0 28 15 nil nil nil nil nil nil 0)))
   (should (equal (iso8601-parse-time "15:28")
-                 '(0 28 15 nil nil nil nil nil nil)))
+                 '(0 28 15 nil nil nil nil nil nil 0)))
 
   (should (equal (iso8601-parse-time "15")
-                 '(0 0 15 nil nil nil nil nil nil))))
+                 '(0 0 15 nil nil nil nil nil nil 0))))
 
 (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)))
+  ;;                '(46 27 15 nil nil nil nil nil nil (5 . 10))))
   ;; (should (equal (iso8601-parse-time "15:27:35,5")
-  ;;                '(46 27 15 nil nil nil nil nil nil)))
+  ;;                '(46 27 15 nil nil nil nil nil nil (5 . 10))))
   )
 
 (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 nil nil nil nil nil nil 0)))
   (should (equal (iso8601-parse-time "00:00:00")
-                 '(0 0 0 nil nil nil nil nil nil)))
+                 '(0 0 0 nil nil nil nil nil nil 0)))
 
   (should (equal (iso8601-parse-time "0000")
-                 '(0 0 0 nil nil nil nil nil nil)))
+                 '(0 0 0 nil nil nil nil nil nil 0)))
   (should (equal (iso8601-parse-time "00:00")
-                 '(0 0 0 nil nil nil nil nil nil))))
+                 '(0 0 0 nil nil nil nil nil nil 0))))
 
 (ert-deftest standard-test-time-of-day-utc ()
   (should (equal (iso8601-parse-time "232030Z")
-                 '(30 20 23 nil nil nil nil nil 0)))
+                 '(30 20 23 nil nil nil nil nil 0 0)))
   (should (equal (iso8601-parse-time "23:20:30Z")
-                 '(30 20 23 nil nil nil nil nil 0)))
+                 '(30 20 23 nil nil nil nil nil 0 0)))
 
   (should (equal (iso8601-parse-time "2320Z")
-                 '(0 20 23 nil nil nil nil nil 0)))
+                 '(0 20 23 nil nil nil nil nil 0 0)))
   (should (equal (iso8601-parse-time "23:20Z")
-                 '(0 20 23 nil nil nil nil nil 0)))
+                 '(0 20 23 nil nil nil nil nil 0 0)))
 
   (should (equal (iso8601-parse-time "23Z")
-                 '(0 0 23 nil nil nil nil nil 0))))
+                 '(0 0 23 nil nil nil nil nil 0 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)))
+                 '(46 27 15 nil nil nil nil nil 3600 0)))
   (should (equal (iso8601-parse-time "15:27:46+0100")
-                 '(46 27 15 nil nil nil nil nil 3600)))
+                 '(46 27 15 nil nil nil nil nil 3600 0)))
 
   (should (equal (iso8601-parse-time "152746+01")
-                 '(46 27 15 nil nil nil nil nil 3600)))
+                 '(46 27 15 nil nil nil nil nil 3600 0)))
   (should (equal (iso8601-parse-time "15:27:46+01")
-                 '(46 27 15 nil nil nil nil nil 3600)))
+                 '(46 27 15 nil nil nil nil nil 3600 0)))
 
   (should (equal (iso8601-parse-time "152746-0500")
-                 '(46 27 15 nil nil nil nil nil -18000)))
+                 '(46 27 15 nil nil nil nil nil -18000 0)))
   (should (equal (iso8601-parse-time "15:27:46-0500")
-                 '(46 27 15 nil nil nil nil nil -18000)))
+                 '(46 27 15 nil nil nil nil nil -18000 0)))
 
   (should (equal (iso8601-parse-time "152746-05")
-                 '(46 27 15 nil nil nil nil nil -18000)))
+                 '(46 27 15 nil nil nil nil nil -18000 0)))
   (should (equal (iso8601-parse-time "15:27:46-05")
-                 '(46 27 15 nil nil nil nil nil -18000))))
+                 '(46 27 15 nil nil nil nil nil -18000 0))))
 
 (ert-deftest standard-test-date-and-time-of-day ()
   (should (equal (iso8601-parse "19850412T101530")
-                 '(30 15 10 12 4 1985 nil nil nil)))
+                 '(30 15 10 12 4 1985 nil nil nil 0)))
   (should (equal (iso8601-parse "1985-04-12T10:15:30")
-                 '(30 15 10 12 4 1985 nil nil nil)))
+                 '(30 15 10 12 4 1985 nil nil nil 0)))
 
   (should (equal (iso8601-parse "1985102T235030Z")
-                 '(30 50 23 12 4 1985 nil nil 0)))
+                 '(30 50 23 12 4 1985 nil nil 0 0)))
   (should (equal (iso8601-parse "1985-102T23:50:30Z")
-                 '(30 50 23 12 4 1985 nil nil 0)))
+                 '(30 50 23 12 4 1985 nil nil 0 0)))
 
   (should (equal (iso8601-parse "1985W155T235030")
-                 '(30 50 23 12 4 1985 nil nil nil)))
+                 '(30 50 23 12 4 1985 nil nil nil 0)))
   (should (equal (iso8601-parse "1985-W155T23:50:30")
-                 '(30 50 23 12 4 1985 nil nil nil))))
+                 '(30 50 23 12 4 1985 nil nil nil 0))))
 
 (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 30 10 25 6 1985 nil nil 0)
-                   (10 9 11 15 3 1970 0 nil 0))))
+                 '((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))))
   (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 30 10 25 6 1985 nil nil 0)
-                   (10 9 11 15 3 1970 0 nil 0))))
+                 '((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))))
 
   ;; 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)))
+                 '(30 20 10 15 10 2 nil nil nil 0)))
 
   (should (equal (iso8601-parse-duration "P00021015T102030")
-                 '(30 20 10 15 10 2 nil nil nil)))
+                 '(30 20 10 15 10 2 nil nil nil 0)))
   (should (equal (iso8601-parse-duration "P0002-10-15T10:20:30")
-                 '(30 20 10 15 10 2 nil nil nil)))
+                 '(30 20 10 15 10 2 nil nil nil 0)))
 
   ;; 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 6 1 nil nil nil 0)))
   (should (equal (iso8601-parse-duration "P0001-06")
-                 '(nil nil nil nil 6 1 nil nil nil)))
+                 '(nil nil nil nil 6 1 nil 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 72 0 0 0 nil nil nil 0)))
 
   ;; 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 20 11 28 6 1986 nil nil nil)
-                   (0 0 12 15 2 1 nil nil nil))))
+                 '((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))))
   (should (equal (iso8601-parse-interval "1985-04-12T23:20:00/P1Y2M15DT12H")
-                 '((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))))
+                 '((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))))
 
   ;; 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 20 23 12 4 1985 nil nil nil)
-                   (0 0 12 15 2 1 nil nil nil)))))
+                 '((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)))))
 
 ;;; iso8601-tests.el ends here
diff --git a/test/lisp/calendar/parse-time-tests.el 
b/test/lisp/calendar/parse-time-tests.el
index 7435620..61a3838 100644
--- a/test/lisp/calendar/parse-time-tests.el
+++ b/test/lisp/calendar/parse-time-tests.el
@@ -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)))
+                 '(42 35 19 22 2 2016 1 -1 3600 0)))
   (should (equal (parse-time-string "22 Feb 2016 19:35:42 +0100")
-                 '(42 35 19 22 2 2016 nil -1 3600)))
+                 '(42 35 19 22 2 2016 nil -1 3600 0)))
   (should (equal (parse-time-string "22 Feb 2016 +0100")
-                 '(nil nil nil 22 2 2016 nil -1 3600)))
+                 '(nil nil nil 22 2 2016 nil -1 3600 nil)))
   (should (equal (parse-time-string "Mon, 22 Feb 16 19:35:42 +0100")
-                 '(42 35 19 22 2 2016 1 -1 3600)))
+                 '(42 35 19 22 2 2016 1 -1 3600 0)))
   (should (equal (parse-time-string "Mon, 22 February 2016 19:35:42 +0100")
-                 '(42 35 19 22 2 2016 1 -1 3600)))
+                 '(42 35 19 22 2 2016 1 -1 3600 0)))
   (should (equal (parse-time-string "Mon, 22 feb 2016 19:35:42 +0100")
-                 '(42 35 19 22 2 2016 1 -1 3600)))
+                 '(42 35 19 22 2 2016 1 -1 3600 0)))
   (should (equal (parse-time-string "Monday, 22 february 2016 19:35:42 +0100")
-                 '(42 35 19 22 2 2016 1 -1 3600)))
+                 '(42 35 19 22 2 2016 1 -1 3600 0)))
   (should (equal (parse-time-string "Monday, 22 february 2016 19:35:42 PST")
-                 '(42 35 19 22 2 2016 1 nil -28800)))
+                 '(42 35 19 22 2 2016 1 nil -28800 0)))
   (should (equal (parse-time-string "Friday, 21 Sep 2018 13:47:58 PDT")
-                 '(58 47 13 21 9 2018 5 t -25200)))
+                 '(58 47 13 21 9 2018 5 t -25200 0)))
   (should (equal (format-time-string
                  "%Y-%m-%d %H:%M:%S"
                  (parse-iso8601-time-string "1998-09-12T12:21:54-0200") t)
diff --git a/test/src/timefns-tests.el b/test/src/timefns-tests.el
index fae058e..feb8fc7 100644
--- a/test/src/timefns-tests.el
+++ b/test/src/timefns-tests.el
@@ -40,23 +40,25 @@
                    (7879679999900 . 100000)
                    (78796799999999999999 . 1000000000000)))
       ;; UTC.
+     (let ((subsec (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)
-                    '(59 59 23 30 6 1972 5 nil 0)))
+                    (list 59 59 23 30 6 1972 5 nil 0 subsec)))
       ;; "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")
-                    '(59 59 23 30 6 1972 5 nil 0)))
+                    (list 59 59 23 30 6 1972 5 nil 0 subsec)))
       ;; 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"))
-                    '(59 59 15 30 6 1972 5 nil -28800)))
+                    (list 59 59 15 30 6 1972 5 nil -28800 subsec)))
       ;; Negative UTC offset, as a Lisp integer.
       (should (string-equal
               (format-time-string format look -28800)
@@ -66,13 +68,13 @@
                   "1972-06-30 15:59:59.999 -0800 (ZZZ)"
                 "1972-06-30 15:59:59.999 -0800 (-08)")))
       (should (equal (decode-time look -28800)
-                    '(59 59 15 30 6 1972 5 nil -28800)))
+                    (list 59 59 15 30 6 1972 5 nil -28800 subsec)))
       ;; 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")
-                    '(59 29 5 1 7 1972 6 nil 19800))))))
+                    (list 59 29 5 1 7 1972 6 nil 19800 subsec)))))))
 
 (ert-deftest decode-then-encode-time ()
   (let ((time-values (list 0 -2 1 0.0 -0.0 -2.0 1.0
@@ -146,5 +148,5 @@
 (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))
+             (encode-time '(29 31 17 30 4 2019 2 t 7200 0))
              '(23752 27217))))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]