From 83f141ae12f2f212355e7354eeb16dc52da98b63 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Wed, 14 Aug 2024 11:35:48 +0300 Subject: [PATCH] Improve documentation of time-parsing functions * doc/lispref/os.texi (Time Parsing): * lisp/calendar/iso8601.el (iso8601-parse): * lisp/calendar/parse-time.el (parse-time-string): Document that these functions don't care about the distinction between local time and UTC. (Bug#72570) (cherry picked from commit 9bedb957bebdca99b1bb96f58ea790e20ed48dee) --- doc/lispref/os.texi | 66 ++++++++++++++++++++++++------------- lisp/calendar/iso8601.el | 18 +++++++--- lisp/calendar/parse-time.el | 11 +++++-- 3 files changed, 65 insertions(+), 30 deletions(-) diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index ddaa1de221c..3ab4b66ba30 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -1788,8 +1788,8 @@ Conversion}). This function parses the time-string @var{string} and returns the corresponding Lisp timestamp. The argument @var{string} should represent a date-time, and should be in one of the forms recognized by -@code{parse-time-string} (see below). This function assumes local time -if @var{string} lacks explicit time zone information, +@code{parse-time-string} (see below). This function assumes Universal +Time if @var{string} lacks explicit time zone information, and assumes earliest values if @var{string} lacks month, day, or time. The operating system limits the range of time and zone values. @end defun @@ -1800,31 +1800,51 @@ structure (@pxref{Time Conversion}). The argument @var{string} should resemble an RFC 822 (or later) or ISO 8601 string, like ``Fri, 25 Mar 2016 16:24:56 +0100'' or ``1998-09-12T12:21:54-0200'', but this function will attempt to parse less well-formed time strings as well. -It parses an incomplete string like ``2024-08-13'' to an incomplete -structure like @samp{(nil nil nil 13 8 2024 nil -1 nil)}, in which -an unknown DST value is @minus{}1 and other unknown values are @code{nil}. + +Note that, unlike @code{decode-time} (@pxref{Time Conversion}), this +function does not interpret the time string, and in particular the +values of daylight-saving and timezone or UTC offset parts of the +@var{string} argument do not affect the returned value of date and time, +they only affect the last two members of the returned decoded time +structure. For example, if the time-zone information is present in +@var{string}, the decoded time structure will include it; otherwise the +time-zone member of the returned value will be @code{nil}. In other +words, this function simply parses the textual representation of date +and time into separate numerical values, and doesn't care whether the +input time is local or UTC. + +If a Lisp program passes the return value of this function to some other +time-related API, it should make sure the @code{nil} members of the +decoded time structure are interpreted correctly, and in particular the +lack of time-zone information is interpreted as UTC or local time, +according to the needs of the calling program. @end defun @vindex ISO 8601 date/time strings @defun iso8601-parse string -This function acts like @code{parse-time-string} except it is stricter -and errors out upon invalid input. It can parse all variants of -the ISO 8601 standard, so in addition to the formats mentioned above, -it also parses things like ``1998W45-3'' (week number) and -``1998-245'' (ordinal day number). -@end defun - -@defun iso8601-parse-duration string -This function parses an ISO 8601 time duration @var{string} -and returns a decoded time structure. -@c FIXME: example? behavior on incomplete input? -@end defun - -@defun iso8601-parse-interval string -This function parses an ISO 8601 time interval @var{string} -and returns three decoded time structures -representing the start, the end, and the duration. -@c FIXME: example? behavior on incomplete input? +For a more strict function (that will error out upon invalid input), +Lisp programs can use this function instead. It can parse all variants +of the ISO 8601 standard, so in addition to the formats mentioned above, +it also parses things like ``1998W45-3'' (week number) and ``1998-245'' +(ordinal day number). To parse durations, there's +@code{iso8601-parse-duration}, and to parse intervals, there's +@code{iso8601-parse-interval}. All these functions return decoded time +structures, except the final one, which returns three of them (the +start, the end, and the duration). + +Like @code{parse-time-string}, this function does not interpret the time +string, and in particular the time-zone designator or UTC offset that is +part of the @var{string} argument does not affect the returned value of +date and time, it only affects the last two members of the returned +decoded time structure. The ISO 8601 standard specifies that date/time +strings that do not include information about UTC relation are assumed +to be in local time, but this function does not do that, because it +doesn't interpret the time values. For example, if the time-zone +information is present in @var{string}, the decoded time structure will +include it; otherwise the time-zone member of the returned value will be +@code{nil}. In other words, this function simply parses the textual +representation of date and time into separate numerical values, and +doesn't care whether the input time is local or UTC. @end defun @defun format-time-string format-string &optional time zone diff --git a/lisp/calendar/iso8601.el b/lisp/calendar/iso8601.el index a31b60eaec2..bb319d54c8c 100644 --- a/lisp/calendar/iso8601.el +++ b/lisp/calendar/iso8601.el @@ -121,11 +121,19 @@ (defun iso8601-parse (string &optional form) "Parse an ISO 8601 date/time string and return a `decode-time' structure. -ISO 8601 date/time strings look like \"2008-03-02T13:47:30+05:30\", -or like shorter, incomplete strings like date \"2008-03-02\", -week number \"2008W32\", and ordinal day number \"2008-234\". -Values returned are identical to those of `decode-time', except -that an unknown DST value is -1 and other unknown values are nil. + +The ISO 8601 date/time strings look like \"2008-03-02T13:47:30\" +or \"2024-04-05T14:30Z\" or \"2024-04-05T12:30−02:00\", +but shorter, incomplete strings like \"2008-03-02\" are valid, as +well as variants like \"2008W32\" (week number) and +\"2008-234\" (ordinal day number). +Note that, unlike `decode-time', this function does not interpret +the time string, and in particular the time-zone designator or UTC +offset that is part of STRING does not affect the returned value of +date and time, it only affects the last two members of the returned +value. This function simply parses the textual representation of +date and time into separate numerical values, and doesn't care +whether the time is local or UTC. See `decode-time' for the meaning of FORM." (if (not (iso8601-valid-p string)) diff --git a/lisp/calendar/parse-time.el b/lisp/calendar/parse-time.el index 9538ea92ee5..f6fc7a8c162 100644 --- a/lisp/calendar/parse-time.el +++ b/lisp/calendar/parse-time.el @@ -154,8 +154,15 @@ or something resembling an RFC 822 (or later) date-time, e.g., \"Wed, 15 Jan 2020 16:12:21 -0800\". This function is somewhat liberal in what format it accepts, and will attempt to return a \"likely\" value even for somewhat malformed strings. -Values returned are identical to those of `decode-time', except -that an unknown DST value is -1 and other unknown values are nil. +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. +Note that, unlike `decode-time', this function does not interpret +the time string, and in particular the values of DST and TZ do not +affect the returned value of date and time, they only affect the +last two members of the returned value. This function simply +parses the textual representation of date and time into separate +numerical values, and doesn't care whether the time is local or UTC. See `decode-time' for the meaning of FORM." (condition-case () -- 2.39.2