The Intellectual Wilderness On Government: "There is nothing more useless than doing efficiently that which should not be done at all."

2013.04.20 13:46

Most common Bash date commands for timestamping

Filed under: Computing — Tags: , , , , — zxq9 @ 13:46

From time to time I get asked how to use the date command to generate a timestamp. Here is an idiot-friendly script you can post for reference in your team’s bin/ if you get interrupted about timestamp questions or have an aversion to typing phrases like “man date” (with or without a space).

All but the first one and last three produce filename-friendly strings.

A big thanks to the following folks for pointing out mistakes and suggesting useful format inclusions:

  • 2013-05: Rich for the reminder to include UTC and timezoned stamps.
  • 2017-10: “Hamilton and Meg” (haha!) for pointing out I had my 4 year example formats messed up and for prodding me to include a 2-year example.
  • 2018-01: Autumn Gray for suggesting that I add examples of including short and long days of the week.
#! /bin/bash

# An overly obvious reference for most commonly requested bash timestamps
# Now all you Mac fags can stop pestering me.

cat << EOD
        Format/result           |       Command              |          Output
--------------------------------+----------------------------+------------------------------
YYYY-MM-DD_hh:mm:ss             | date +%F_%T                | $(date +%F_%T)
YYYYMMDD_hhmmss                 | date +%Y%m%d_%H%M%S        | $(date +%Y%m%d_%H%M%S)
YYYYMMDD_hhmmss (UTC version)   | date --utc +%Y%m%d_%H%M%SZ | $(date --utc +%Y%m%d_%H%M%SZ)
YYYYMMDD_hhmmss (with local TZ) | date +%Y%m%d_%H%M%S%Z      | $(date +%Y%m%d_%H%M%S%Z)
YYYYMMSShhmmss                  | date +%Y%m%d%H%M%S         | $(date +%Y%m%d%H%M%S)
YYYYMMSShhmmssnnnnnnnnn         | date +%Y%m%d%H%M%S%N       | $(date +%Y%m%d%H%M%S%N)
YYMMDD_hhmmss                   | date +%y%m%d_%H%M%S        | $(date +%y%m%d_%H%M%S)
Seconds since UNIX epoch:       | date +%s                   | $(date +%s)
Nanoseconds only:               | date +%N                   | $(date +%N)
Nanoseconds since UNIX epoch:   | date +%s%N                 | $(date +%s%N)
ISO8601 UTC timestamp           | date --utc +%FT%TZ         | $(date --utc +%FT%TZ)
ISO8601 UTC timestamp + ms      | date --utc +%FT%T.%3NZ     | $(date --utc +%FT%T.%3NZ)
ISO8601 Local TZ timestamp      | date +%FT%T%Z              | $(date +%FT%T%Z)
YYYY-MM-DD (Short day)          | date +%F\(%a\)             | $(date +%F\(%a\))
YYYY-MM-DD (Long day)           | date +%F\(%A\)             | $(date +%F\(%A\))
EOD

If executed, it will produce the (obvious) output:

        Format/result           |       Command              |          Output
--------------------------------+----------------------------+------------------------------
YYYY-MM-DD_hh:mm:ss             | date +%F_%T                | 2018-01-24_13:06:51
YYYYMMDD_hhmmss                 | date +%Y%m%d_%H%M%S        | 20180124_130651
YYYYMMDD_hhmmss (UTC version)   | date --utc +%Y%m%d_%H%M%SZ | 20180124_040651Z
YYYYMMDD_hhmmss (with local TZ) | date +%Y%m%d_%H%M%S%Z      | 20180124_130651JST
YYYYMMSShhmmss                  | date +%Y%m%d%H%M%S         | 20180124130651
YYYYMMSShhmmssnnnnnnnnn         | date +%Y%m%d%H%M%S%N       | 20180124130651170243401
YYMMDD_hhmmss                   | date +%y%m%d_%H%M%S        | 180124_130651
Seconds since UNIX epoch:       | date +%s                   | 1516766811
Nanoseconds only:               | date +%N                   | 174236092
Nanoseconds since UNIX epoch:   | date +%s%N                 | 1516766811175655627
ISO8601 UTC timestamp           | date --utc +%FT%TZ         | 2018-01-24T04:06:51Z
ISO8601 UTC timestamp + ms      | date --utc +%FT%T.%3NZ     | 2018-01-24T04:06:51.178Z
ISO8601 Local TZ timestamp      | date +%FT%T%Z              | 2018-01-24T13:06:51JST
YYYY-MM-DD (Short day)          | date +%F\(%a\)             | 2018-01-24(æ°´)
YYYY-MM-DD (Long day)           | date +%F\(%A\)             | 2018-01-24(水曜日)

Note that the last two, short and long day-of-week are dependent on the environment variable LANG. After setting LANG=en_US we wind up with the following:

YYYY-MM-DD (Short day)          | date +%F\(%a\)             | 2018-01-24(Wed)
YYYY-MM-DD (Long day)           | date +%F\(%A\)             | 2018-01-24(Wednesday)

23 Comments »

  1. “man date”… haaaaaaa…

    Comment by avraml — 2013.04.22 11:14 @ 11:14

  2. You nearly made me choke with those non-UTC timestamps! You want to add date --utc +%FT%TZ and date +%FT%T%Z? The “T” makes it a little harder to read at first, but it’s correct per ISO 8601.

    Comment by Rich — 2013.05.17 10:00 @ 10:00

  3. @Rich
    Not a bad point. I didn’t include anything with timezones. I didn’t articulate this clearly, but the primary motivation for the post/script was being pestered with questions about how to produce filename-friendly timestamps in scripts — hence the lack of characters that are tricky on some operating systems (colons, in particular).

    Anyway, its easy to forget about timezones living in a country where there is only one! I’ve updated the post with your examples, because they are indeed useful.

    Thanks for the input!

    Comment by zxq9 — 2013.05.17 10:16 @ 10:16

  4. Wow, for about 2-3 minutes I thought you were smart until I reached the following in your text:
    “# Now all you Mac fags can stop pestering me.”

    Now I just think you’re a complete loser.

    Comment by Mac Fag — 2014.05.6 08:51 @ 08:51

  5. @Mac Fag
    At the time I wrote this I was surrounded by the Mac Fag Clone Army (figuratively, at least). That comment was for them, but if you feel you belong in the same category you’re welcome to apply the label to yourself.

    Comment by zxq9 — 2014.05.6 12:10 @ 12:10

  6. “Mac Fag” might be a touch juvenile, but it clearly hit close to home for someone… i can’t imagine any other reason you left it in the comments than to troll.

    +1 for the Best in Show reference! Excellent demonstration why its stupid to try flaming someone on their own blog.

    Btw, writing this on my iPhone, which is actually quite annoying.

    Comment by Marzipan — 2014.05.6 16:50 @ 16:50

  7. When I posted this I never imagined that a single commented line would become such a topic for discussion.

    Comment by zxq9 — 2014.05.6 16:58 @ 16:58

  8. Brilliant. Both the post and the retort.

    Comment by apocalysque — 2015.12.18 13:06 @ 13:06

  9. I would like to get this:
    ISO8601 UTC timestamp | date –utc +%FT%TZ | 2013-05-17T01:16:09Z

    But with milliseconds also. I.E.
    2013-05-17T01:16:09.123Z

    Comment by Brian M — 2016.08.24 07:05 @ 07:05

  10. For three digits of the nanosecond output you can insert a length field before the “N”:
    date --utc +%FT%T.%3NZ
    I’ll add that to the list.

    Thanks!

    Comment by zxq9 — 2016.10.14 09:16 @ 09:16

  11. “When I posted this I never imagined that a single commented line would become such a topic for discussion.”

    That’s what happens when you use hate speech.

    Comment by Conor — 2017.05.28 03:09 @ 03:09

  12. “hate speech”

    At first I was like
    (ಠ_ಠ)

    Then I was like
    \(´▽`)/

    Comment by zxq9 — 2017.05.28 21:04 @ 21:04

  13. As I type this on my MacBook Air sipping a Caffè Mocha from Starbucks I appreciate the beautiful table of formats and outputs. Viewing in a log file the output reminds me of the regularity of receiving my J Crew catalogs. :-)

    Currently your excellent table is one of the top Google results for “bash create timestamp”. Would you adjust the first column to be consistent with the output for number of years, and add 2-year formats?
    YYYYMMDD_hhmmss | date +%Y%m%d_%H%M%S | $(date +%Y%m%d_%H%M%S)
    YYMMDD_hhmmss | date +%y%m%d_%H%M%S | $(date +%y%m%d_%H%M%S)

    Comment by Hamilton and Meg — 2017.10.16 18:00 @ 18:00

  14. How delightful to find a Starbucks-going MacBook user with a sense of humor!

    Good idea. I’ll make that change directly.

    Thank you for taking the time to make the suggestion. Whatever else you’re doing, I hope you’re having fun coding! o/

    Comment by zxq9 — 2017.10.16 21:31 @ 21:31

  15. Thanks! Needed this for an EDI application…
    Had to get to at least %4N to guarantee a unique value on our platforms.
    Used this for testing:

    #!/bin/bash
    
    cnt=1
    while [ $cnt -lt 25 ]
    do
      echo $(date +%Y%m%d%H%M%S_%3N) #milliseconds
      echo $(date +%Y%m%d%H%M%S_%6N) #microseconds
      echo $(date +%Y%m%d%H%M%S_%N) #nanoseconds
      cnt=$((cnt+1))
    done

    Comment by Larry — 2017.10.27 03:52 @ 03:52

  16. Might be useful to add `%a` and `%A`.

    Comment by Autumn Grey — 2018.01.6 07:52 @ 07:52

  17. Added. Thank you for the suggestion!

    Comment by zxq9 — 2018.01.24 13:19 @ 13:19

  18. `–utc` is not in standard date, it is part of GNU date (or gdate on many systems)

    `TZ=UTC date +%FT%T%Z`

    will work in any bash-like shell, it will not work in a shell like csh tcsh or fish.

    Comment by Lewis — 2018.09.18 23:30 @ 23:30

  19. Interesting! I’ll add a note and some examples about this.

    Thank you for pointing that out.

    Comment by zxq9 — 2018.09.19 07:29 @ 07:29

  20. Google brought me here while seeking a quick example of different date/timestamps with bash… googled this plenty before, first time finding this result… totally caught off guard by the mac-fag comment in the example you chose to include.

    You either put that in there or decided to leave it when you copy-pasted something you did not create. That has nothing to do with the topic at hand. Unnecessary hate.

    Comment by t — 2019.04.30 16:00 @ 16:00

  21. Hope it was helpful for you.

    And I wrote the above code and the comment — it was a jab back at some of the folks I was working with at the time, “Mac fag” being a bit of an in-joke at the time.

    I have left it up here on the site specifically because I find it amusing that some tiny fraction of people find it (and anything else) “hateful” and leave drive-by comments such as yours.

    Comment by zxq9 — 2019.05.1 16:39 @ 16:39

  22. No hate … I just think you’re kind of a dick. Because of you’re small bit of bash-ery you offered up here, you think people should have to put up with you’re assbaggery – which makes you also a bit of a douche. Cheers.

    Comment by animalmutha — 2019.06.1 02:22 @ 02:22

  23. …says this assbag on someone else’s website where a resource was provided out of pure generosity…

    Haha! I’ve missed this aspect of the intertubes!

    Comment by zxq9 — 2019.06.1 06:21 @ 06:21

RSS feed for comments on this post.

Leave a comment

Powered by WordPress