In a shell script, there are the following variables:
datestamp=$(date '+%Y-%m-%d_T%H-%M-%S')
datestamp_pretty=$(date '+%m/%d/%Y at %I:%M:%S %p')

The first one is used as part of the output filename while the second one is used to display a nicely readable date and time in the contents of the file. Since these are created separately, the seconds can be off slightly. Is there a way to create a single date variable and then format it two different ways? If so, how is this done?

  • That's not a duplicate. Here, a better approach would be something like eval "$(date +"datestamp='%Y-%m-%d_T%H-%M-%S' datestamp_pretty='%m/%d/%Y at %I:%M:%S %p'")" and avoid relying on that -d GNU extension. Dec 10, 2019 at 9:37
  • Note that that datestamp_pretty format of yours is US-specific and would generally not work properly outside a US or C/POSIX locale. Using %c is probably better for a human-readable date adapted to the user's locale. Dec 10, 2019 at 9:43
  • @StéphaneChazelas How would %c be used in datestamp_pretty to replace the code that's there but yield the same output?
    – knot22
    Dec 11, 2019 at 2:42

2 Answers 2


This is pretty easy if you are using GNU date.

First, get the most generic time format from date. I chose to get the epoch time:

epoch=$(date +%s)

Then, convert the epoch into whatever format you want however many times you want:

datestamp=$(date -d @$epoch '+%Y-%m-%d_T%H-%M-%S')
datestamp_pretty=$(date -d @$epoch '+%m/%d/%Y at %I:%M:%S %p')

It should always represent the time when you first captured $epoch.

If you do not have GNU date, you would need some other method of converting the epoch to a human date.

  • In @$epoch, what does the @ do?
    – knot22
    Dec 3, 2019 at 23:06
  • According to this coreutils example page, it is shorthand to represent date -d "1970-01-01 UTC $epoch seconds" Dec 3, 2019 at 23:48
  • 1
    The "@" should make you read man date.
    – waltinator
    Dec 4, 2019 at 13:43

Here’s a way to do it that doesn't require GNU date and doesn't require you to run date more than once.

Pick a string that will never appear in any of the date/time strings.  It can be a single character — for example, ~, ^ and | would all work.  But I’ll demonstrate with /foo/.

Simply concatenate your date string formats with your chosen string between them.  (Remove the + from the second format.)  Capture the output from date into a variable, and then split it at your delimiter string:

combined=$(date '+%Y-%m-%d_T%H-%M-%S/foo/%m/%d/%Y at %I:%M:%S %p')

You must log in to answer this question.

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