emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Max Nikulin <manikulin@gmail.com>
To: Paul Eggert <eggert@cs.ucla.edu>, 54764@debbugs.gnu.org
Cc: emacs-orgmode@gnu.org
Subject: Re: bug#54764: encode-time: make DST and TIMEZONE fields of the list argument optional ones
Date: Wed, 13 Apr 2022 21:40:17 +0700	[thread overview]
Message-ID: <c6525aa8-1496-8ebe-cf2a-24f65cc44672@gmail.com> (raw)
In-Reply-To: <149de00f-115b-5367-414f-c7700ef8966b@cs.ucla.edu>

On 09/04/2022 14:52, Paul Eggert wrote:
> On 4/7/22 05:37, Max Nikulin wrote:
> 
>>  From my point of view it is better to change implementation of 
>> `encode-time' so that it may accept 6-component list SECOND...YEAR. It 
>> should not add noticeable performance penalty but makes the function 
>> more convenient in use.
> 
> Unfortunately it makes the function more convenient to use incorrectly. 
> This was part of the motivation for the API change. The obsolescent 
> calling convention has no way to deal with ambiguous timestamps like 
> 2022-11-06 01:30 when TZ="America/Los_Angeles". Org mode surely has bugs 
> in this area, although I don't have time to scout them out.

Handling DST is a step forward, it is an important case. Unfortunately 
there are enough peculiarities in the time zoo. I do not think new 
interface can be used correctly in the following case of time transition 
with no change of DST:

#+name: encode-time-and-format
#+begin_src elisp :var time=nil :var tz=() :var dst=-1
   (let* ((seconds-year
	  (reverse (mapcar #'string-to-number (split-string time "[- :]"))))
	 (time-list (append seconds-year (list nil dst tz))))
     (format-time-string "%F %T %Z %z" (encode-time time-list) tz))
#+end_src

zdump -v Africa/Juba
...
Africa/Juba  Sun Jan 31 20:59:59 2021 UT = Sun Jan 31 23:59:59 2021 EAT 
isdst=0 gmtoff=10800
Africa/Juba  Sun Jan 31 21:00:00 2021 UT = Sun Jan 31 23:00:00 2021 CAT 
isdst=0 gmtoff=7200

#+call: encode-time-and-format(time="2021-01-31 23:30:00", 
tz="Africa/Juba", dst=-1)

#+RESULTS:
: 2021-01-31 23:30:00 CAT +0200

#+call: encode-time-and-format(time="2021-01-31 23:30:00", 
tz="Africa/Juba", dst=())

#+RESULTS:
: 2021-01-31 23:30:00 CAT +0200

#+call: encode-time-and-format(time="2021-01-31 23:30:00", 
tz="Africa/Juba", dst='t)
: Debugger entered--Lisp error: (error "Specified time is not 
representable")


I do not see a way to get 23:30 EAT +0300. For you example with regular 
DST transition there is no any problem:


#+call: encode-time-and-format(time="2022-11-06 01:30:00", 
tz="America/Los_Angeles", dst=-1)

#+RESULTS:
: 2022-11-06 01:30:00 PDT -0700

#+call: encode-time-and-format(time="2022-11-06 01:30:00", 
tz="America/Los_Angeles", dst=())

#+RESULTS:
: 2022-11-06 01:30:00 PST -0800

#+call: encode-time-and-format(time="2022-11-06 01:30:00", 
tz="America/Los_Angeles", dst='t)

#+RESULTS:
: 2022-11-06 01:30:00 PDT -0700

> PS. Org mode usually uses encode-time for calendrical calculations. This 
> is dicey, as some days don't exist (for example, December 30, 2011 does 
> not exist if TZ="Pacific/Apia", because Samoa moved across the 
> International Date Line that day). And it's also dicey when Org mode 
> uses 00:00:00 (midnight at the start of the day) as a timestamp 
> representing the entire day, as it's all too common for midnight to not 
> exist (or to be duplicated) due to a DST transition. Generally speaking, 
> when Org mode is doing calendrical calculations it should use 
> calendrical functions rather than encode-time+decode-time, which are 
> best used for time calculations not calendar calculations. (I realize 
> that fixing this in Org would be nontrivial; perhaps I should file this 
> "PS" as an Org bug report for whoever has time to fix it....)

Then `encode-time' should only accept time zone as time offset and 
should not allow default or named value that may be ambiguous. However 
my opinion is that is should be possible to provide hints to 
`encode-time' to get deterministic behavior in the case of time transitions.

> diff --git a/lisp/org/org-compat.el b/lisp/org/org-compat.el
> index 819ce74d93..247373d6b9 100644
> --- a/lisp/org/org-compat.el
> +++ b/lisp/org/org-compat.el
> @@ -115,6 +115,27 @@ org-table1-hline-regexp
>    (defun org-time-convert-to-list (time)
>      (seconds-to-time (float-time time))))
>  
> +;; Like Emacs 27+ `encode-time' with one argument.
> +(if (ignore-errors (encode-time (decode-time)))
> +    (defsubst org-encode-time-1 (time)
> +      (encode-time time))
> +  (defun org-encode-time-1 (time)
> +    (let ((dst-zone (nthcdr 7 time)))
> +      (unless (consp (cdr dst-zone))
> +	(signal wrong-type-argument (list time)))
> +      (let ((etime (apply #'encode-time time))
> +	    (dst (car dst-zone))
> +	    (zone (cadr dst-zone)))
> +	(when (and (symbolp dst) (not (integerp zone)) (not (consp zone)))
> +	  (let* ((detime (decode-time etime))
> +		 (dedst (nth 7 detime)))
> +	    (when (and (not (eq dedst dst)) (symbolp dedst))
> +	      ;; Assume one-hour DST and adjust the timestamp.
> +	      (setq etime (time-add etime (seconds-to-time
> +					   (- (if dedst 3600 0)
> +					      (if dst 3600 0))))))))

I am against this workaround. It fixes (to some extent) usual DST 
transitions, but it adds another bug

Australia/Lord_Howe  Sat Apr  2 14:59:59 2022 UT = Sun Apr  3 01:59:59 
2022 +11 isdst=1 gmtoff=39600
Australia/Lord_Howe  Sat Apr  2 15:00:00 2022 UT = Sun Apr  3 01:30:00 
2022 +1030 isdst=0 gmtoff=37800
Australia/Lord_Howe  Sat Oct  1 15:29:59 2022 UT = Sun Oct  2 01:59:59 
2022 +1030 isdst=0 gmtoff=37800
Australia/Lord_Howe  Sat Oct  1 15:30:00 2022 UT = Sun Oct  2 02:30:00 
2022 +11 isdst=1 gmtoff=39600

> +	etime))))
> +
>  ;; `newline-and-indent' did not take a numeric argument before 27.1.
>  (if (version< emacs-version "27")
>      (defsubst org-newline-and-indent (&optional _arg)


  parent reply	other threads:[~2022-04-13 14:46 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-07 12:37 bug#54764: encode-time: make DST and TIMEZONE fields of the list argument optional ones Max Nikulin
2022-04-09  7:52 ` Paul Eggert
2022-04-10  3:57   ` Max Nikulin
2022-04-13 14:40   ` Max Nikulin [this message]
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

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=c6525aa8-1496-8ebe-cf2a-24f65cc44672@gmail.com \
    --to=manikulin@gmail.com \
    --cc=54764@debbugs.gnu.org \
    --cc=eggert@cs.ucla.edu \
    --cc=emacs-orgmode@gnu.org \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public 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).