On Mon, Oct 30, 2017 at 5:40 PM, Allen Li <vianchielfa...@gmail.com> wrote: > (current-time-string (time-to-seconds (org-2ft "<2017-10-31>"))) > "Sun Oct 29 17:00:00 2017" > > This seems wrong > > In org-2ft > > (org-parse-time-string s nil t) > > The t means use UTC instead of Emacs local time. > > However, Org translates <now> into (float-time), which is in Emacs localtime. > > 1. SCHEDULED>"<now>" compares a UTC time against a local time. > 2. Either org-2ft should be fixed to be localtime, or <now> should be > (float-time) in UTC. > > I don't know how Org internals works, but my experience so far has > been that Emacs and *nix in general is very naive about timezones; a > naked timestamp is assumed to be localtime if it does not have > accompanying timezone information. > > Thus, it seems to be more correct to change org-2ft to parse times as > localtime. However, I don't know if UTC timestamps are assumed by > other parts of Org internals, in which case fixing <now> (float-time) > would be safest.
My initial analysis was wrong because I wasn't thinking clearly. Just to set a stake in the ground: timestamps are seconds since epoch and timezone neutral. Emacs time values are also timezone neutral: (sec-high sec-low microsec picosec) (current-time-string (float-time)) "Mon Oct 30 21:21:31 2017" ; right (current-time-string (org-time-today)) "Mon Oct 30 00:00:00 2017" ; right (current-time-string (org-2ft "<2017-10-31>")) "Mon Oct 30 17:00:00 2017" ; wrong Removing the t for zone fixes it (defun org-2ft (s) "Convert S to a floating point time. If S is already a number, just return it. If it is a string, parse it as a time string and apply `float-time' to it. If S is nil, just return 0." (cond ((numberp s) s) ((stringp s) (condition-case nil (float-time (apply #'encode-time (org-parse-time-string s))) (error 0.))) (t 0.))) (current-time-string (org-2ft "<2017-10-31>")) "Tue Oct 31 00:00:00 2017" ; now right I will also note that the FIXME comment in org-parse-time-string suggests that it too is not handling timezones correctly. In fact, perhaps org-parse-time-string should not take a zone argument, since Org does not support timezones thus the only valid value for zone is nil. I suspect that org-display-custom-time, another caller that passes t for zone, is also timezone incorrect. That is to say, nothing in Org allows passing in a custom timezone, let alone a UTC timezone; thus, every caller that passes a non-nil zone to org-parse-time-string is getting an incorrect result. tl;dr time is hard.