How to convert YYYYMMDDHHMMSS to a date readable by `date`

19,444

Solution 1

date doesn't allow "YYYYMMDDHHMMSS", but it does "YYYYMMDD HH:MM:SS", so:

D="20100101123456"
date -d "${D:0:8} ${D:8:2}:${D:10:2}:${D:12:2}"

Solution 2

If the format is totally fixed, you could just do it within bash, chopping up the string:

d=20100101123456
pretty_date="${d:0:4}-${d:4:2}-${d:6:2} ${d:8:2}:${d:10:2}:${d:12:2}"
# 2010-01-01 12:34:56
...

I wouldn't bother trying to use regex - like you said, the pattern gets ugly fast. A lot of repetition of ([0-9]{4}), even with extended or perl regex. Or you could be flexible and just match .; no verification.

Solution 3

What's with all of these regular expression answers? The date(1) tool has the ability to use strftime() style date formatting... an an example of converting one date type to another:

$ date -j -f "%Y%m%d%H%M%S" "20100101123456" "+%Y-%m-%d %H:%M:%S"
2010-01-01 12:34:56

So if it's not in the format you want, convert it like that and then use it. If you just want to set it, you can simply do:

$ date -f "%Y%m%d%H%M%S" "20100101123456"

Solution 4

Try this:

echo "20101106213245" | sed -r 's/^.{8}/& /;:a; s/([ :])(..)\B/\1\2:/;ta'

Result:

20101106 21:32:45
  • Insert a space after the eighth character
  • [label a] After a space or colon and the next two characters, add a colon
  • If a replacement was made, goto label a

You want some hyphens, too?

echo "20101106213245" | sed -r 's/^.{4}/&-/;:a; s/([-:])(..)\B/\1\2:/;ta;s/:/-/;s/:/ /'

Result:

2010-11-06 21:32:45
  • Insert a hyphen after the fourth character
  • [label a] After a hyphen or colon and the next two characters, add a colon
  • If a replacement was made, goto label a
  • Change the first colon to a hyphen (2010-11:06:21:32:45 -> 2010-11-06:21:32:45)
  • Change the next colon to a space (2010-11-06:21:32:45 -> 2010-11-06 21:32:45)

Solution 5

 sed -ne 's/\(....\)\(..\)\(..\)\(..\)\(..\)\(..\)/\1-\2-\3 \4:\5:\6/p'

I admit it'S a mouthful. All the .'s should optimally be [0-9] or \d, though I don't remember if sed supports the latter.

Share:
19,444
Sousou
Author by

Sousou

Updated on June 14, 2022

Comments

  • Sousou
    Sousou almost 2 years

    I have a set of date/time strings in the YYYYMMDDHHMMSS format that I want to convert to something readable by the date utility. Usually, I can do something like:

    date -d "2010-10-01 12:34:56"

    However, date does not like the YYYYMMDDHHMMSS:

    date -d "20100101123456"..invalid date

    So, I probably need to refine the string to be in the prior format. I'm thinking sed is the answer, but it gets ugly very fast. I'm quite certain my strings will be the proper format, so how do I easily convert them?

  • SourceSeeker
    SourceSeeker over 13 years
    That's valid for BSD, but not for GNU.
  • uzi
    uzi over 13 years
    So you're right... a rare instance where the GNU tool is inferior.
  • Sousou
    Sousou over 13 years
    The other instance of inferiority is the license terms. :)
  • Mark Stinson
    Mark Stinson over 11 years
    In shell formatting saves significant time and eliminates the overhead load of pipes and external binaries. There's lots of ${} transformations available. And do not forget use [[ ]] so tests are also ran in the same space.
  • tripleee
    tripleee about 6 years
    Generally sed does not support Perl shorthands like \d, \s, \t, etc but you can say d='[0-9]'; sed -ne "s/\\($d$d$d$d\\)\\($d$d\\)\\($d$d\\)\\($d$d\\)\\($d$d\\)\\(‌​$d$d\\)"'/\1-\2-\3 \4:\5:\6/p' (though notice how the double quotes force the backslashes to require doubling; you can't use single quotes because then the shell would not expand the value of $d).
  • Cadoiz
    Cadoiz over 2 years
    tbh I find this more readable then this one, +1
  • Cadoiz
    Cadoiz over 2 years
    Be aware that reading a date (see -d-Option) is not a part of POSIX date. But as long as you're not working on distributions like Solaris (OP has tagged it linux and not unix) you should be good. :) See my answer here for a bit more details.