From: miker Date: Tue, 16 Mar 2010 14:13:26 +0000 (+0000) Subject: use logical date math to avoid problems with DST boundary X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=6dde6e18352ba8a99d077b26913f9ad12eb64f24;p=Evergreen.git use logical date math to avoid problems with DST boundary git-svn-id: svn://svn.open-ils.org/ILS/branches/rel_1_6_0@15854 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/action.pm b/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/action.pm index 36f765422e..e82f15e518 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/action.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Storage/Publisher/action.pm @@ -593,6 +593,73 @@ __PACKAGE__->register_method( method => 'find_usr_summary_surveys', ); +sub seconds_to_interval_hash { + my $interval = shift; + my $limit = shift || 's'; + $limit =~ s/^(.)/$1/o; + + my %ouptut; + + my ($y,$ym,$M,$Mm,$w,$wm,$d,$dm,$h,$hm,$m,$mm,$s); + my ($year, $month, $week, $day, $hour, $minute, $second) = + ('years','months','weeks','days', 'hours', 'minutes', 'seconds'); + + if ($y = int($interval / (60 * 60 * 24 * 365))) { + $output{$year} = $y; + $ym = $interval % (60 * 60 * 24 * 365); + } else { + $ym = $interval; + } + return %output if ($limit eq 'y'); + + if ($M = int($ym / ((60 * 60 * 24 * 365)/12))) { + $output{$month} = $M; + $Mm = $ym % ((60 * 60 * 24 * 365)/12); + } else { + $Mm = $ym; + } + return %output if ($limit eq 'M'); + + if ($w = int($Mm / 604800)) { + $output{$week} = $w; + $wm = $Mm % 604800; + } else { + $wm = $Mm; + } + return %output if ($limit eq 'w'); + + if ($d = int($wm / 86400)) { + $output{$day} = $d; + $dm = $wm % 86400; + } else { + $dm = $wm; + } + return %output if ($limit eq 'd'); + + if ($h = int($dm / 3600)) { + $output{$hour} = $h; + $hm = $dm % 3600; + } else { + $hm = $dm; + } + return %output if ($limit eq 'h'); + + if ($m = int($hm / 60)) { + $output{$minute} = $m; + $mm = $hm % 60; + } else { + $mm = $hm; + } + return %output if ($limit eq 'm'); + + if ($s = int($mm)) { + $output{$second} = $s; + } else { + $output{$second} = 0 unless (keys %output); + } + return %output; +} + sub generate_fines { my $self = shift; @@ -742,7 +809,12 @@ sub generate_fines { } # XXX Use org time zone (or default to 'local') once we have the ou setting built for that - my $billing_ts = DateTime->from_epoch( epoch => $last_fine + $fine_interval * $bill, time_zone => 'local' ); + my $billing_ts = DateTime->from_epoch( epoch => $last_fine, time_zone => 'local' ); + my $current_bill_count = $bill; + while ( $current_bill_count ) { + $billing_ts->add( seconds_to_interval_hash( $fine_interval ) ); + $current_bill_count--; + } my $dow = $billing_ts->day_of_week_0(); my $dow_open = "dow_${dow}_open";