+ }
+ return 0;
+}
+
+=item _endpoints TIME CUTOFF_DAY
+
+Given a current time and a day of the month to prorate to, return three
+times: the start of the prorate interval (usually the current time), the
+end of the prorate interval (i.e. the cutoff date), and the time one month
+before the end of the prorate interval.
+
+=cut
+
+sub _endpoints {
+ my $self = shift;
+ my $mnow = shift;
+ my @cutoff_days = sort {$a <=> $b} @_;
+
+ # only works for freq >= 1 month; probably can't be fixed
+ my ($sec, $min, $hour, $mday, $mon, $year) = (localtime($mnow))[0..5];
+ my $rounding_mode = $self->option('prorate_round_day',1);
+ if ( $rounding_mode == 1 ) {
+ # If the time is 12:00-23:59, move to the next day by adding 18
+ # hours to $mnow. Because of DST this can end up from 05:00 to 18:59
+ # but it's always within the next day.
+ $mnow += 64800 if $hour >= 12;
+ # Get the new day, month, and year.
+ ($mday,$mon,$year) = (localtime($mnow))[3..5];
+ # Then set $mnow to midnight on that day.
+ $mnow = timelocal(0,0,0,$mday,$mon,$year);
+ } elsif ( $rounding_mode == 2 ) {
+ # Move the time back to midnight. This increases the length of the
+ # prorate interval.
+ $mnow = timelocal(0,0,0,$mday,$mon,$year);
+ ($mday,$mon,$year) = (localtime($mnow))[3..5];
+ } elsif ( $rounding_mode == 3 ) {
+ # If the time is after midnight, move it forward to the next midnight.
+ # This decreases the length of the prorate interval.
+ if ( $sec > 0 or $min > 0 or $hour > 0 ) {
+ # move to one second before midnight, then tick forward
+ $mnow = timelocal(59,59,23,$mday,$mon,$year) + 1;
+ ($mday,$mon,$year) = (localtime($mnow))[3..5];