emacs-orgmode
[Top][All Lists]
Advanced

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

Re: Observation of hysteresis in a GNU libc time conversion function


From: Max Nikulin
Subject: Re: Observation of hysteresis in a GNU libc time conversion function
Date: Wed, 18 Jan 2023 23:32:08 +0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.4.2

On 18/01/2023 16:54, Ihor Radchenko wrote:
Max Nikulin writes:

           (dt '(-90 -60 -31 -30 -29 -15 0 15 29 30 31 60 90))

This is problematic. You are putting MINUTES out of normal range.

Actually after some experiments and surprising results I figured out what really happens. I modified your example to get the value that you was likely expecting:

(let* ((tz "Europe/Berlin")
       (t1 (encode-time `(0 1 3 29 10 2023 nil -1 ,tz)))
       ;; !!! Try to comment out the line below
       (_ (encode-time `(0 59 1 29 10 2023 nil -1 ,tz)))
       (t2 (encode-time `(0 59 2 29 10 2023 nil -1 ,tz))))
  (list
   (format-time-string "%F %T %z %Z" t1 tz)
   (format-time-string "%F %T %z %Z" t2 tz)
   (time-subtract t1 t2)))
("2023-10-29 03:01:00 +0100 CET" "2023-10-29 02:59:00 +0200 CEST" 3720)

No negative minutes were involved.

I decided that hysteresis example is more funny.

Frankly speaking, I just forgot that I may use (make-decoded-time :minute -40) and `decoded-time-add' since I was not limited by Emacs-26 support.

`encode-time' docstring for Emacs-26 has the following statement:

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.

So I do not think it affects anything. I decided to ask GNU libc developers
https://inbox.sourceware.org/libc-alpha/tq93sc$p3$1@ciao.gmane.io/T/#u
"mktime result may depend on previous calls"

Looking at
https://codecogs.com/library/computing/c/time.h/ctime.php?alias=mktime,
out-of-range minutes are not documented.

Looks like a compilation of unspecified sources. The following is similar to ctime(3) man page

  if structure members are outside their valid
  interval,  they will be normalized (so that, for example,
  40 October is changed into 9 November);

My reading is that out of range values for other "members" are allowed as well. However it may be tricky.

Also, see
https://stackoverflow.com/questions/20104531/weird-mktime-logic-with-negative-seconds

My expectation is that ±1 day (or month) should preserve local time hours (e.g. 11:00 CET -> 11:00 CEST) if such moment of time exists. ±24 hours, ±24*60 minutes, ±24*3600 seconds across DST change should cause appropriate shift of hours (e.g. 11:00 -> 12:00 is possible).

Moreover "out of range" month day 0 is the only way to specify last month day to get

     Jan, 31 <- 1 month -> Feb, 28 (or 29) <- 1 month -> Mar, 31

arithmetic.

However it is hardly implementation specific and GNU date(1) CLI utility, PostgreSQL, PHP timelib, JavaScript Date objects behave differently.

I still do not think it affects my example though.




reply via email to

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