Bug 257075

Summary: touch(1) does not accept input from date(1) with -I to -d
Product: Base System Reporter: Michael Osipov <michael.osipov>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: New ---    
Severity: Affects Some People CC: michael.osipov, tamelingdaniel
Priority: ---    
Version: 12.2-STABLE   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
Adds support for the output ISO 8601 output of date(1) none

Description Michael Osipov 2021-07-09 08:23:03 UTC
Running on stable/12:4e2ae05c3

I am trying to set the mtime of a file in the future to trick make.

# ahead_of_time="$(date -v +2S -Iseconds)"
# echo $ahead_of_time
2021-07-09T10:17:08+02:00
# touch -d "$ahead_of_time" .
touch: out of range or illegal time specification: YYYY-MM-DDThh:mm:SS[.frac][tz]

Although tz is documented as:
                   tz      An optional letter Z indicating the time is in UTC.
                           Otherwise, the time is assumed to be in local time.
                           Local time is affected by the value of the TZ
                           environment variable.

It is confusing in many ways:
* I cannot reuse default values produced by tools from base
* tz is not a TZ, but rather Zulu only and should rather say in the pattern:
YYYY-MM-DDThh:mm:SS[.frac][Z]

A much better approach would be if -d would parse properly extended ISO 8601 format as spit out by date -I and documented as such -- accepting any offset.
Comment 1 Michael Osipov 2023-03-28 13:23:50 UTC
Anyone willing to take a look?
Comment 2 Daniel Tameling 2023-03-29 12:14:54 UTC
I recently wanted to use touch -d with the Date string from Email headers and I would also appreciate more flexibility. In the end I used GNU touch, which is very liberal in what it accepts:

  The --date=STRING is a mostly free format human readable date string such as 
  "Sun, 29 Feb 2004 16:21:42 -0800" or "2004-02-29 16:21:42" or even "next 
  Thursday". A date string may contain items indicating calendar date, time of 
  day, time zone, day of week, relative time, relative date, and numbers. An 
  empty string indicates the beginning of the day. The date string format is more 
  complex than is easily documented here but is fully described in the info 
  documentation.

I think matching that would be an overkill, but it would be nice to have more options than currently supported.
Comment 3 Michael Osipov 2023-03-29 13:08:26 UTC
(In reply to Daniel Tameling from comment #2)

I would expect that RFC time and ISO 8601 (telescoping) would also work. That would be cover a LOT of cases.
Comment 4 Daniel Tameling 2023-04-02 13:53:58 UTC
Created attachment 241265 [details]
Adds support for the output ISO 8601 output of date(1)

I tried to come up with a patch. I looked at the source code of date and it manually adds the colon. So I had to remove it manually. I now supports the timezone with and without a colon.

$ ./touch -d 2021-07-09T10:17:08+02:00 test1
$ ./touch -d 2021-07-09T10:17:08+0200  test2
$ gtouch -d 2021-07-09T10:17:08+02:00  test3
$ stat -f '%Sm %N' test*                                                                                                                                                  
Jul  9 10:17:08 2021 test1
Jul  9 10:17:08 2021 test2
Jul  9 10:17:08 2021 test3
Comment 5 Michael Osipov 2023-04-02 16:50:27 UTC
(In reply to Daniel Tameling from comment #4)

This input is invalid:
> ./touch -d 2021-07-09T10:17:08+0200  test2

I would not support it. ISO 8601 provides you two ways: basic and extended formats. You must pick one and stick with one. You are *not* allowed to match.

Four years ago I have written to cem@ about the incorrect implementation of 'date -I': https://github.com/freebsd/freebsd/commit/627fbf85f712cc71087e9476036f230b59b31783#diff-a58c8d455292fcb202f71a7682d0ea08R267 well, he did reject my request.
Comment 6 Michael Osipov 2023-04-02 16:57:20 UTC
(In reply to Daniel Tameling from comment #4)

I will test your patch next week. Logically, it looks fine to me.
Comment 7 Michael Osipov 2023-04-12 12:29:21 UTC
(In reply to Michael Osipov from comment #5)

I can confirm that your patch works for me.