5
\$\begingroup\$

A simple reworking of the Bash date command to my own personal liking. Possibly a rather trivial task; I just wanted the date and time to be in the form of:

Fri Sep 2 2016
11:37 P.M.

I think this accomplishes that:

#!/bin/bash

today() {
    now="$(date | awk '{ OFS=" "; print $1,$2,$3,$6 }')"
    h="$(date "+%H")"
    m="$(date "+%M")"
    if [ $h -gt 12 ]; then 
        echo -e "$now\n$(( $h - 12 )):$m P.M."
    elif [ $h = 12 ]; then
        echo -e "$now\n$h:$m P.M."
    elif [ $h = 00 ]; then
        h=12; echo -e "$now\n$h:$m A.M."
    elif [ $h -le 11 ]; then
        if [ $h -lt 10 ]; then
            h="$(echo $h | cut -c2)"
        fi
        echo -e "$now\n$h:$m A.M."
    fi
}

today

Is there anything I could do to improve this?

\$\endgroup\$
5
\$\begingroup\$

Parsing formatted output — as you have done with $(date | awk '{ OFS=" "; print $1,$2,$3,$6 }') — is a dangerous game: it's hard to say exactly what awk should expect as input. For example, on GNU/Linux, I get:

$ LC_TIME=en_CA.UTF-8 date
Fri Sep  2 23:54:56 PDT 2016
$ LC_TIME=C date
Fri Sep  2 23:54:56 PDT 2016

However, on macOS, I get:

$ LC_TIME=en_CA.UTF-8 date
Fri  2 Sep 2016 23:54:56 PDT
$ LC_TIME=C date
Fri Sep  2 23:54:56 PDT 2016

Note the difference in the output in the en_CA.UTF-8 locale. More "exotic" locales could produce even wilder output. I don't recommend parsing the output of date, but if you do, be sure to explicitly state the locale using LC_TIME=C date.

What would be a better approach, then? The date command's format specifiers are meant for just this kind of thing, and you can get quite close to your desired output. On GNU/Linux:

$ date +'%a %b %e %Y%n%I:%M %p'
Fri Sep  2 2016
23:54 PM

On macOS:

$ date +'%a %b %e %Y%n%I:%M %p'
Fri Sep  2 2016
23:54 pm

Although the format specifiers are only loosely standardized, I would still consider this to be a more idiomatic and reliable solution than yours. If you insist on getting exactly the format that you specified in your example, then a bit of post-processing might be needed.

$ date +'%a %b %e %Y%n%I:%M %p' | sed -e 's/  //' -e 's/[Aa][Mm]$/A.M./' -e 's/[Pp][Mm]$/P.M./'
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.