6

man date won't show me any reserved words but they have 'now' or 'today' etc.

I wonder if there is any clear way to print start(00:00:00) of the day.

Will date -u -d "$(date +'%F')" suffice in any situation? Looks a little dumb.

1 Answer 1

10

date -d 00:00 or date -d 00:00:00 work with the GNU, ast-open, toybox and busybox implementations of date.

date -d 0 also works with GNU date.

$ date -d 00:00
Tue  4 Oct 00:00:00 BST 2022

With BSD date:

$ date -jf %H%M%S 000000
Mon Oct  4 00:00:00 BST 2022

None of -j, -f, -d are standard option to date.

POSIX date has no provision for specifying an input date other than now except for setting the system clock (under the XSI option).

You could do:

$ date '+%a %e 00:00:00 %Z %Y'
Tue  4 00:00:00 BST 2022

But the BST part can end up being wrong if you run that on the day the clock changes from/to winter time.

ksh93 and zsh have builtin support for parsing input dates:

  • ksh93

    $ printf '%(%c [%s epoch time])T\n' 00:00
    Tue Oct  4 00:00:00 2022 [1664838000 epoch time]
    

    (bash copied the %(format)T from ksh93 but not the ability to specify input dates other than in epoch seconds).

    ksh93 can also be built with the ast-open date builtin.

  • zsh

    $ zmodload zsh/datetime
    $ strftime -s today %F
    $ strftime -rs start %F $today
    $ strftime '%c [%s epoch time]' $start
    Tue 04 Oct 2022 00:00:00 BST [1664838000 epoch time]
    

    Or getting today's date using prompt expansion (here via the % parameter expansion flag):

    $ zmodload zsh/datetime
    $ strftime -rs start %F ${(%):-%D{%F}}
    $ strftime '%c [%s epoch time]' $start
    Tue 04 Oct 2022 00:00:00 BST [1664838000 epoch time]
    

Note that your:

date -u -d "$(date +'%F')"

Takes today's date in your timezone in YYYY-MM-DD format, but then asks date to give you the time for 00:00:00 UTC on that day, which unless you're in a timezone that currently happens to align with UTC will not be the start of your day.

Here in mainland Britain which is still in summer time (one hour ahead of UTC):

$ date -u -d "$(date +'%F')" +%s
1664841600
$ date -d 00:00 +%s
1664838000
6
  • 1
    the GNU date also accepts things such as "today" ("yesterday" & "tomorrow" work too) as an input string and thus you could be more explicit by using an expression such as:- date -d "today 00:00:00" +"%F %T %Z"; this would have a more explicit intention for later maintainers (including yourself, days or years later).
    – MNB
    Commented Oct 5, 2022 at 8:40
  • 1
    @MNB, yes though, it's a lot less portable. Also beware of TZ=Europe/London faketime 2022-10-30T00:01 date -d tomorrow +%F returning 2022-10-30 with current versions of GNU date. Commented Oct 5, 2022 at 9:12
  • agreed on the lower portability. Also that is an interesting bug, is that due to the BST to GMT transition in the early hours of the 30th October?
    – MNB
    Commented Oct 5, 2022 at 9:33
  • 1
    @MNB, yes, see info date 'Relative items in date strings'. tomorrow is the same as 1 day or day and a day is 24 hours of 3600 seconds, not a calendar day. Commented Oct 5, 2022 at 9:41
  • 2
    Having said that TZ=Europe/London faketime 2022-10-30T00:01 date -d 'tomorrow 00:00:00' +%FT%T%z returns 2022-10-31T00:00:00+0000. Commented Oct 5, 2022 at 9:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .