32

Given a date and time in a format that is not recognized by date, how can I get date to recognize the date and time?

For example:

$ date -d "09SEP2012:23:58:46"
date: invalid date `09SEP2012:23:58:46'
$ date -d "09SEP2012:23:58:46" --magic-option "ddMMMYYY:hh:mm:ss"
Sun Sep  9 23:58:46 MDT 2012

Does --magic-option exist? If not, is there a more elegant way to solve this rather than using sed to transform the input into a well-formed date string?

1

3 Answers 3

13

Neither POSIX nor GNU date have --magic-option. FreeBSD calls it -f (with a syntax similar to date's output format specifiers, not the one you propose).

Your date is very close to being recognized by GNU date: all it takes is replacing the colon that separates the date from the time by a space.

date -d "$(echo "09SEP2012:23:58:46" | sed 's/:/ /')"
2
  • 2
    and with custom formats? Only way to go are regular expressions? this is horrible :-(
    – phil294
    Dec 22, 2017 at 19:39
  • 3
    You can't parse dates without knowing something about the format they're in, the classical example being 01/02/03. Dec 22, 2017 at 19:50
11

I wrote a bunch of tools (dateutils) that deal with dates and times in a more script-friendly way. Your magic option there is --input-format|-i, e.g.:

dconv -i '%d%b%Y:%H:%M:%S' "09SEP2012:23:58:46"
=>
  2012-09-09T23:58:46

While dconv does not directly support date's output format (it doesn't confer TZ or anything in the environment), there's a tool strptime in dateutils that does support the %Z format specifier.

5

If you're using an environment like Ubuntu that has busybox installed, you can do busybox date -D "$input_format" -d "$input", such as:

$ busybox date -D "%m/%d/%Y %H:%M:%S" -d "02/27/2013 23:48:00"
Wed Feb 27 23:48:00 CST 2013

If you want to format the output string to something non-standard you can specify an output format with busybox date -D "$input_format" -d "$input" +"$output_format", such as

$ busybox date -D "%m/%d/%Y" -d "02/27/2013" +"%d.%-m.%y"
27.2.13

but for ISO-8601-compliant dates, use -I with the level of precision needed, such as:

$ busybox date -D "%m/%d/%Y %H:%M:%S" -d "02/27/2013 23:48:00" -Iseconds
2013-02-27T23:48:00-0600

Notes

The busybox man page. This might not work with %Z timezone format.

1
  • Thanks for this! This was the most helpful answer here as it usually doesn't involve installing any additional tools.
    – Shadowcat
    Sep 11, 2022 at 16:24

You must log in to answer this question.

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