From: Paul Eggert <eggert@cs.ucla.edu> To: Max Nikulin <manikulin@gmail.com> Cc: orgmode <emacs-orgmode@gnu.org>, 54764@debbugs.gnu.org Subject: Re: bug#54764: encode-time: make DST and TIMEZONE fields of the list argument optional ones Date: Wed, 20 Apr 2022 12:17:47 -0700 [thread overview] Message-ID: <37ffb641-a4da-89fd-6ef5-909db5a5fe3c@cs.ucla.edu> (raw) In-Reply-To: <8ba9e258-dd24-a0a0-1aa6-9c2831c05af0@gmail.com> [-- Attachment #1: Type: text/plain, Size: 1934 bytes --] 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. [-- Attachment #2: 0001-More-encode-time-pitfall-doc-fixes.patch --] [-- Type: text/x-patch, Size: 2651 bytes --] From f98c3f4426fecf794f47f27aebe1f3b854fb1bfd Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@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
prev parent reply other threads:[~2022-04-20 19:48 UTC|newest] Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-04-07 12:37 Max Nikulin 2022-04-09 7:52 ` Paul Eggert 2022-04-10 3:57 ` Max Nikulin 2022-04-13 14:40 ` Max Nikulin 2022-04-13 18:35 ` Paul Eggert 2022-04-14 13:19 ` Max Nikulin 2022-04-14 22:46 ` Paul Eggert 2022-04-15 2:14 ` Tim Cross 2022-04-15 17:23 ` Max Nikulin 2022-04-16 19:23 ` Paul Eggert 2022-04-21 16:59 ` Max Nikulin 2022-04-19 2:02 ` Paul Eggert 2022-04-19 5:50 ` Eli Zaretskii 2022-04-19 22:22 ` Paul Eggert 2022-04-20 7:23 ` Eli Zaretskii 2022-04-20 18:19 ` Paul Eggert 2022-04-20 18:41 ` Eli Zaretskii 2022-04-20 19:01 ` Paul Eggert 2022-04-20 19:14 ` Eli Zaretskii 2022-04-20 19:23 ` Paul Eggert 2022-04-20 19:30 ` Eli Zaretskii 2022-04-21 0:11 ` Paul Eggert 2022-04-21 6:44 ` Eli Zaretskii 2022-04-21 23:56 ` Paul Eggert 2022-04-22 5:01 ` Eli Zaretskii 2022-04-23 14:35 ` Bernhard Voelker 2022-04-20 15:07 ` Max Nikulin 2022-04-20 18:29 ` Paul Eggert 2022-04-25 15:30 ` Max Nikulin 2022-04-25 15:37 ` Paul Eggert 2022-04-25 19:49 ` Paul Eggert 2022-04-30 11:22 ` Max Nikulin 2022-05-01 2:32 ` Paul Eggert 2022-05-01 17:15 ` Max Nikulin 2022-04-13 15:12 ` Max Nikulin 2022-04-16 16:26 ` Max Nikulin 2022-04-17 1:58 ` Paul Eggert 2022-04-20 16:56 ` Max Nikulin 2022-04-20 19:17 ` Paul Eggert [this message]
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style List information: https://www.orgmode.org/ * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=37ffb641-a4da-89fd-6ef5-909db5a5fe3c@cs.ucla.edu \ --to=eggert@cs.ucla.edu \ --cc=54764@debbugs.gnu.org \ --cc=emacs-orgmode@gnu.org \ --cc=manikulin@gmail.com \ --subject='Re: bug#54764: encode-time: make DST and TIMEZONE fields of the list argument optional ones' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Code repositories for project(s) associated with this inbox: https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).