X-Git-Url: https://defaria.com/gitweb/?a=blobdiff_plain;ds=inline;f=lib%2FDateUtils.pm;h=f8bfc1c8c0caa7a6783a6e7d0676d2ef0a06445f;hb=a9acda90df2ba4a4777fe263005a5d45ffd869e0;hp=b8c1f49f662fc486cec21f7d389e160fa0ad3ee1;hpb=020a4a5ea2be725b155cae3a2cadc9aba3911b9b;p=clearscm.git diff --git a/lib/DateUtils.pm b/lib/DateUtils.pm index b8c1f49..f8bfc1c 100644 --- a/lib/DateUtils.pm +++ b/lib/DateUtils.pm @@ -60,7 +60,7 @@ use Time::Local; use Display; use Utils; -our @EXPORT = qw ( +our @EXPORT = qw( Add Age Compare @@ -79,6 +79,7 @@ our @EXPORT = qw ( YMDHMS timestamp ymdhms + MDYHMS2SQLDatetime ); my @months = ( @@ -101,11 +102,11 @@ my $SECS_IN_HOUR = $SECS_IN_MIN * 60; my $SECS_IN_DAY = $SECS_IN_HOUR * 24; # Forwards -sub Today2SQLDatetime (); -sub DateToEpoch ($); -sub EpochToDate ($); +sub Today2SQLDatetime(); +sub DateToEpoch($); +sub EpochToDate($); -sub ymdhms { +sub ymdhms(;$) { my ($time) = @_; $time ||= time; @@ -138,34 +139,34 @@ sub ymdhms { return $year, $mon, $mday, $hour, $min, $sec; } # ymdhms -sub julian ($$$) { +sub julian($$$) { my ($year, $month, $day) = @_; my $days = 0; my $m = 1; - foreach (@months) { + for (@months) { last if $m >= $month; $m++; $days += $_; - } # foreach + } # for return $days + $day; } # julian -sub _is_leap_year ($) { +sub _is_leap_year($) { my ($year) = @_; - + return 0 if $year % 4; return 1 if $year % 100; return 0 if $year % 400; - + return 1; } # _is_leap_year -sub Add ($%) { +sub Add($%) { my ($datetime, %parms) = @_; - + =pod =head2 Add ($datetime, %parms) @@ -222,47 +223,47 @@ Returns: 'days', 'months', ); - - foreach (keys %parms) { + + for (keys %parms) { unless (InArray ($_, @validKeys)) { croak "Invalid key in DateUtils::Add: $_"; } # unless - } # foreach - + } # for + my $epochTime = DateToEpoch $datetime; - + my $amount = 0; - + $parms{seconds} ||= 0; $parms{minutes} ||= 0; $parms{hours} ||= 0; $parms{days} ||= 0; - + $amount += $parms{days} * $SECS_IN_DAY; $amount += $parms{hours} * $SECS_IN_HOUR; $amount += $parms{minutes} * $SECS_IN_MIN; $amount += $parms{seconds}; - + $epochTime += $amount; $datetime = EpochToDate $epochTime; - + if ($parms{month}) { my $years = $parms{month} / 12; my $months = $parms{month} % 12; - + my $month = substr $datetime, 5, 2; - + $years += ($month + $months) / 12; substr ($datetime, 5, 2) = ($month + $months) % 12; - + substr ($datetime, 0, 4) = substr ($datetime, 0, 4) + $years; } # if - + return $datetime; } # Add -sub Age ($) { +sub Age($) { my ($timestamp) = @_; =pod @@ -317,7 +318,6 @@ Returns: my $leap_days = 0; for (my $i = $timestamp_year; $i < $today_year; $i++) { - $leap_days++ if $i % 4 == 0; } # for @@ -326,12 +326,12 @@ Returns: } # if } # Age -sub Compare ($$) { +sub Compare($$) { my ($date1, $date2) = @_; - + =pod -=head2 Compare ($date2, $date2) +=head2 Compare ($date1, $date2) Compares two datetimes returning -1 if $date1 < $date2, 0 if equal or 1 if $date1 > $date2 @@ -371,9 +371,9 @@ Returns: return DateToEpoch ($date1) <=> DateToEpoch ($date2); } # Compare -sub DateToEpoch ($) { +sub DateToEpoch($) { my ($date) = @_; - + =pod =head2 DateToEpoch ($datetime) @@ -414,13 +414,13 @@ Returns: my $hour = substr $date, 11, 2; my $minute = substr $date, 14, 2; my $seconds = substr $date, 17, 2; - + my $days; for (my $i = 1970; $i < $year; $i++) { $days += _is_leap_year ($i) ? 366 : 365; } # for - + my @monthDays = ( 0, 31, @@ -435,23 +435,22 @@ Returns: 304, 334, ); - + $days += $monthDays[$month - 1]; - - $days++ - if _is_leap_year ($year) and $month > 2; - - $days += $day - 1; - + + $days++ if _is_leap_year ($year) and $month > 2; + + $days += $day - 1; + return ($days * $SECS_IN_DAY) + ($hour * $SECS_IN_HOUR) + ($minute * $SECS_IN_MIN) + $seconds; } # DateToEpoch -sub EpochToDate ($) { +sub EpochToDate($) { my ($epoch) = @_; - + =pod =head2 EpochToDate ($epoch) @@ -486,23 +485,23 @@ Returns: =cut - my $year = 1970; my ($month, $day, $hour, $minute, $seconds); + + my $year = 1970; my $leapYearSecs = 366 * $SECS_IN_DAY; my $yearSecs = $leapYearSecs - $SECS_IN_DAY; - + while () { my $amount = _is_leap_year ($year) ? $leapYearSecs : $yearSecs; - - last - if $amount > $epoch; - + + last if $amount > $epoch; + $epoch -= $amount; $year++; } # while - + my $leapYearAdjustment = _is_leap_year ($year) ? 1 : 0; - + if ($epoch >= (334 + $leapYearAdjustment) * $SECS_IN_DAY) { $month = '12'; $epoch -= (334 + $leapYearAdjustment) * $SECS_IN_DAY; @@ -546,18 +545,18 @@ Returns: $epoch = $epoch % $SECS_IN_HOUR; $minute = int ($epoch / $SECS_IN_MIN); $seconds = $epoch % $SECS_IN_MIN; - + $day = "0$day" if $day < 10; $hour = "0$hour" if $hour < 10; $minute = "0$minute" if $minute < 10; $seconds = "0$seconds" if $seconds < 10; - + return "$year-$month-$day $hour:$minute:$seconds"; } # EpochToDate -sub UTCTime ($) { +sub UTCTime($) { my ($datetime) = @_; - + =pod =head2 UTCTime ($epoch) @@ -596,22 +595,22 @@ Returns: my ($sec, $min, $hour, $mday, $mon, $year) = gmtime ( DateToEpoch ($datetime) - (timegm (@localtime) - timelocal (@localtime)) ); - + $year += 1900; $mon++; - $sec = '0' . $sec if $sec < 10; - $min = '0' . $min if $min < 10; - $hour = '0' . $hour if $hour < 10; + $sec = '0' . $sec if $sec < 10; + $min = '0' . $min if $min < 10; + $hour = '0' . $hour if $hour < 10; $mon = '0' . $mon if $mon < 10; $mday = '0' . $mday if $mday < 10; - + return "$year-$mon-${mday}T$hour:$min:${sec}Z"; } # UTCTime -sub UTC2Localtime ($) { +sub UTC2Localtime($) { my ($utcdatetime) = @_; - + # If the field does not look like a UTC time then just return it. return $utcdatetime unless $utcdatetime =~ /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z/; @@ -620,17 +619,17 @@ sub UTC2Localtime ($) { my @localtime = localtime; - return EpochToDate ( + return EpochToDate( DateToEpoch ($utcdatetime) + (timegm (@localtime) - timelocal (@localtime)) ); } # UTC2Localtime -sub FormatDate ($) { - my ($date) = @_; +sub FormatDate($;$) { + my ($date, $separator) = @_; =pod -=head2 FormatDate ($date) +=head2 FormatDate ($date, $separator) Formats date @@ -644,6 +643,10 @@ Parameters: Date in YYYYMMDD +=tiem $separator + +If specified, indicates that $date has separators (e.g. 2021-07-04). + =back =for html @@ -662,14 +665,20 @@ Returns: =cut - return substr ($date, 4, 2) - . "/" - . substr ($date, 6, 2) - . "/" - . substr ($date, 0, 4); + unless ($separator) { + return substr($date, 4, 2) . '/' + . substr($date, 6, 2) . '/' + . substr($date, 0, 4); + } else { + return substr($date, 5, 2) + . '/' + . substr($date, 8, 2) + . '/' + . substr($date, 0, 4); + } # if } # FormatDate -sub FormatTime ($) { +sub FormatTime($) { my ($time) = @_; =pod @@ -712,10 +721,12 @@ Returns: $hours = $hours - 12 if $hours > 12; + $hours = "0$hours" if length $hours == 1; + return "$hours:$minutes $AmPm"; } # FormatTime -sub MDY (;$) { +sub MDY(;$) { my ($time) = @_; =pod @@ -757,7 +768,7 @@ Returns: return "$mon/$mday/$year"; } # MDY -sub SQLDatetime2UnixDatetime ($) { +sub SQLDatetime2UnixDatetime($) { my ($sqldatetime) = @_; =pod @@ -817,7 +828,7 @@ Returns: return $months{$month} . " $day, $year \@ $time"; } # SQLDatetime2UnixDatetime -sub SubtractDays ($$) { +sub SubtractDays($$) { my ($timestamp, $nbr_of_days) = @_; =pod @@ -866,6 +877,14 @@ Returns: my $month = substr $timestamp, 5, 2; my $day = substr $timestamp, 8, 2; + # We are not properly accounting for leap days but this is just a rough + # estimate anyway + if ($nbr_of_days > 365) { + $year -= int $nbr_of_days / 365; + + $nbr_of_days = $nbr_of_days % 365; + } # if + # Convert to Julian my $days = julian $year, $month, $day; @@ -911,7 +930,7 @@ Returns: return $year . "-" . $month . "-" . $days . substr $timestamp, 10; } # SubtractDays -sub Today2SQLDatetime () { +sub Today2SQLDatetime() { =pod @@ -945,10 +964,10 @@ Returns: =cut - return UnixDatetime2SQLDatetime (scalar (localtime)); + return UnixDatetime2SQLDatetime(scalar localtime); } # Today2SQLDatetime -sub UnixDatetime2SQLDatetime ($) { +sub UnixDatetime2SQLDatetime($) { my ($datetime) = @_; =pod @@ -1057,7 +1076,7 @@ Returns: unless ($months{$month_name}) { $month_name = substr $datetime, 8, 3; } # unless - + my $month = $months{$month_name}; my $time = substr $datetime, 11, 8; @@ -1069,12 +1088,12 @@ Returns: warning "Year undefined for $orig_datetime\nReturning today's date"; return Today2SQLDatetime; } # unless - + unless ($month) { warning "Month undefined for $orig_datetime\nReturning today's date"; return Today2SQLDatetime; } # unless - + unless ($day) { warning "Day undefined for $orig_datetime\nReturning today's date"; return Today2SQLDatetime; @@ -1088,7 +1107,7 @@ Returns: return "$year-$month-$day $time"; } # UnixDatetime2SQLDatetime -sub YMD (;$) { +sub YMD(;$) { my ($time) = @_; =pod @@ -1130,7 +1149,7 @@ Returns: return "$year$mon$mday"; } # YMD -sub YMDHM (;$) { +sub YMDHM(;$) { my ($time) = @_; =pod @@ -1172,7 +1191,7 @@ Returns: return "$year$mon$mday\@$hour:$min"; } # YMDHM -sub YMDHMS (;$) { +sub YMDHMS(;$) { my ($time) = @_; =pod @@ -1214,7 +1233,7 @@ Returns: return "$year$mon$mday\@$hour:$min:$sec"; } # YMDHMS -sub timestamp (;$) { +sub timestamp(;$) { my ($time) = @_; =pod @@ -1260,7 +1279,7 @@ Returns: =head3 Perl Modules -=for html
+=for html =head1 INCOMPATABILITIES