Search code examples
perldateawksolaris

Hours and Minutes addition


I work in a solaris server and the date -d option is not there. No gdate as well. I know fair amount of questions have been asked related to this, I have gone through almost all of them. But I don't know perl so I don't know how to modify those answers w.r.t my requirement.

Here's what I have which works in Linux:

date -d "$hr:$mi $duration minutes" +'%H%M'

where $hr and $mi are hours and mins, $duration is in minutes.

When I run like this in Linux, I get this:

date -d "23:28 60 minutes" +'%H%M'
0028

How can I get a perl equivalent (possibly a one liner?) that will work in Solaris?

EDIT: Adding awk tag to see if there's a solution there since my perl is ancient. Thanks for trying to help, folks.

EDIT (2): I'm having the same problem as here, only I don't have the luxury of using date -d. I'm open to any solution in python or perl, need not be an one liner.

PS: Checked This, no tclsh. Checked This as well, don't have a clue what's going there!


Solution

  • Solaris is a little behind the times in a number of ways. Its date command is missing a bunch of stuff, like the ability to process Linux-style -d options or BSD-style -v options. Solaris' strftime() is missing a bunch of stuff (which affects the available date formats), perl is ancient, awk is ancient...

    I've been using the following hack for years on Solaris, to get the current epoch second:

    truss /usr/bin/date 2>&1 | awk '/^time/{print $NF}'
    

    Converting the other way is impossible using any POSIX tools as far as I know, but since you have perl available, the following might work:

    perl -le 'print scalar localtime $ARGV[0]' 1510329000
    

    Once you have this conversion in both directions, you can do math on it to adjust dates. For example:

    $ date
    Fri Nov 10 10:24:31 EST 2017
    $ now=$( truss /usr/bin/date 2>&1 | awk '/^time/{print $NF}' )
    $ then=$( perl -le 'print scalar localtime $ARGV[0]' $((now+3600)) )
    $ echo "$then"
    Fri Nov 10 11:24:46 2017
    

    For conversion of arbitrary GMT date/times to epoch seconds, I inherited the following bash code years and years ago. YMMV.

    # Use whatever process you like to populate these variables.
    # Note that since epoch zero was at midnight GMT, this time is GMT as well.
    read year month day hour minute second <<<"2017 11 10 15 50 00"
    
    if [[ $month -gt 2 ]]; then
      (( month++ ))
    else
      (( month+=13 ))
      (( year-=1 ))
    fi
    
    day=$(( (year*365)+(year/4)-(year/100)+(year/400)+(month*306001/10000)+day ))
    days_since_epoch=$(( day-719591 ))   # this seems to be close to Jan 1 1970
    seconds_since_epoch=$(( (days_since_epoch*86400)+(hour*3600)+(minute*60)+second ))
    
    echo "epoch: $seconds_since_epoch"
    

    Most of this code is intended to account for leap years and seconds. I haven't delved too much into the origin of the magic numbers, but with results that appear to work, I don't question them. :)

    To get just the hour and minute from perl, as you've shown in your question, you could probably use the following code:

    perl -le 'my ($h,$m) = (localtime($ARGV[0]))[2,1]; printf("%02d%02d\n",$h,$m);' 1510329000
    

    or

    perl -le 'use POSIX "strftime"; print strftime("%H%M", localtime($ARGV[0]));' 1510329000
    

    Aren't you happy to be using such a classic operating system as Solaris?

    See also: