[Rt-commit] r3951 - in rt/branches/3.7-EXPERIMENTAL: . etc lib/RT lib/t/regression

ruz at bestpractical.com ruz at bestpractical.com
Wed Oct 12 08:51:52 EDT 2005


Author: ruz
Date: Wed Oct 12 08:51:50 2005
New Revision: 3951

Added:
   rt/branches/3.7-EXPERIMENTAL/lib/t/regression/09-api-date.t
Modified:
   rt/branches/3.7-EXPERIMENTAL/   (props changed)
   rt/branches/3.7-EXPERIMENTAL/etc/RT_Config.pm.in
   rt/branches/3.7-EXPERIMENTAL/lib/RT/Date.pm
Log:
 r1133 at cubic-pc:  cubic | 2005-10-12 16:52:37 +0400
  r1131 at cubic-pc:  cubic | 2005-10-12 16:47:04 +0400
  RT:Date rewrite
  Changes:
  * new config option $DateTimeFormat
  * @MONTHS and @DAYS_OF_WEEK arrays
  * class support different output formats
  * new Get method
  * DateTime, Date and Time methods support formats
  * new Localtime method for basic timezones support
  * LocalTimezone renamed into Timezone
  * Timezone method could return different timezones
  ** UTC
  ** timezone of the RT server($RT::Timezone)
  ** the timezone setting of the current user
  * +75 tests of the RT::Date API
  
 


Modified: rt/branches/3.7-EXPERIMENTAL/etc/RT_Config.pm.in
==============================================================================
--- rt/branches/3.7-EXPERIMENTAL/etc/RT_Config.pm.in	(original)
+++ rt/branches/3.7-EXPERIMENTAL/etc/RT_Config.pm.in	Wed Oct 12 08:51:50 2005
@@ -469,8 +469,18 @@
 
 # }}}
 
-# {{{ RT Date Handling Options (for Time::ParseDate)
+# {{{ RT Date Handling Options
 
+# You can choose date and time format.
+# See "Output formatters" section in perldoc lib/RT/Date.pm
+# for more options.
+# Some examples:
+#Set($DateTimeFormat, { Fromat => 'ISO', Seconds => 0 });
+#Set($DateTimeFormat, 'RFC2822');
+#Set($DateTimeFormat, { Format => 'RFC2822', Seconds => 0, DayOfWeek => 0 });
+Set($DateTimeFormat, 'DefaultFormat');
+
+# Next two options are for Time::ParseDate
 # Set this to 1 if your local date convention looks like "dd/mm/yy"
 # instead of "mm/dd/yy".
 

Modified: rt/branches/3.7-EXPERIMENTAL/lib/RT/Date.pm
==============================================================================
--- rt/branches/3.7-EXPERIMENTAL/lib/RT/Date.pm	(original)
+++ rt/branches/3.7-EXPERIMENTAL/lib/RT/Date.pm	Wed Oct 12 08:51:50 2005
@@ -76,8 +76,8 @@
 use RT::Base;
 
 use strict;
-use vars qw/@ISA/;
- at ISA = qw/RT::Base/;
+use warnings;
+use base qw/RT::Base/;
 
 use vars qw($MINUTE $HOUR $DAY $WEEK $MONTH $YEAR);
 
@@ -88,25 +88,56 @@
 $MONTH  = 4 * $WEEK;
 $YEAR   = 365 * $DAY;
 
-# {{{ sub new 
+our @MONTHS = qw(
+    Jan
+    Feb
+    Mar
+    Apr
+    May
+    Jun
+    Jul
+    Aug
+    Sep
+    Oct
+    Nov
+    Dec
+);
+
+our @DAYS_OF_WEEK = qw(
+    Sun
+    Mon
+    Tue
+    Wed
+    Thu
+    Fri
+    Sat
+);
+
+# {{{ sub new
+
+=head2 new
+
+Object constructor takes one argument C<RT::CurrentUser> object.
 
-sub new  {
-  my $proto = shift;
-  my $class = ref($proto) || $proto;
-  my $self  = {};
-  bless ($self, $class);
-  $self->CurrentUser(@_);
-  $self->Unix(0);
-  return $self;
+=cut
+
+sub new {
+    my $proto = shift;
+    my $class = ref($proto) || $proto;
+    my $self  = {};
+    bless ($self, $class);
+    $self->CurrentUser(@_);
+    $self->Unix(0);
+    return $self;
 }
 
 # }}}
 
 # {{{ sub Set
 
-=head2 sub Set
+=head2 Set
 
-takes a param hash with the fields 'Format' and 'Value'
+Takes a param hash with the fields 'Format' and 'Value'
 
 if $args->{'Format'} is 'unix', takes the number of seconds since the epoch 
 
@@ -146,7 +177,7 @@
     }
 
     elsif ( $args{'Format'} =~ /^(sql|datemanip|iso)$/i ) {
-	$args{'Value'} =~ s!/!-!g;
+        $args{'Value'} =~ s!/!-!g;
 
         if (( $args{'Value'} =~ /^(\d{4}?)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/ )
             || ( $args{'Value'} =~
@@ -201,10 +232,10 @@
 
         #Convert it to an ISO format string
 
-	my $date = Time::ParseDate::parsedate($args{'Value'},
-			UK => $RT::DateDayBeforeMonth,
-			PREFER_PAST => $RT::AmbiguousDayInPast,
-			PREFER_FUTURE => !($RT::AmbiguousDayInPast));
+        my $date = Time::ParseDate::parsedate($args{'Value'},
+                        UK => $RT::DateDayBeforeMonth,
+                        PREFER_PAST => $RT::AmbiguousDayInPast,
+                        PREFER_FUTURE => !($RT::AmbiguousDayInPast));
 
         #This date has now been set to a date in the _local_ timezone.
         #since ISO dates are known to be in GMT (for RT's purposes);
@@ -236,13 +267,10 @@
 sub SetToMidnight {
     my $self = shift;
     
-    use Time::Local;
     my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = gmtime($self->Unix);
     $self->Unix(timegm (0,0,0,$mday,$mon,$year,$wday,$yday));
     
     return ($self->Unix);
-    
-    
 }
 
 
@@ -250,8 +278,8 @@
 
 # {{{ sub SetToNow
 sub SetToNow {
-	my $self = shift;
-	return($self->Set(Format => 'unix', Value => time))
+        my $self = shift;
+        return($self->Set(Format => 'unix', Value => time))
 }
 # }}}
 
@@ -269,8 +297,8 @@
     my $self = shift;
     my $other = shift;
 
-    if (ref($other) eq 'RT::Date') {
-	$other=$other->Unix;
+    if (UNIVERSAL::isa($other => 'RT::Date')) {
+        $other=$other->Unix;
     }
     return ($self->Unix - $other);
 }
@@ -278,7 +306,7 @@
 
 # {{{ sub DiffAsString
 
-=head2 sub DiffAsString
+=head2 DiffAsString
 
 Takes either an RT::Date object or the date in unixtime format as a string
 
@@ -293,10 +321,10 @@
 
 
     if ($other < 1) {
-	return ("");
+        return ("");
     }
     if ($self->Unix < 1) {
-	return("");
+        return("");
     }
     my $diff = $self->Diff($other);
 
@@ -366,7 +394,7 @@
 
 # {{{ sub AgeAsString
 
-=head2 sub AgeAsString
+=head2 AgeAsString
 
 Takes nothing
 
@@ -377,25 +405,30 @@
 sub AgeAsString {
     my $self = shift;
     return ($self->DiffAsString(time));
-    }
+}
 # }}}
 
 # {{{ sub AsString
 
-=head2 sub AsString
+=head2 AsString
 
-Returns the object\'s time as a string with the current timezone.
+Returns the object's time as a string with the current timezone.
 
 =cut
 
 sub AsString {
     my $self = shift;
+
     return ($self->loc("Not set")) if ($self->Unix <= 0);
 
-    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($self->Unix);
+    my %args = (@_);
+    my $format = $RT::DateTimeFormat || 'DefaultFormat';
+    $format = { Format => $format } unless ref $format;
+    %args = (%$format, %args);
 
-    return $self->loc("[_1] [_2] [_3] [_4]:[_5]:[_6] [_7]", $self->GetWeekday($wday), $self->GetMonth($mon), map {sprintf "%02d", $_} ($mday, $hour, $min, $sec), ($year+1900));
+    return $self->Get( Timezone => 'user', %args );
 }
+
 # }}}
 
 # {{{ GetWeekday
@@ -410,13 +443,8 @@
     my $self = shift;
     my $dow = shift;
     
-    return $self->loc('Mon.') if ($dow == 1);
-    return $self->loc('Tue.') if ($dow == 2);
-    return $self->loc('Wed.') if ($dow == 3);
-    return $self->loc('Thu.') if ($dow == 4);
-    return $self->loc('Fri.') if ($dow == 5);
-    return $self->loc('Sat.') if ($dow == 6);
-    return $self->loc('Sun.') if ($dow == 0);
+    return $self->loc("$DAYS_OF_WEEK[$dow].") if $DAYS_OF_WEEK[$dow];
+    return '';
 }
 
 # }}}
@@ -431,28 +459,17 @@
 
 sub GetMonth {
     my $self = shift;
-   my $mon = shift;
+    my $mon = shift;
 
-    # We do this rather than an array so that we don't call localize 12x what we need to
-    return $self->loc('Jan.') if ($mon == 0);
-    return $self->loc('Feb.') if ($mon == 1);
-    return $self->loc('Mar.') if ($mon == 2);
-    return $self->loc('Apr.') if ($mon == 3);
-    return $self->loc('May.') if ($mon == 4);
-    return $self->loc('Jun.') if ($mon == 5);
-    return $self->loc('Jul.') if ($mon == 6);
-    return $self->loc('Aug.') if ($mon == 7);
-    return $self->loc('Sep.') if ($mon == 8);
-    return $self->loc('Oct.') if ($mon == 9);
-    return $self->loc('Nov.') if ($mon == 10);
-    return $self->loc('Dec.') if ($mon == 11);
+    return $self->loc("$MONTHS[$mon].") if $MONTHS[$mon];
+    return '';
 }
 
 # }}}
 
 # {{{ sub AddSeconds
 
-=head2 sub AddSeconds
+=head2 AddSeconds
 
 Takes a number of seconds as a string
 
@@ -508,7 +525,7 @@
 
 # {{{ sub Unix
 
-=head2 sub Unix [unixtime]
+=head2 Unix [unixtime]
 
 Optionally takes a date in unix seconds since the epoch format.
 Returns the number of seconds since the epoch
@@ -518,58 +535,35 @@
 sub Unix {
     my $self = shift;
     
-    $self->{'time'} = shift if (@_);
+    $self->{'time'} = (shift || 0) if (@_);
     
     return ($self->{'time'});
 }
 # }}}
 
-# {{{ sub ISO
-
-=head2 ISO
-
-Takes nothing
-
-Returns the object's date in ISO format
+=head2 DateTime
 
 =cut
 
-sub ISO {
-    my $self=shift;
-    my    ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst, $date) ;
-    
-    return ('1970-01-01 00:00:00') if ($self->Unix == -1);
-
-    #  0    1    2     3     4    5     6     7     8
-    ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime($self->Unix);
-    #make the year YYYY
-    $year+=1900;
-
-    #the month needs incrementing, as gmtime returns 0-11
-    $mon++;
-        
-    $date = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year,$mon,$mday, $hour,$min,$sec);
-    
-    return ($date);
+sub DateTime {
+    my $self = shift;
+    return $self->Get( @_, Date => 1, Time => 1 );
 }
 
-# }}}
-
 # {{{ sub Date
 
 =head2 Date
 
-Takes nothing
+Takes Format argument which allows you choose date formatter.
+Pass throught other arguments to the formatter method.
 
-Returns the object's date in yyyy-mm-dd format; this is the same as
-the ISO format without the time
+Returns the object's formatted date. Default formatter is ISO.
 
 =cut
 
 sub Date {
     my $self = shift;
-    my ($date, $time) = split ' ', $self->ISO;
-    return $date;
+    return $self->Get( @_, Date => 1, Time => 0 );
 }
 
 # }}}}
@@ -587,47 +581,227 @@
 
 sub Time {
     my $self = shift;
-    my ($date, $time) = split ' ', $self->ISO;
-    return $time;
+    return $self->Get( @_, Date => 0, Time => 1 );
 }
 
 # }}}}
 
-# {{{ sub W3CDTF
+sub Get
+{
+    my $self = shift;
+    my %args = (@_);
+    my $formatter = delete($args{'Format'}) || 'ISO';
+    $formatter = 'ISO' unless $self->can($formatter);
+    no strict 'refs';
+    return $self->$formatter( %args );
+}
 
-=head2 W3CDTF
+=head2 Output formatters
 
-Takes nothing
+Fomatter is a method that returns date and time in different configurable
+format.
+Each method takes several arguments:
+
+=over 1
+
+=item Date
+
+=item Time
+
+=item Timezone - Timezone context C<server>, C<user> or C<UTC>
+
+=back
 
-Returns the object's date in W3C DTF format
+Formatters may also add own arguments to the list, for example
+in RFC2822 format day of time in output is optional so it
+understand argument C<DayOfTime>.
+
+=head3 DefaultFormat
+
+=cut
+
+sub DefaultFormat
+{
+    my $self = shift;
+    my %args = ( Date => 1,
+                 Time => 1,
+                 Timezone => '',
+                 @_,
+               );
+    
+       #  0    1    2     3     4    5     6     7      8      9
+    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$ydaym,$isdst,$offset) =
+                            $self->Localtime($args{'Timezone'});
+    $wday = $self->GetWeekday($wday);
+    $mon = $self->GetMonth($mon);
+    ($mday, $hour, $min, $sec) = map { sprintf "%02d", $_ } ($mday, $hour, $min, $sec);
+
+    if(!$args{'Date'} && !$args{'Time'}) {
+        return '';
+    } elsif($args{'Date'} && $args{'Time'}) {
+        return $self->loc('[_1] [_2] [_3] [_4]:[_5]:[_6] [_7]',
+                          $wday,$mon,$mday,$hour,$min,$sec,$year);
+    } elsif($args{'Date'}) {
+        return $self->loc('[_1] [_2] [_3] [_4]',
+                          $wday,$mon,$mday,$year);
+    } else {
+        return $self->loc('[_1]:[_2]:[_3]',
+                          $hour,$min,$sec);
+    }
+}
+
+=head3 ISO
+
+Returns the object's date in ISO format
+Takes additional argument C<Seconds>.
+ISO format has no locale dependant elements so method
+ignore argument C<Localize>.
+
+=cut
+
+sub ISO {
+    my $self = shift;
+    my %args = ( Date => 1,
+                 Time => 1,
+                 Timezone => '',
+                 Seconds => 1,
+                 @_,
+               );
+       #  0    1    2     3     4    5     6     7      8      9
+    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$ydaym,$isdst,$offset) =
+                            $self->Localtime($args{'Timezone'});
+
+    #the month needs incrementing, as gmtime returns 0-11
+    $mon++;
+    
+    my $res = '';
+    $res .= sprintf("%04d-%02d-%02d", $year, $mon, $mday) if $args{'Date'};
+    $res .= sprintf(' %02d:%02d', $hour, $min) if $args{'Time'};
+    $res .= sprintf(':%02d', $sec, $min) if $args{'Time'} && $args{'Seconds'};
+    $res =~ s/^\s+//;
+    
+    return $res;
+}
+
+=head3 W3CDTF
+
+Returns the object's date and time in W3C DTF format
 
 =cut
 
 sub W3CDTF {
     my $self = shift;
-    my $date = $self->ISO . 'Z';
+    my %args = ( Time => 1,
+                 @_,
+               );
+    my $date = $self->ISO(%args);
+    $date .= 'Z' if $args{'Time'};
     $date =~ s/ /T/;
     return $date;
 };
 
+
+=head3 RFC2822
+
+Returns the object's date and time in RFC2822 format
+
+=cut
+
+sub RFC2822 {
+    my $self = shift;
+    my %args = ( Date => 1,
+                 Time => 1,
+                 Timezone => '',
+                 DayOfWeek => 1,
+                 Seconds => 1,
+                 @_,
+               );
+
+    # XXX: Don't know how to get timezone shift by timezone name
+       #  0    1    2     3     4    5     6     7      8     9
+    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$ydaym,$isdst,$offset) =
+                            $self->Localtime($args{'Timezone'});
+
+    my ($date, $time) = ('','');
+    $date .= "$DAYS_OF_WEEK[$wday], " if $args{'DayOfWeek'} && $args{'Date'};
+    $date .= "$mday $MONTHS[$mon] $year" if $args{'Date'};
+    
+    $time .= sprintf("%02d:%02d", $hour, $min) if $args{'Time'};
+    $time .= sprintf(":%02d", $sec) if $args{'Time'} && $args{'Seconds'};
+    if( $args{'Time'} ) {
+        my $sign = $offset<0? '-': '+';
+        $offset = abs $offset;
+        $offset = int($offset/60);
+        my $offset_mins = $offset % 60;
+        my $offset_hours = int($offset/60);
+        $time .= sprintf(" $sign%02d%02d", $offset_hours, $offset_mins);
+    }
+    
+    return join ' ', grep $_, ($date, $time);
+}
+
+=head2 Timezones handling
+
+=head3 Localtime
+
+Takes one argument C<$context>, see Timezone method.
+
+Returns object's date and time in format perl builtin function C<localtime>
+returns with two exceptions:
+
+1) year is always in full specification, it is not offset against 1900.
+
+2) returns additional element C<offset> which represent timezone offset
+against C<UTC> in seconds.
+
+=cut
+
+sub Localtime
+{
+    my $self = shift;
+    my $tz = $self->Timezone(shift);
+
+    my $unix = $self->Unix;
+    $unix = 0 if $unix < 0;
+    
+    local $ENV{'TZ'} = $tz;
+    my @local = localtime($unix);
+    $local[5] += 1900; # change year to 4+ digits format
+    my $offset = Time::Local::timegm_nocheck(@local) - $unix;
+    return @local, $offset;
+}
+
+
 # }}}
 
-# {{{ sub LocalTimezone 
+# {{{ sub Timezone
 
-=head2 LocalTimezone
+=head3 Timezone
 
-  Returns the current timezone. For now, draws off a system timezone, RT::Timezone. Eventually, this may
-pull from a 'Timezone' attribute of the CurrentUser
+Returns the timezone name.
+
+Takes C<$context> argument which could be either C<user>, C<server> or C<UTC>.
+Default value is C<user> that mean it returns current user's Timezone value.
+If context is C<server> it returns value of the <$Timezone> RT config option.
+If both server's and user's timezone names are undefined returns 'UTC'.
 
 =cut
 
-sub LocalTimezone {
+sub Timezone {
     my $self = shift;
+    my $context = lc(shift || 'utc');
+    $context = 'utc' unless $context =~ /^(?:utc|server|user)$/;
 
-    return $self->CurrentUser->Timezone
-	if $self->CurrentUser and $self->CurrentUser->can('Timezone');
+    my $tz;
+    if( $context eq 'user' ) {
+        $tz = $self->CurrentUser->UserObj->Timezone;
+    } elsif( $context eq 'server') {
+        $tz = $RT::Timezone;
+    } else {
+        $tz = 'UTC';
+    }
 
-    return ($RT::Timezone);
+    return ($tz || $RT::Timezone || 'UTC');
 }
 
 # }}}

Added: rt/branches/3.7-EXPERIMENTAL/lib/t/regression/09-api-date.t
==============================================================================
--- (empty file)
+++ rt/branches/3.7-EXPERIMENTAL/lib/t/regression/09-api-date.t	Wed Oct 12 08:51:50 2005
@@ -0,0 +1,299 @@
+#!/usr/bin/perl
+
+use Test::More qw/no_plan/;
+#use Test::More tests => 25;
+
+use warnings; use strict;
+use RT;
+RT::LoadConfig();
+RT::Init();
+
+use RT::User;
+
+use_ok('RT::Date', "loaded RT::Date");
+{
+    my $date = RT::Date->new($RT::SystemUser);
+    isa_ok($date, 'RT::Date', "constructor returned RT::Date oject");
+}
+
+{
+    # set timezone in all places to UTC
+    $RT::SystemUser->UserObj->__Set(Field => 'Timezone', Value => 'UTC')
+                                if $RT::SystemUser->UserObj->Timezone;
+    $RT::Timezone = 'UTC';
+}
+
+{
+    my $user = RT::User->new($RT::SystemUser);
+    my($uid, $msg) = $user->Create( Name => "date_api" . rand(200),
+                                   Privileged => 1,
+                                 );
+    ok($uid, "user was created") or diag("error: $msg");
+    my $current_user = new RT::CurrentUser($user);
+
+    my $date = RT::Date->new($current_user);
+    is($date->Timezone, 'UTC', "dropped all timzones to UTC");
+    is($date->Timezone('user'), 'UTC', "dropped all timzones to UTC");
+    is($date->Timezone('server'), 'UTC', "dropped all timzones to UTC");
+
+    is($date->Timezone('unknown'), 'UTC', "with wrong context returns UTC");
+
+    $current_user->UserObj->__Set( Field => 'Timezone', Value => 'Europe/Moscow');
+    is($current_user->UserObj->Timezone,
+       'Europe/Moscow',
+       "successfuly changed user's timezone");
+    is($date->Timezone('user'),
+       'Europe/Moscow',
+       "in user context returns user's timezone");
+    is($date->Timezone, 'UTC', "the deafult value is always UTC");
+    is($date->Timezone('server'), 'UTC', "wasn't changed");
+
+    $RT::Timezone = 'Africa/Ouagadougou';
+    is($date->Timezone('server'),
+       'Africa/Ouagadougou',
+       "timezone of the RT server was changed");
+    is($date->Timezone('user'),
+       'Europe/Moscow',
+       "in user context still returns user's timezone");
+    is($date->Timezone, 'UTC', "the deafult value is always UTC");
+    
+    $current_user->UserObj->__Set( Field => 'Timezone', Value => '');
+    is($current_user->UserObj->Timezone,
+       '',
+       "successfuly changed user's timezone");
+    is($date->Timezone('user'),
+       'Africa/Ouagadougou',
+       "in user context returns timezone of the server if user's one is not defined");
+    is($date->Timezone, 'UTC', "the deafult value is always UTC");
+
+    $RT::Timezone = '';
+    is($date->Timezone, 'UTC', "dropped all timzones to UTC");
+    is($date->Timezone('user'),
+       'UTC',
+       "user's and server's timzones are not defined, so UTC");
+    is($date->Timezone('server'),
+       'UTC',
+       "timezone of the server is not defined so UTC");
+
+    $RT::Timezone = 'UTC';
+}
+
+{
+    my $date = RT::Date->new($RT::SystemUser);
+    is($date->Unix, 0, "new date returns 0 in Unix format");
+    is($date->Get, '1970-01-01 00:00:00', "default is ISO format");
+    is($date->Get(Format =>'SomeBadFormat'),
+       '1970-01-01 00:00:00',
+       "don't know format, return ISO format");
+    is($date->Get(Format =>'W3CDTF'),
+       '1970-01-01T00:00:00Z',
+       "W3CDTF format with defaults");
+    is($date->Get(Format =>'RFC2822'),
+       'Thu, 1 Jan 1970 00:00:00 +0000',
+       "RFC2822 format with defaults");
+
+    is($date->ISO(Time => 0),
+       '1970-01-01',
+       "ISO format without time part");
+    is($date->W3CDTF(Time => 0),
+       '1970-01-01',
+       "W3CDTF format without time part");
+    is($date->RFC2822(Time => 0),
+       'Thu, 1 Jan 1970',
+       "RFC2822 format without time part");
+
+    is($date->ISO(Date => 0),
+       '00:00:00',
+       "ISO format without date part");
+    is($date->W3CDTF(Date => 0),
+       '00:00:00Z',
+       "W3CDTF format without date part");
+    is($date->RFC2822(Date => 0),
+       '00:00:00 +0000',
+       "RFC2822 format without date part");
+
+    is($date->ISO(Date => 0, Seconds => 0),
+       '00:00',
+       "ISO format without date part and seconds");
+    is($date->W3CDTF(Date => 0, Seconds => 0),
+       '00:00Z',
+       "W3CDTF format without date part and seconds");
+    is($date->RFC2822(Date => 0, Seconds => 0),
+       '00:00 +0000',
+       "RFC2822 format without date part and seconds");
+
+    is($date->RFC2822(DayOfWeek => 0),
+       '1 Jan 1970 00:00:00 +0000',
+       "RFC2822 format without 'day of week' part");
+    is($date->RFC2822(DayOfWeek => 0, Date => 0),
+       '00:00:00 +0000',
+       "RFC2822 format without 'day of week' and date parts(corner case test)");
+
+    is($date->Date,
+       '1970-01-01',
+       "the default format for the 'Date' method is ISO");
+    is($date->Date(Format => 'W3CDTF'),
+       '1970-01-01',
+       "'Date' method, W3CDTF format");
+    is($date->Date(Format => 'RFC2822'),
+       'Thu, 1 Jan 1970',
+       "'Date' method, RFC2822 format");
+    is($date->Date(Time => 1),
+       '1970-01-01',
+       "'Date' method doesn't pass through 'Time' argument");
+    is($date->Date(Date => 0),
+       '1970-01-01',
+       "'Date' method overrides 'Date' argument");
+
+    is($date->Time,
+       '00:00:00',
+       "the default format for the 'Time' method is ISO");
+    is($date->Time(Format => 'W3CDTF'),
+       '00:00:00Z',
+       "'Time' method, W3CDTF format");
+    is($date->Time(Format => 'RFC2822'),
+       '00:00:00 +0000',
+       "'Time' method, RFC2822 format");
+    is($date->Time(Date => 1),
+       '00:00:00',
+       "'Time' method doesn't pass through 'Date' argument");
+    is($date->Time(Time => 0),
+       '00:00:00',
+       "'Time' method overrides 'Time' argument");
+
+    is($date->DateTime,
+       '1970-01-01 00:00:00',
+       "the default format for the 'DateTime' method is ISO");
+    is($date->DateTime(Format =>'W3CDTF'),
+       '1970-01-01T00:00:00Z',
+       "'DateTime' method, W3CDTF format");
+    is($date->DateTime(Format =>'RFC2822'),
+       'Thu, 1 Jan 1970 00:00:00 +0000',
+       "'DateTime' method, RFC2822 format");
+    is($date->DateTime(Date => 0, Time => 0),
+       '1970-01-01 00:00:00',
+       "the 'DateTime' method overrides both 'Date' and 'Time' arguments");
+}
+
+{
+    # setting value via Unix method
+    my $date = RT::Date->new($RT::SystemUser);
+    $date->Unix(1);
+    is($date->ISO, '1970-01-01 00:00:01', "set value new value");
+
+    # TODO: other Set* methods
+}
+
+{
+    my $date = RT::Date->new($RT::SystemUser);
+    
+    $date->Unix(0);
+    $date->AddSeconds;
+    is($date->ISO, '1970-01-01 00:00:00', "nothing changed");
+    $date->AddSeconds(0);
+    is($date->ISO, '1970-01-01 00:00:00', "nothing changed");
+    
+    $date->Unix(0);
+    $date->AddSeconds(5);
+    is($date->ISO, '1970-01-01 00:00:05', "added five seconds");
+    $date->AddSeconds(-2);
+    is($date->ISO, '1970-01-01 00:00:03', "substracted two seconds");
+    
+    $date->Unix(0);
+    $date->AddSeconds(3661);
+    is($date->ISO, '1970-01-01 01:01:01', "added one hour, minute and a second");
+
+    TODO: {
+        local $TODO = "BUG or subject to change Date handling to support unix time <= 0";
+        $date->Unix(0);
+        $date->AddSeconds(-2);
+        ok($date->Unix > 0);
+    }
+
+    $date->Unix(0);
+    $date->AddDay;
+    is($date->ISO, '1970-01-02 00:00:00', "added one day");
+    $date->AddDays(2);
+    is($date->ISO, '1970-01-04 00:00:00', "added two days");
+    $date->AddDays(-1);
+    is($date->ISO, '1970-01-03 00:00:00', "substructed one day");
+    
+    $date->Unix(0);
+    $date->AddDays(31);
+    is($date->ISO, '1970-02-01 00:00:00', "added one month");
+}
+
+{
+    my $date = RT::Date->new($RT::SystemUser);
+
+    my $unix = 1129084200; # 2005-10-12 02:30:00 UTC
+    my $iso  = "2005-10-12 02:30:00";
+    $date->Unix($unix);
+    is($date->ISO, $iso, "correct date and time");
+
+    $date->SetToMidnight;
+    is($date->ISO, '2005-10-12 00:00:00', "correct midnight date and time");
+    TODO: {
+        local $TODO = "'SetToMidnight' method should support 'Timezone' argumnet";
+        my $user = RT::User->new($RT::SystemUser);
+        my($uid, $msg) = $user->Create( Name => "date_api" . rand(200),
+                                        Timezone => 'Europe/Moscow',
+                                        Privileged => 1,
+                                      );
+        ok($uid, "user was created") or diag("error: $msg");
+        my $current_user = new RT::CurrentUser($user);
+        is($current_user->UserObj->Timezone,
+           'Europe/Moscow',
+           "user has own timezone");
+        
+        my $date = RT::Date->new($current_user);
+
+        $date->Unix($unix);
+        is($date->ISO, $iso, "correct date and time");
+
+        $date->SetToMidnight( Timezone => 'user' );
+        is($date->ISO, '2005-10-11 20:00:00', "correct midnight date and time");
+    }
+}
+
+{
+    my $user = RT::User->new($RT::SystemUser);
+    my($uid, $msg) = $user->Create( Name => "date_api" . rand(200),
+                                    Lang => 'en',
+                                    Privileged => 1,
+                                  );
+    ok($uid, "user was created") or diag("error: $msg");
+    my $current_user = new RT::CurrentUser($user);
+
+    my $date = RT::Date->new($current_user);
+    is($date->AsString, "Not set", "AsString returns 'Not set'");
+
+    $RT::DateTimeFormat = '';
+    $date->Unix(1);
+    is($date->AsString, 'Thu Jan 01 00:00:01 1970', "correct string");
+    is($date->AsString(Date => 0), '00:00:01', "correct string");
+    is($date->AsString(Time => 0), 'Thu Jan 01 1970', "correct string");
+    
+    $RT::DateTimeFormat = 'RFC2822';
+    $date->Unix(1);
+    is($date->AsString, 'Thu, 1 Jan 1970 00:00:01 +0000', "correct string");
+
+    $RT::DateTimeFormat = { Format => 'RFC2822', Seconds => 0 };
+    $date->Unix(1);
+    is($date->AsString, 'Thu, 1 Jan 1970 00:00 +0000', "correct string");
+    is($date->AsString(Seconds => 1), 'Thu, 1 Jan 1970 00:00:01 +0000', "correct string");
+}
+
+#TODO: Set
+#TODO: SetToNow
+#TODO: Diff
+#TODO: DiffAsString
+#TODO: DurationAsString
+#TODO: AgeAsString
+#TODO: AsString
+#TODO: GetWeekday
+#TODO: GetMonth
+#TODO: RFC2822 with Timezones
+
+exit(0);
+


More information about the Rt-commit mailing list