0

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!

mathB
  • 634
  • 8
  • 21
  • 1
    Which version of Perl do you have? Run `perl -v` please. And also [edit] and include the expected output. I don't know what that `date -d` with the string is supposed to do. Is it part of a shell script? What are the values? – simbabque Nov 10 '17 at 09:04
  • This is perl v5.8.4 – mathB Nov 10 '17 at 09:05
  • 1
    Wow. That's ancient. That version of today is almost 14 years old. – simbabque Nov 10 '17 at 09:07
  • @simbabque I know :( I have updated the question with what I get in Linux. I'd like to get the same result, if possible in via `perl`. – mathB Nov 10 '17 at 09:08
  • So `$hr`, `$mi` and `$duration` are shell variables? – simbabque Nov 10 '17 at 09:09
  • If you want a one-liner ... where do the time and duration come from? Just type them in? – zdim Nov 10 '17 at 09:09
  • Is the format always the same? I don't think 5.8.4 included any useful date parsing utilities in the core distribution. Can you install stuff from CPAN, or is that box completely locked down? – simbabque Nov 10 '17 at 09:11
  • @simbabque yes, they are variables, calculated in a shell script. Basically I take those values from a file which has time and duration along with a few more values. – mathB Nov 10 '17 at 09:11
  • What does it do? I don't see how the output works. You have hour, minute and a duration, and you format it to hour and minute, but it disregards the 23 from the time string, and the 60 minute duration, and gives you an output of `%H` as `00` hours and `%M` as 28 minutes. Does not seem very useful. – simbabque Nov 10 '17 at 09:14
  • @zdim, they are extracted from a file using `awk` command. @simbabque - no, I can't install anything, I don't have any privileges. I checked and found that I have `Time::Local`. Does that help? – mathB Nov 10 '17 at 09:14
  • @simbabque I am basically calculating an ETA. 23:28 is the start time. Duration in minutes is what I should add to this 23:28 time and produce an ETA, which is 12:28 the next day or 00:28 in Unix. Makes sense? – mathB Nov 10 '17 at 09:18
  • If it is exactly what you describe that is simple: add minutes, see if it's `>60` and adjust, increment hour and roll it over if `>24`. (Are there any other `Time::` or `Date::` modules?) – zdim Nov 10 '17 at 09:22
  • @zdim, that's exactly what I want. I do have `Time::Local` present. – mathB Nov 10 '17 at 09:24
  • What version of Solaris? – ghoti Nov 10 '17 at 11:25
  • @ghoti, version 10. `Oracle Solaris 10 8/11 s10s_...` – mathB Nov 10 '17 at 11:28
  • Okay, er ... do you have a C compiler available? That is, can you run `gcc --version`, or when you run `cc`, do you get something other than `language optional software package not installed`? – ghoti Nov 10 '17 at 15:03
  • Ok, I can answer this only on Monday as I've lost access to my system and its weekend. :-) Thanks for trying everyone. Hopefully we'll get something! – mathB Nov 10 '17 at 15:22
  • You can download a Solaris 10 install image which you can run in VirtualBox if you want to experiment over the weekend. – ghoti Nov 10 '17 at 15:27
  • I had that thought, let me try. – mathB Nov 10 '17 at 15:28
  • The default awk on Solaris in /bin is old, broken awk which no-one should ever use but there IS an almost-POSIX awk in /usr/xpg4/bin. Maybe look there or elsewhere to see if there's a different `date` command too? – Ed Morton Nov 10 '17 at 16:20
  • @EdMorton I did check, there was another `date` in xpg4 (or something similar path), but it wasn't compatible with `date -d` as well. `awk` wasn't supporting `strftime` I didn't look further. But I got the solution, Thanks to ghoti! – mathB Nov 11 '17 at 02:23

1 Answers1

1

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:

ghoti
  • 45,319
  • 8
  • 65
  • 104
  • This is very interesting, though some of the codes above scares me. I tried this, took a little time to install `Solaris 10`. I used the input `2017 11 10 23 33 00` in the script to calculate epoch and I got `1510356780`. But when I use `perl -le 'print scalar localtime $ARGV[0]' 1510356780` to check if I get the right date, I get `Nov 11, 05:33:00 2017`! EDIT: Your script adds 6 hours to the input time, isn't it? I can't seem to find that `6 hours` - where do I modify the time I want to add? :) – mathB Nov 10 '17 at 18:05
  • Epoch second `1510356780` is indeed `Fri Nov 10 23:33:00 UTC 2017`. When you print that perl snippet, your system is printing the time in the local time zone. I suspect you're running this in Asia somewhere -- [PRC or Bangladesh or Bhutan](https://en.wikipedia.org/wiki/UTC%2B06:00). If you instead run `TZ=GMT perl -le 'print scalar localtime $ARGV[0]' 1510356780` (assuming you're in POSIX or bash shell), you'll see the results you expect. Or try `perl -le 'use POSIX; print POSIX::strftime("%F %T %Z%z", localtime($ARGV[0]));' 1510356780` to see the time with the timezone. – ghoti Nov 10 '17 at 18:41
  • *Its date command is missing a bunch of stuff, like the ability to process Linux-style `-d` options or BSD-style `-v` options.* I bet it doesn't process Microsoft-style options, either. ;-) – Andrew Henle Nov 10 '17 at 19:35
  • @AndrewHenle -- Microsoft operating systems have a `date` command? News to me! (Notwithstanding Xenix, of course, whose `date` command was probably pretty close to Solaris's...) – ghoti Nov 11 '17 at 01:53
  • @ghoti You are right. It's the timezone. I ran it with `TZ=GMT`, it works. I don't know how it's going to be in my server :) Either way, I can manage now. Thanks for your help, I was really in dark. I have to wonder though, how simple the `date -d` command was to get the desired output I want. And how tough it is to recreate something that is not supported in Solaris. – mathB Nov 11 '17 at 02:10
  • @ghoti You missed the point entirely. You seem to expect platform-specific non-standard extensions to [the POSIX-standardized `date` utility](http://pubs.opengroup.org/onlinepubs/9699919799/utilities/date.html) to be available on multiple platforms. – Andrew Henle Nov 12 '17 at 16:20