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 &lt;= $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 &lt; 0) {$year--; $month=12;} 

  return "$year-$month-$day $hour:00:00"; 
}
There's a timestamp file available here: http://coolwx.com/buoydata/data/curr/timestamp, so I think it'll be easier if you download and parse both data and timestamp files. 

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-&gt;strptime("2013092616", "%Y%m%d%H"); # Time::Piece object, see docs
say $time-&gt;datetime; # outputs: 2013-09-26T16:00:00


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