Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[Temporal.pm] implement later/earlier
Also kill off TimeUnit and change the API for .truncated-to, all
according to spec change 337f433398a070884e3258fc724c3b5f775fe085.
  • Loading branch information
Carl Masak committed May 21, 2014
1 parent 196b4ff commit f244c39
Showing 1 changed file with 50 additions and 32 deletions.
82 changes: 50 additions & 32 deletions src/core/Temporal.pm
@@ -1,15 +1,7 @@
my class DateTime { ... }
my class Date { ... }

my enum TimeUnit (
:second(1), :seconds(2),
:minute(3), :minutes(4),
:hour(5), :hours(6),
:day(7), :days(8),
:week(9), :weeks(10),
:month(11), :months(12),
:year(13), :years(14),
);
my @UNITS = <second minute hour day week month year> X~ '', 's';

my role Dateish {
method is-leap-year($y = $.year) {
Expand Down Expand Up @@ -114,14 +106,16 @@ my role Dateish {
1 .. self.days-in-month);
}

method truncate-parts(TimeUnit $unit, %parts? is copy) {
method truncate-parts(Cool $unit, %parts? is copy) {
# Helper for DateTime.truncated-to and Date.truncated-to.
if $unit == week | weeks {
X::DateTime::InvalidDeltaUnit.new(:$unit).throw
unless $unit eq any(@UNITS);
if $unit eq 'week' | 'weeks' {
my $dc = self.get-daycount;
my $new-dc = $dc - self.day-of-week($dc) + 1;
%parts<year month day> =
self.ymd-from-daycount($new-dc);
} else { # $unit == month | months | year | years
} else { # $unit eq 'month' | 'months' | 'year' | 'years'
%parts<day> = 1;
$unit eq 'year' and %parts<month> = 1;
}
Expand Down Expand Up @@ -329,29 +323,37 @@ my class DateTime does Dateish {
$!timezone.Int / 60 / 60;
}

method delta($amount, TimeUnit $unit) {
method later(*%unit) {
die "More than one time unit supplied"
if %unit.keys > 1;

my ($unit, $amount) = %unit.kv;

X::DateTime::InvalidDeltaUnit.new(:$unit).throw
unless $unit eq any(@UNITS);

my ($hour, $minute) = $!hour, $!minute;
my $date;

given $unit {
when second | seconds {
when 'second' | 'seconds' {
return DateTime.new(self.Instant + $amount);
}

when minute | minutes { $minute += $amount; proceed }
when 'minute' | 'minutes' { $minute += $amount; proceed }

$hour += floor($minute / 60);
$minute %= 60;

when hour | hours { $hour += $amount; proceed }
when 'hour' | 'hours' { $hour += $amount; proceed }

my $day-delta += floor($hour / 24);
$hour %= 24;

when day | days { $day-delta += $amount; proceed }
when week | weeks { $day-delta += 7 * $amount; proceed }
when 'day' | 'days' { $day-delta += $amount; proceed }
when 'week' | 'weeks' { $day-delta += 7 * $amount; proceed }

when month | months {
when 'month' | 'months' {
my ($month, $year) = $!month, $!year;
$month += $amount;
$year += floor(($month - 1) / 12);
Expand All @@ -360,7 +362,7 @@ my class DateTime does Dateish {
succeed;
}

when year | years {
when 'year' | 'years' {
my $year = $!year + $amount;
$date = Date.new(:$year, :$!month, :$!day);
succeed;
Expand All @@ -387,17 +389,21 @@ my class DateTime does Dateish {
self.new(:$date, :$hour, :$minute, :$second);
}

method truncated-to(TimeUnit $unit) {
method earlier(*%unit) {
self.later(| -<< %unit);
}

method truncated-to(Cool $unit) {
my %parts;
given $unit {
%parts<second> = self.whole-second;
when second {}
when 'second' {}
%parts<second> = 0;
when minute {}
when 'minute' {}
%parts<minute> = 0;
when hour {}
when 'hour' {}
%parts<hour> = 0;
when day {}
when 'day' {}
# Fall through to Dateish.
%parts = self.truncate-parts($unit, %parts);
}
Expand Down Expand Up @@ -526,22 +532,30 @@ my class Date does Dateish {
self.new(DateTime.now);
}

method truncated-to(TimeUnit $unit) {
method truncated-to(Cool $unit) {
self.clone(|self.truncate-parts($unit));
}

method delta($amount, TimeUnit $unit) {
method later(*%unit) {
die "More than one time unit supplied"
if %unit.keys > 1;

my ($unit, $amount) = %unit.kv;

X::DateTime::InvalidDeltaUnit.new(:$unit).throw
unless $unit eq any(@UNITS);

my $date;

given $unit {
X::DateTime::InvalidDeltaUnit.new(:$unit).throw
when second | seconds | minute | minutes | hour | hours;
when 'second' | 'seconds' | 'minute' | 'minutes' | 'hour' | 'hours';

my $day-delta;
when day | days { $day-delta = $amount; proceed }
when week | weeks { $day-delta = 7 * $amount; proceed }
when 'day' | 'days' { $day-delta = $amount; proceed }
when 'week' | 'weeks' { $day-delta = 7 * $amount; proceed }

when month | months {
when 'month' | 'months' {
my ($month, $year) = $!month, $!year;
$month += $amount;
$year += floor(($month - 1) / 12);
Expand All @@ -550,7 +564,7 @@ my class Date does Dateish {
succeed;
}

when year | years {
when 'year' | 'years' {
my $year = $!year + $amount;
$date = Date.new(:$year, :$!month, :$!day);
succeed;
Expand All @@ -562,6 +576,10 @@ my class Date does Dateish {
$date;
}

method earlier(*%unit) {
self.later(| -<< %unit);
}

method clone(*%_) {
my %args = { :$!year, :$!month, :$!day, %_ };
self.new(|%args);
Expand Down

0 comments on commit f244c39

Please sign in to comment.