# More elegant way to get timestamp from day/hour? (Perl)

http://coolwx.com/buoydata/data/curr/all.html provides weather data from ships (or maybe buoys) at sea, but the date is given as "25/18" (meaning the 18th hour of the 25th day of the month, all times GMT).

I need to convert this to a full timestamp ("2013-09-25 18:00:00"). All reports are in the near past. One glitch: if today is the 1st, and the report is "31/18" for example, it's referring to the 31st of last month.

Here's my solution, which I feel is kludgey. Can it be improved?

sub ship2time {
my(@now) = gmtime(time());
# assumed given as "foo/bar";
my($day,$hour) = split(/\//, $_[0]); # today's date (GMT) my($today) = strftime("%d", @now);
# if the given day is in the past (or very near future) it's this month
if ($day <=$today+1) {
return strftime("%Y-%m-$day$hour:00:00", @now);
}

# otherwise, we're referring to last month (eg, today is the 1st,
# report says 31st)
my($year,$month) = split(/\-/, strftime("%Y-%m", @now));
$month--; if ($month < 0) {$year--;$month=12;}

return "$year-$month-$day$hour:00:00";
}

• The link you gave as an example has month name in the first line (Offshore Data at 06Z Sep 26) - can you use it? – Xaerxess Sep 26 '13 at 6:53
• Wow, that's embarrassing. I always just ignored the header lines. I also didn't realize all the reports were on the same day/hour. You're right. – user1149 Sep 26 '13 at 15:47
• Plus, there's a timestamp file available here: coolwx.com/buoydata/data/curr/timestamp - I think it'll be easier if you download both data and timestamp files and make your life easier and code more elegant :) You can parse the timestamp with this with %Y%m%d%H, i.e.: perl -MTime::Piece -E 'say Time::Piece->strptime("2013092616", "%Y%m%d%H")->datetime' (outputs 2013-09-26T16:00:00). – Xaerxess Sep 26 '13 at 16:15
• I never though to look at the virtual directory coolwx.com/buoydata/data/curr but there's a lot of info there, thanks. Turn your comment into an answer and I'll approve it. – user1149 Sep 26 '13 at 18:47

You can parse the timestamp with this with %Y%m%d%H pattern, for example using core Time::Piece module and its strptime function:
use Time::Piece;
my $time = Time::Piece->strptime("2013092616", "%Y%m%d%H"); # Time::Piece object, see docs say$time->datetime; # outputs: 2013-09-26T16:00:00

See documentation for more formatting methods of Time::Piece object.