- my($range_sub, $start, $end, %opt) = @_;
-
- my $as = $opt{'no_as'} ? '' : " AS rangecol_${start}_$end";
-
- my $offset = $opt{'offset'} || 0;
- # Time::ParseDate for excruciating correctness
- # Always use $offset - 1day + 1sec = the last second of that day
- $start = parsedate('00:00 '.($start + $offset - 1).' days ago') - 1;
- $end = $end ?
- parsedate('00:00 '.($end + $offset - 1).' days ago') - 1 :
- '';
- my $cutoff = parsedate('00:00 '.($offset - 1).' days ago') - 1;
-
- my $sql = &{$range_sub}( $start, $end, $cutoff ); #%opt?
+ my($range_sub, $startdays, $enddays, %opt) = @_;
+
+ my $as = $opt{'no_as'} ? '' : " AS rangecol_${startdays}_$enddays";
+
+ my $as_of = $opt{'as_of'} || time;
+ my $cutoff = DateTime->from_epoch(epoch => $as_of, time_zone => 'local');
+ $cutoff->truncate(to => 'day'); # local midnight on the report day
+ $cutoff->add(days => 1); # the day after that
+ $cutoff->subtract(seconds => 1); # the last second of the report day
+
+ my $start = $cutoff->clone;
+ $start->subtract(days => $startdays);
+
+ my $end = $cutoff->clone;
+ $end->subtract(days => $enddays);
+
+ #warn "cutoff ".$cutoff->epoch.", range $startdays-$enddays (".$start->epoch . '-' . ($enddays ? $end->epoch : '').")\n";
+ my $sql = &{$range_sub}( $start->epoch,
+ $enddays ? $end->epoch : '',
+ $cutoff->epoch ); #%opt?