| Solstice documentation | Contained in the Solstice distribution. |
Solstice::DateTime - Models a point in time.
use Solstice::DateTime;
my $dt = new Solstice::DateTime(time());
my $dt = new Solstice::DateTime('2005-03-11 02:34:12');
my $dt = new Solstice::DateTime('now');
# These functions return the object
$date_time->addYears($year_count);
$date_time->addMonths($month_count);
$date_time->addDays($day_count);
No symbols exported.
Constructor. Returns a DateTime object.
Sets the date
Sets the time
Returns a duplicate DateTime object.
Add some number of years to the date.
Add some number of months to the date.
Add some number of days to the date
Add some number of hours to the date
Add some number of min to the date
Add some number of seconds to the date
Validate the date values as forming a valid date. Date::Calc::check_date does the heavy work.
Validate the time values as forming a valid time. Date::Calc::check_time does the heavy work.
Returns a boolean specifying whether the obj datetime is valid
Returns a boolean specifying whether the obj contains a datetime
Returns a boolean specifying whether the obj datetime is equal to the passed datetime.
Returns a boolean specifying whether the obj datetime is the same date to the passed in datetime
Returns a boolean specifying whether the obj datetime is before the passed datetime.
Returns a boolean specifying whether the obj datetime is before now.
Returns the number of days apart the 2 datetime objects are, as a float. Returns 0 if either is invalid.
Returns the number of seconds apart the 2 datetime objects are. Returns 0 if either is invalid.
Returns an SQL formatted date
Returns an ISO 8601 formatted date
Returns a human-readable date string
Return a formatted string, that displays a moving 3-day window
Returns a Unix formatted date (epoch seconds)
Returns a formatted datetime string; $format contains a strftime-style formatting string. Date validity is not implicit.
Takes a date object and compares it to itself.
Does the heavy lifting for addDays, addMonths, and addYears.
Update the date if the DateTime obj is a 'now' obj
Catalyst Group, <catalyst@u.washington.edu>
$Revision: 3364 $
Copyright 1998-2007 Office of Learning Technologies, University of Washington
Licensed under the Educational Community License, Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: http://www.opensource.org/licenses/ecl1.php
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
| Solstice documentation | Contained in the Solstice distribution. |
package Solstice::DateTime; # $Id: DateTime.pm 3364 2006-05-05 07:18:21Z mcrawfor $
use 5.006_000; use strict; use warnings; use base qw(Solstice::Model); use Date::Calc qw(:all); use Date::Format; use constant TRUE => 1; use constant FALSE => 0; use constant SUCCESS => 1; use constant FAIL => 0; our ($VERSION) = ('$Revision: 3364 $' =~ /^\$Revision:\s*([\d.]*)/);
sub new { my $class = shift; my $input = shift; my $self = $class->SUPER::new(); return $self unless defined $input; $self->_init($input); return $self; }
sub setDate { my $self = shift; my ($year, $month, $day) = @_; $self->_setYear($year); $self->_setMonth($month); $self->_setDay($day); return SUCCESS; }
sub setTime { my $self = shift; my ($hour, $min, $sec, $ampm) = @_; if (defined $ampm and defined $hour and $hour =~ /^\d+$/) { $hour += 12 if ($ampm eq 'pm' and $hour > 0 and $hour < 13); $hour = 0 if ($ampm eq 'am' and $hour == 12); } $self->_setHour($hour); $self->_setMin($min); $self->_setSec($sec); return SUCCESS; }
sub clone { my $self = shift; $self->_updateToNow(); my $clone = Solstice::DateTime->new({ year => $self->_getYear(), month => $self->_getMonth(), day => $self->_getDay(), hour => $self->_getHour(), min => $self->_getMin(), sec => $self->_getSec(), ampm => 0, }); $clone->setIsNow($self->getIsNow()); return $clone; }
sub addYears { my $self = shift; my $years = shift; return $self->_addYMD($years, 0, 0); }
sub addMonths { my $self = shift; my $months = shift; return $self->_addYMD(0, $months, 0); }
sub addDays { my $self = shift; my $days = shift; return $self->_addYMD(0, 0, $days); }
sub addHours { my $self = shift; my $hours = shift; return $self->_addHMS($hours, 0, 0); }
sub addMinutes { my $self = shift; my $min = shift; return $self->_addHMS(0, $min, 0); }
sub addSeconds { my $self = shift; my $seconds = shift; return $self->_addHMS(0, 0, $seconds); }
sub getYear { my $self = shift; $self->_updateToNow(); return $self->_getYear(); }
sub getMonth { my $self = shift; $self->_updateToNow(); return $self->_getMonth(); }
sub getDay { my $self = shift; $self->_updateToNow(); return $self->_getDay(); }
sub getHour { my $self = shift; $self->_updateToNow(); return $self->_getHour(); }
sub getMin { my $self = shift; $self->_updateToNow(); return $self->_getMin(); }
sub getSec { my $self = shift; $self->_updateToNow(); return $self->_getSec(); }
sub isValidDate { my $self = shift; return TRUE if $self->getIsNow(); my $year = $self->_getYear(); my $month = $self->_getMonth(); my $day = $self->_getDay(); return FALSE unless ( defined $year and $year =~ /^\d+$/ and defined $month and $month =~ /^\d+$/ and defined $day and $day =~ /^\d+$/ ); return check_date($year, $month, $day) ? TRUE : FALSE; }
sub isValidTime { my $self = shift; return TRUE if $self->getIsNow(); my $hour = $self->_getHour(); my $min = $self->_getMin(); my $sec = $self->_getSec(); return FALSE unless ( defined $hour and $hour =~ /^\d+$/ and defined $min and $min =~ /^\d+$/ and defined $sec and $sec =~ /^\d+$/ ); return check_time($hour, $min, $sec) ? TRUE : FALSE; }
sub isValid { my $self = shift; return ($self->isValidDate() && $self->isValidTime()) ? TRUE : FALSE; }
sub isEmpty { my $self = shift; return FALSE if $self->getIsNow(); return ($self->_getYear() || $self->_getMonth() || $self->_getDay() || $self->_getHour() || $self->_getMin() || $self->_getSec()) ? FALSE : TRUE; }
sub isEqualTo { my $self = shift; my $arg = shift; return FALSE unless $self->isValid(); return FALSE unless (defined $arg and $arg->isValid()); $self->_updateToNow(); $arg->_updateToNow(); return ($self->getTimeApart($arg)==0) ? TRUE : FALSE; }
sub isSameDay { my $self = shift; my $arg = shift; return FALSE unless $self->isValid(); return FALSE unless (defined $arg && $arg->isValid()); $self->_updateToNow(); $arg->_updateToNow(); return ($self->getDaysApart($arg)==0) ? TRUE : FALSE; }
sub isBefore { my $self = shift; my $arg = shift; return undef unless $self->isValid(); return undef unless (defined $arg and $arg->isValid()); $self->_updateToNow(); $arg->_updateToNow(); my $days1 = Date_to_Days($self->_getYear(), $self->_getMonth(), $self->_getDay()); my $days2 = Date_to_Days($arg->_getYear(), $arg->_getMonth(), $arg->_getDay()); return TRUE if ($days1 < $days2); return FALSE if ($days1 > $days2); return ($self->_getHour() * 3600 + $self->_getMin() * 60 + $self->_getSec()) < ($arg->_getHour() * 3600 + $arg->_getMin() * 60 + $arg->_getSec()) ? TRUE : FALSE; }
sub isBeforeNow { my $self = shift; return undef unless $self->isValid(); return FALSE if $self->getIsNow(); $self->_updateToNow(); my ($year, $month, $day, $hour, $min, $sec) = Today_and_Now(); my $days1 = Date_to_Days($self->_getYear(), $self->_getMonth(), $self->_getDay()); my $days2 = Date_to_Days($year, $month, $day); return TRUE if ($days1 < $days2); return FALSE if ($days1 > $days2); return ($self->_getHour() * 3600 + $self->_getMin() * 60 + $self->_getSec()) < ($hour * 3600 + $min * 60 + $sec) ? TRUE : FALSE; }
sub getDaysApart { my $self = shift; my $date = shift; return 0 unless $self->isValidDate(); return 0 unless $date->isValidDate(); return Delta_Days($self->getYear(), $self->getMonth(), $self->getDay(), $date->getYear(), $date->getMonth(), $date->getDay()); }
sub getTimeApart { my $self = shift; my $date = shift; return 0 unless $self->isValidDate(); return 0 unless $date->isValidDate(); my ($day, $hour, $min, $sec) = Delta_DHMS($self->getYear(), $self->getMonth(), $self->getDay(),$self->getHour(), $self->getMin(),$self->getSec(), $date->getYear(), $date->getMonth(), $date->getDay(), $date->getHour(), $date->getMin(), $date->getSec()); return $sec +($min*60)+($hour*3600)+ ($day*24*3600); }
sub toSQL { my $self = shift; return undef unless $self->isValid(); return $self->toString("%Y-%m-%d %H:%M:%S"); }
sub toISO { my $self = shift; return undef unless $self->isValid(); return $self->toString("%Y%m%d%H%M%S"); }
sub toCommon { my $self = shift; return undef unless $self->isValid(); return $self->toString("%L/%d/%Y %l:%M %p"); }
sub toMovingWindow { my $self = shift; return undef unless $self->isValid(); my $now = time(); my $day = 60 * 60 * 24; my $dateformat = "%L%d%Y"; my $timeformat = "%l:%M %p"; my $date = $self->toString($dateformat); if($self->isBefore(Solstice::DateTime->new($now - $day)) || Solstice::DateTime->new($now + $day)->isBefore($self)){ return $self->toString("%b %e, %Y %l:%M %p"); } elsif ($date == Solstice::DateTime->new($now)->toString($dateformat)) { return $self->toString('Today, '.$timeformat); } elsif ($date == Solstice::DateTime->new($now - $day)->toString($dateformat)) { return $self->toString('Yesterday, '.$timeformat); } elsif ($date == Solstice::DateTime->new($now + $day)->toString($dateformat)) { return $self->toString('Tomorrow, '.$timeformat); }else { return $self->toString("%b %e, %Y %l:%M %p"); } }
sub toUnix { my $self = shift; # seeing as 3:14:07 a.m. on Jan. 19, 2038 is the limit on 32bit machines for unix timestamps # we don't want to be using this method since our model considers dates larger than that valid warn "toUnix is deprecated!! DO NOT USE AT ". join(' ', caller()); return undef unless $self->isValid(); $self->_updateToNow(); return Mktime($self->_getYear(), $self->_getMonth(), $self->_getDay(), $self->_getHour(), $self->_getMin(), $self->_getSec()); }
sub toString { my $self = shift; my $format = shift; $self->_updateToNow(); my @date = ($self->_getSec(), $self->_getMin(), $self->_getHour(), $self->_getDay(), ($self->_getMonth() || 1) - 1, ($self->_getYear() || 1900) - 1900); return strftime($format, @date); }
sub cmpDate { my $self = shift; my $date = shift; if (!$self->isValidDate()) { # I'm invalid, but the other one isn't, it should be ahead of me. if ($date->isValidDate()) { return 1; } else { # Both are invalid, consider them equivelent. return 0; } } # I'm valid, but the other one isn't, i should be ahead of it. if (!$date->isValidDate()) { return -1; } my $diff = $self->getTimeApart($date); return 0 <=> $diff; } # Legacy method sub isNow { my $self = shift; return $self->getIsNow(); }
sub _init { my $self = shift; my $input = shift; my ($year, $month, $day, $hour, $min, $sec, $ampm); if ($self->isValidHashRef($input)) { # Hashref input $year = $input->{'year'}; $month = $input->{'month'}; $day = $input->{'day'}; $hour = $input->{'hour'}; $min = $input->{'min'}; $sec = $input->{'sec'}; $ampm = $input->{'ampm'}; } elsif ($input =~ /^0000-00-00 00:00:00$/) { # MySQL 'zero' date...leave values undef } elsif ($input =~ /^(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)$/) { # MySQL date...leading zeros are removed ($year, $month, $day, $hour, $min, $sec) = ($1, $2+0, $3+0, $4+0, $5+0, $6+0); } elsif ($input =~ /^(\d\d\d\d)-(\d\d)-(\d\d)$/) { # MySQL date with no time ($year, $month, $day, $hour, $min, $sec) = ($1, $2+0, $3+0, 0, 0, 0); } elsif ($input =~ /^(\d{1,2})\D(\d{1,2})\D(\d\d\d\d) (\d{1,2}):(\d|[0-5][0-9])([^\d]|$)/){ # Form input ($month, $day, $year, $hour, $min, $sec) = ($1, $2, $3, $4, $5, 0); } elsif ($input =~ /^(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/) { # ISO 8601 date ($year, $month, $day, $hour, $min, $sec) = ($1, $2, $3, $4, $5, $6); }elsif ($input =~ /^\w+\s+(\w+)\s+(\d+)\s+(\d\d):(\d\d):(\d\d)\s*\w*\s+(\d\d\d\d)$/){ #system date ($year, $month, $day, $hour, $min, $sec) = ($6, Decode_Month($1), $2, $3, $4, $5); } elsif ($input =~ /^\w+,\s+(\d+)\s+(\w+)\s+(\d{4})\s+(\d\d):(\d\d):(\d\d)\s+\w+$/) { ($year, $month, $day, $hour, $min, $sec) = ($3, Decode_Month($2), $1, $4, $5, $6); } elsif ($input =~ /^\d+$/) { # Unix date ($sec, $min, $hour, $day, $month, $year) = localtime($input); $year += 1900; $month++; } elsif ($input eq 'now') { # Moving 'now' date $self->setIsNow(TRUE); return SUCCESS; } else { return FAIL; } $self->setDate($year, $month, $day); $self->setTime($hour, $min, $sec, $ampm); $self->setIsNow(FALSE); return SUCCESS; }
sub _addYMD { my $self = shift; my $y = shift || 0; my $m = shift || 0; my $d = shift || 0; return FAIL if $self->isEmpty(); my ($year, $month, $day) = Add_Delta_YMD($self->_getYear(), $self->_getMonth(), $self->_getDay(), $y, $m, $d); return $self->setDate($year, $month, $day); } sub _addHMS { my $self = shift; my $h = shift || 0; my $m = shift || 0; my $s = shift || 0; return FAIL if $self->isEmpty(); my ($year, $month, $day, $hour, $min, $sec) = Add_Delta_DHMS($self->_getYear(), $self->_getMonth(), $self->_getDay(), $self->_getHour(), $self->_getMin(), $self->_getSec(), 0,$h,$m,$s); return $self->setTime($hour, $min, $sec); }
sub _updateToNow { my $self = shift; return SUCCESS unless $self->getIsNow(); my ($sec, $min, $hour, $day, $month, $year) = localtime(); $self->setDate($year + 1900, $month + 1, $day); $self->setTime($hour, $min, $sec); return SUCCESS; }
sub _getAccessorDefinition { return [ { name => 'IsNow', key => '_is_now', type => 'Boolean', }, { name => 'Sec', key => '_sec', type => 'Integer', private_get => TRUE, }, { name => 'Min', key => '_min', type => 'Integer', private_get => TRUE, }, { name => 'Hour', key => '_hour', type => 'Integer', private_get => TRUE, }, { name => 'Day', key => '_day', type => 'Integer', private_get => TRUE, }, { name => 'Month', key => '_month', type => 'Integer', private_get => TRUE, }, { name => 'Year', key => '_year', type => 'Integer', private_get => TRUE, }, ]; } 1; __END__