Search code examples
timeformatgnuplot

gnuplot: how to convert 12h time format into 24h time format?


How can I convert the annoying 12h time format (with AM and PM) into the 24h time format?

I wanted to avoid external programs like awk as in this example.

Since gnuplot has a time-specifier %p for "am" and "pm" (check help time_specifiers), I thought it would be easy. But the following code does not give the correct result, but a warning message:

warning: Bad time format in string

Maybe, I'm using %p incorrectly?

Code:

### change 12h time format to 24h format (does not give correct results)
reset session

$Data12 <<EOD
12/31/19  8:12:01 AM
12/31/19  8:12:02 PM
12/31/19 12:00:03 am
12/31/19 12:00:04 pm
EOD

myTimeFmt12 = "%m/%d/%y %H:%M:%S %p"
myTimeFmt24 = "%d.%m.%Y %H:%M:%S"

set table $Data24
    plot $Data12 u (strftime(myTimeFmt24,timecolumn(1,myTimeFmt12))) w table
unset table
print $Data24
### end of code

Result:

         "tbTime12to24.plt" line 15: warning: Bad time format in string
         "tbTime12to24.plt" line 15: warning: Bad time format in string
         "tbTime12to24.plt" line 15: warning: Bad time format in string
         "tbTime12to24.plt" line 15: warning: Bad time format in string
 31.12.2019 08:12:01    
 31.12.2019 08:12:02    
 31.12.2019 12:00:03    
 31.12.2019 12:00:04

Solution

  • That's a somewhat "lengthy" solution I have come up with by defining my own formula, although I was hoping for a short "gnuplot-integrated" solution.

    Code: (edit: simplified workaround for gnuplot >=5.2.0, covers a.m. and p.m. as well)

    ### change 12h time format to 24h format
    reset session
    
    $Data12 <<EOD
    12/31/19  8:12:01 AM
    12/31/19  8:12:02 a.m.
    12/31/19  8:12:03 PM
    12/31/19  8:12:04 p.m.
    12/31/19 12:00:05 am
    12/31/19 12:00:06 a.m.
    12/31/19 12:00:07 pm
    12/31/19 12:00:08 p.m.
    EOD
    
    myTimeFmt12 = "%m/%d/%y %H:%M:%S"
    myTimeFmt24 = "%d.%m.%Y %H:%M:%S"
    
    # change 12h am/pm format to 24h format
    myTime12to24(colT,colM) = (_t = timecolumn(colT,myTimeFmt12), _p=strcol(colM), \
                              strftime(myTimeFmt24, _t + 12*3600*( \
                              ((_p eq "PM" || _p eq "pm" || _p eq "p.m.") ? 1 : 0) + (floor(_t/3600)%12==0 ? -1 : 0))))
    
    set table $Data24
        plot $Data12 u (myTime12to24(1,3)) w table
    unset table
    print $Data24
    ### end of code
    

    Result:

    31.12.2019 08:12:01
    31.12.2019 08:12:02
    31.12.2019 20:12:03
    31.12.2019 20:12:04
    31.12.2019 00:00:05
    31.12.2019 00:00:06
    31.12.2019 12:00:07
    31.12.2019 12:00:08
    

    Code: (since gnuplot >=5.4.0, %p is also implemented as input format, but it is not intended to cover a.m. and p.m.. I agree that not all variations of this unfortunate time format can be taken into account.)

    ### change 12h time format to 24h format
    reset session
    
    $Data12 <<EOD
    12/31/19  8:12:01 AM
    12/31/19  8:12:02 a.m.
    12/31/19  8:12:03 PM
    12/31/19  8:12:04 p.m.
    12/31/19 12:00:05 am
    12/31/19 12:00:06 a.m.
    12/31/19 12:00:07 pm
    12/31/19 12:00:08 p.m.
    EOD
    
    myTimeFmt12 = "%m/%d/%y %H:%M:%S %p"
    myTimeFmt24 = "%d.%m.%Y %H:%M:%S"
    
    set table $Data24
        plot $Data12 u (strftime(myTimeFmt24,timecolumn(1,myTimeFmt12))) w table
    unset table
    print $Data24
    ### end of code
    

    Result:

    31.12.2019 08:12:01
    31.12.2019 08:12:02
    31.12.2019 20:12:03
    31.12.2019 08:12:04    # not correct
    31.12.2019 00:00:05
    31.12.2019 12:00:06    # not correct
    31.12.2019 12:00:07
    31.12.2019 12:00:08