spider/perl/IsoTime.pm

149 lines
2.5 KiB
Perl
Raw Normal View History

#
# Utility routines for handling Iso 8601 date time groups
#
2007-06-24 01:17:43 +00:00
#
#
# Copyright (c) Dirk Koopman, G1TLH
#
use strict;
package IsoTime;
use Date::Parse;
use vars qw($year $month $day $hour $min $sec @days @ldays);
@days = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
@ldays = (31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
# is it a leap year?
sub _isleap
{
my $year = shift;
return ($year % 4 == 0 && ($year % 100 != 0 || $year % 400 == 0)) ? 1 : 0;
}
sub full
{
return sprintf "%04d%02d%02dT%02d%02d%02d", $year, $month, $day, $hour, $min, $sec;
}
sub dayminsec
{
return sprintf "%02dT%02d%02d%02d", $day, $hour, $min, $sec;
}
sub daymin
{
return sprintf "%02dT%02d%02d", $day, $hour, $min;
}
sub hourmin
{
return sprintf "%02d%02d", $hour, $min;
}
sub hourminsec
{
return sprintf "%02d%02d%02d", $hour, $min, $sec;
}
sub update
{
my $t = shift || time;
($sec,$min,$hour,$day,$month,$year) = gmtime($t);
$month++;
$year += 1900;
}
sub unixtime
{
my $iso = shift;
# get the correct day, if required
if (my ($h) = $iso =~ /^([012]\d)[0-5]\d(?:[0-5]\d)?$/) {
my ($d, $m, $y) = ($day, $month, $year);
if ($h != $hour) {
if ($hour < 12 && $h - $hour >= 12) {
# yesterday
($d, $m, $y) = _yesterday($d, $m, $y);
} elsif ($hour >= 12 && $hour - $h > 12) {
# tomorrow
($d, $m, $y) = _tomorrow($d, $m, $y);
}
}
$iso = sprintf("%04d%02d%02dT", $y, $m, $d) . $iso;
} elsif (my ($d) = $iso =~ /^(\d\d)T\d\d\d\d/) {
# get the correct month and year if it is a short date
if ($d == $day) {
$iso = sprintf("%04d%02d", $year, $month) . $iso;
} else {
my $days = _isleap($year) ? $ldays[$month-1] : $days[$month-1];
my ($y, $m) = ($year, $month);
if ($d < $day) {
if ($day - $d > $days / 2) {
if ($month == 1) {
$y = $year - 1;
$m = 12;
} else {
$m = $month - 1;
}
}
} else {
if ($d - $day > $days / 2) {
if ($month == 12) {
$y = $year + 1;
$m = 1;
} else {
$m = $month + 1;
}
}
}
$iso = sprintf("%04d%02d", $y, $m) . $iso;
}
}
return str2time($iso);
}
sub _tomorrow
{
my ($d, $m, $y) = @_;
$d++;
my $days = _isleap($y) ? $ldays[$month-1] : $days[$month-1];
if ($d > $days) {
$d = 1;
$m++;
if ($m > 12) {
$m = 1;
$y++;
} else {
$y = $year;
}
}
return ($d, $m, $y);
}
sub _yesterday
{
my ($d, $m, $y) = @_;
$d--;
if ($d <= 0) {
$m--;
$y = $year;
if ($m <= 0) {
$m = 12;
$y--;
}
$d = _isleap($y) ? $ldays[$m-1] : $days[$m-1];
}
return ($d, $m, $y);
}
1;