Most common Bash date commands for timestamping

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.
  • 2020-09: rade noticed that I had a “Zulu” notation for UTC listed as ISO8601, which it is not, and provided a correction. I’ve specified the Z-notation UTC timestamp separately from the (now corrected) ISO8601 timestamp. Thanks, rade!
#! /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)
Z-notation UTC timestamp        | date --utc +%FT%TZ         | $(date --utc +%FT%TZ)
Z-notation UTC timestamp + ms   | date --utc +%FT%T.%3NZ     | $(date --utc +%FT%T.%3NZ)
ISO8601 UTC timestamp           | date --utc +%FT%T%Z        | $(date --utc +%FT%T%Z)
ISO8601 UTC timestamp + ms      | date --utc +%FT%T.%3N%Z    | $(date --utc +%FT%T.%3N%Z)
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                | 2020-09-09_11:17:10
YYYYMMDD_hhmmss                 | date +%Y%m%d_%H%M%S        | 20200909_111710
YYYYMMDD_hhmmss (UTC version)   | date --utc +%Y%m%d_%H%M%SZ | 20200909_021710Z
YYYYMMDD_hhmmss (with local TZ) | date +%Y%m%d_%H%M%S%Z      | 20200909_111710JST
YYYYMMSShhmmss                  | date +%Y%m%d%H%M%S         | 20200909111710
YYYYMMSShhmmssnnnnnnnnn         | date +%Y%m%d%H%M%S%N       | 20200909111710866549239
YYMMDD_hhmmss                   | date +%y%m%d_%H%M%S        | 200909_111710
Seconds since UNIX epoch:       | date +%s                   | 1599617830
Nanoseconds only:               | date +%N                   | 873291281
Nanoseconds since UNIX epoch:   | date +%s%N                 | 1599617830874893393
Z-notation UTC timestamp        | date --utc +%FT%TZ         | 2020-09-09T02:17:10Z
Z-notation UTC timestamp + ms   | date --utc +%FT%T.%3NZ     | 2020-09-09T02:17:10.878Z
ISO8601 UTC timestamp           | date --utc +%FT%T%Z        | 2020-09-09T02:17:10UTC
ISO8601 UTC timestamp + ms      | date --utc +%FT%T.%3N%Z    | 2020-09-09T02:17:10.881UTC
ISO8601 Local TZ timestamp      | date +%FT%T%Z              | 2020-09-09T11:17:10JST
YYYY-MM-DD (Short day)          | date +%F\(%a\)             | 2020-09-09(水)
YYYY-MM-DD (Long day)           | date +%F\(%A\)             | 2020-09-09(水曜日)

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\)             | 2020-09-09(Wed)
YYYY-MM-DD (Long day)           | date +%F\(%A\)             | 2020-09-09(Wednesday)

37 thoughts on “Most common Bash date commands for timestamping

  1. 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.

  2. @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!

  3. 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.

  4. @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.

  5. “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.

  6. 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

    1. 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!

  7. “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.

  8. As I type this on my MacBook Air sipping a Café 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)

    1. 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/

  9. 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

  10. `–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.

  11. 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.

    1. 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.

  12. 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.

    1. …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!

  13. Hey, there’s a slur in your post you and should probably remove it. Congrats on your SEO ranking and all I guess, but that doesn’t excuse using slurs to marginalize/dehumanize a group of people you don’t like. Perhaps you should try listening instead of getting so offended and hurt when someone corrects you. I know it can be difficult It comes off like you’re too insecure and weak to admit you were wrong. We’re all wrong sometimes, it’s okay.

    1. This becoming a top result was a total surprise to me — I’ve never made any attempt at SEO.
      I’m pretty sure this is the only page that’s got any rank, though. Almost all of my traffic is from people who know me in some way or people browsing documentation for obscure projects I’ve written.

      As for the “slur”… Picking on a certain stereotype associated with Mac users is funny to me, and harsh or “problematic” language is something I’ve found useful in just the last few years as a social filter. People who will immediately take the attack angle “you’re too insecure and weak to admit you were wrong” are exactly the sort I prefer not to deal with.

  14. Wow. One poster called you 3 pejoratives in a single comment: dick, assbag and douche. Don’t people have manners anymore? I don’t understand the rationale behind responding to a generalized jovial jab at a group (intended to harm no specific person) with a vitriolic attack on an individual.

    Funny thing, I never even noticed the Mac fag reference. It was a #comment, and because I came here on a date formatting mission, my eyes went right to the tables of date commands. I never even noticed the Mac reference until I read Comment 5. Then I had to scroll up to find it. Suffice it to say that I’m grateful for the free information you’ve published here, and since I’m not a self-appointed patrolman for the PC Police, I didn’t take offense.

    1. @bob I believe we can generally choose how to feel about almost anything that does not directly and repeatedly impact one’s own life, and the decision to feel rage and take vicarious offense on behalf of imagined people is a prime example of how this ability to choose can manifest negatively.

      Thanks for keeping things light. Let’s keep choosing to feel inspired and eager to create new things! Woohoo!

      Whatever you’re making, I sure hope you’re having a good time doing it. \o/

  15. missing ‘%’ before symbol ‘Z’

    Type error in line 12 of the date table:
    wrong: date –utc +%FT%TZ $(date –utc +%FT%TZ)
    right: date –utc +%FT%T%Z $(date –utc +%FT%T%Z)

    Type error in line 13 of the date table:
    wrong: date –utc +%FT%T.%3NZ $(date –utc +%FT%T.%3NZ)
    right: date –utc +%FT%T.%3N%Z $(date –utc +%FT%T.%3N%Z)

    1. Oops! Thank you for noticing! I had intended that to be the “Zulu” notation for UTC, and you’re right — Z-notation (nautical/aviation/NATO) is not the same as ISO8601. I’ve added your correction as well as separate Z-notation lines.

    1. Hi, Vladimir! Can we add or subtract a certain interval of time? That is an interesting question. Let’s see…

      There is a switch `–date=STRING` that instructs the command to render a formatted date set to the value provided by STRING, and we know that we can have the date command give us the epoch in seconds, and we should be able to perform arithmetic on those seconds in an inner command. So… YES! I think I can do this.
      Two weeks in seconds should be 60 seconds * 60 minutes * 24 hours * 14 days.

      In the four command examples below I:
      1. Get the date in seconds.
      2. Insert this as an inner command to date itself via –date.
      3. Perform the subtraction of 14 days.
      4. Add a format at the end of that subtraction to have it produce whatever format I want.

      ceverett@okonomiyaki:~$ date +%s
      1617164020
      ceverett@okonomiyaki:~$ date --date=@$(date +%s)
      2021年  3月 31日 水曜日 13:13:42 JST
      ceverett@okonomiyaki:~$ date --date=@$(($(date +%s) - (60 * 60 * 24 * 14)))
      2021年  3月 17日 水曜日 13:13:46 JST
      ceverett@okonomiyaki:~$ date --date=@$(($(date +%s) - (60 * 60 * 24 * 14))) +%FT%T%Z
      2021-03-17T13:14:02JST

      And it worked! Yay! From here a script command could easily be written that makes the number of days an arbitrary argument. If you stumble on a simpler way to do this please let me know!

  16. Wonderful post and responses.
    Thank you all for contributing to the informed (for the most part) and humorous comments, quite useful (Thank you zxq9!)
    Just what I needed for a quick little script to insert an iso8601 timestamp in some text files.
    Really found the mac fag comments a little strange and somewhat humorous that some people only seem to look for, focus on, and become consumed with perceived hate in a forum like this.
    surprising and strange. …. maybe I should get out more to learn more about such strange people, …

    nah I’m good.
    TY again, great snippet!

  17. This result *was* a big win for the amount of time it *would have* saved me and the effort it saved compared to having to think for myself with “man date”. That is, it save me time until I got to the train wreck of this comments thread. Now I have lost all productivity gained because I could not stop reading these comments. Funny, I was not offended by the hot-topic comment because my brain automatically p.c.-ed it up for you. I just thought it said, “Now all you Mac fans can stop pestering me.”, which I read as a cleaver but classy dig on the brainlessness of mac users. I do discourage the use of the word fag for reasons, but I also find this humorously cringey imagining some useful hero in an uptight corporate workplace following your advice to “post for reference in your team’s bin/” without noticing that’s there.

    1. Everything about this response brought a smile. Thank you.

      I suppose at this point (the original script being a pre-2016 specimen, after all) the original bit is a social fossil of sorts, but just so great that a bygone phrase in language can trigger so many unwilling to understand. Our Hearts Were Young and Gay level misunderstanding.

      Anyway, great to know the script has reached another user! I sincerely hope that you and your family and friends are having a great time in 2021 despite the going madness. o/

  18. March 21, 2022, 17:29:58 (UTC-04:00) could someone help me , can we output date time like this ? EST as well as UTC in the brackets.

    Currently, I am using date –utc +%FT%T%Z

    Thanks in advance

    1. Oh, hi! Yes. This can be done. Took me a few tries to get it sorted out, but it turns out it is even possible to include the +/- offset from UTC using `date`:

      ceverett@okonomiyaki:~$ env LANG=en_US date --utc +"%B %d, %Y, %H:%M:%S (UTC%z)"
      March 26, 2022, 03:58:17 (UTC+0000)
      ceverett@okonomiyaki:~$ env LANG=en_US date +"%B %d, %Y, %H:%M:%S (UTC%z)"
      March 26, 2022, 12:58:29 (UTC+0900)
      

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.