On 4/20/22 09:56, Max Nikulin wrote:
A typo: double "a".
Thanks, fixed in the attached which I installed in master.
If I get your idea correctly then "January, 31" + "1 month" should be
more impressive as impossible date.
Thanks, good idea; also in the attached patch.
I can not figure out which elisp function can help to
determine wall time for Aug 1 start of day in Cairo:
Africa/Cairo Thu Jul 31 21:59:59 2014 UT = Thu Jul 31 23:59:59 2014 EET
isdst=0 gmtoff=7200
Africa/Cairo Thu Jul 31 22:00:00 2014 UT = Fri Aug 1 01:00:00 2014
EEST isdst=1 gmtoff=10800
input: 2014-08-01 Africa/Cairo
(timezone may be implicit as the system one)
expected output: 01:00:00
Given mktime's limitations there's no trivial way to do this for
arbitrary timestamps, since 00:00 doesn't exist in Cairo that day.
Worse, in some locations near the International Date Line entire days do
not exist, because at 00:00 they advanced the clocks forward 24 hours in
order to move the date line.
It sounds like you're asking for a function that, given a date, yields
the first broken-down timestamp on or after 00:00 of that date. For
something like that, I'd use encode-time on 00:00 of that date to get a
timestamp T, and then use time-add and decode-time to decode T-86400
seconds, T, and T+86400 seconds, and if the decoded times all look fine
then return (decode-time T). If not (i.e., their UTC offsets differ, or
T's decoded time is not 00:00 on the correct date) I'd use binary search
to find discontinuities between T-86400 and T+86400 and look next to
those discontinuities to find timestamps closer to what you want.
Of course this is not ideal - but it's similar to what many mktime
implementations do internally, and it's also similar to what Emacs's
cal-dst already does (maybe you can look there for ideas), so you'd be
in good company.From f98c3f4426fecf794f47f27aebe1f3b854fb1bfd Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Wed, 20 Apr 2022 12:03:19 -0700
Subject: [PATCH] More encode-time pitfall doc fixes
* doc/lispref/os.texi (Time Conversion): Improve discussion of
encode-time pitfalls based on comments by Max Nikulin (Bug#54764#63).
---
doc/lispref/os.texi | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index cabae08970..4138dab09f 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -1670,7 +1670,7 @@ Time Conversion
convention, @var{dst} is @minus{}1 and @var{zone} defaults to the
current time zone rule (@pxref{Time Zone Rules}).
When modernizing an obsolescent caller, ensure that the more-modern
-list equivalent contains 9 elements with a a @code{dst} element that
+list equivalent contains 9 elements with a @code{dst} element that
is @minus{}1, not @code{nil}.
Year numbers less than 100 are not treated specially. If you want them
@@ -1695,22 +1695,28 @@ Time Conversion
For example:
@lisp
-;; Try to compute the time four years from now.
+;; Try to compute the time one month from now.
;; Watch out; this might not work as expected.
(let ((time (decode-time)))
- (setf (decoded-time-year time)
- (+ (decoded-time-year time) 4))
+ (setf (decoded-time-month time)
+ (+ (decoded-time-month time) 1))
time)
@end lisp
@noindent
Unfortunately, this code might not work as expected if the resulting
-time is invalid due to daylight saving transitions, time zone changes,
+time is invalid due to month length differences,
+daylight saving transitions, time zone changes,
or missing leap days or leap seconds. For example, if executed on
-February 29, 2096 this code yields a nonexistent date because 2100 is
-not a leap year. To avoid some (though not all) of the problem, you
+January 30 this code yields a nonexistent date February 30,
+which @code{encode-time} would adjust to early March.
+Similarly, adding four years to February 29, 2096 would yield the
+nonexistent date February 29, 2100; and adding one hour to 01:30 on
+March 13, 2022 in New York would yield a timestamp 02:30 that does not
+exist because clocks sprang forward from 02:00 to 03:00 that day.
+To avoid some (though not all) of the problem, you
can base calculations on the middle of the affected unit, e.g., start
-at July 1 when adding years. Alternatively, you can use the
+at the 15th of the month when adding months. Alternatively, you can use the
@file{calendar} and @file{time-date} libraries.
@end defun
--
2.32.0