diff Lib/DateTime.pm @ 49:16ada169ca75

migrating to the Eclipse IDE
author wizard@linux-odin.local
date Fri, 26 Feb 2010 10:49:21 +0300
parents 03e58a454b20
children
line wrap: on
line diff
--- a/Lib/DateTime.pm	Fri Feb 26 01:43:42 2010 +0300
+++ b/Lib/DateTime.pm	Fri Feb 26 10:49:21 2010 +0300
@@ -1,312 +1,312 @@
-use strict;
-package DateTime::Span;
-package DateTime;
-use Common;
-use Time::Local;
-use Time::Zone;
-use Date::Format;
-our @ISA = qw(Object);
-
-use overload
-    '+' => \&opAdd,
-    '-' => \&opSubtract,
-    '<=>' => \&opCompare,
-    'bool' => \&opAsBool,
-    'fallback' => 1,
-    '""' => \&opAsString;
-
-BEGIN {
-    DeclareProperty UnixTime => ACCESS_READ;
-}
-
-sub CTOR {
-    my $this = shift;
-    
-    if (@_ >= 2) {
-        my(%args) = @_;
-        
-        $this->{$UnixTime} = $args{UnixTime} or die new Exception("A correct unix time value is required");
-    } else {
-        $this->{$UnixTime} = $this->ParseISOTime(shift,'+000');
-    }
-}
-
-sub ParseISOTime {
-    my ($class,$time,$timezone) = @_;
-    
-    if ($time =~ /^(\d{4})-(\d{2})-(\d{2})(?:.(\d{2}):(\d{2}):(\d{2})(?:\.\d{3})?)?/ ) {
-        my ($yyyy,$mm,$dd,$hh,$MM,$SS) = ($1-1900,$2-1,$3,$4 || 0,$5 || 0,$6 || 0);
-        if ($timezone) {
-            return tz_offset($timezone) + timegm($SS,$MM,$hh,$dd,$mm,$yyyy);
-        } else {
-            return timelocal($SS,$MM,$hh,$dd,$mm,$yyyy);
-        }
-    } else {
-        die new Exception("The specified string isn\'t a correct ISO date",$time);
-    }
-}
-
-sub new_ISO {
-    my ($class,$ISOTime,$zone) = @_;
-    return $class->new(UnixTime => $class->ParseISOTime($ISOTime,$zone));
-}
-
-sub now {
-    my ($class) = @_;
-    return $class->new(UnixTime => time);
-}
-
-sub AsISOString {
-    my ($this,$zone) = @_;
-    return time2str("%Y-%m-%dT%H:%M:%S",$this->{$UnixTime},$zone);
-}
-
-sub AsFormatString {
-    my ($this,$format,$zone) = @_;
-    return time2str($format,$this->{$UnixTime},$zone);
-}
-
-sub opAdd {
-    my ($a,$b,$flag) = @_;
-    
-    if (UNIVERSAL::isa($b,'DateTime::Span')) {
-        return new DateTime(UnixTime => $a->{$UnixTime} + $b->SecondsSpan);
-    } elsif (not ref $b){
-        return new DateTime(UnixTime => $a->UnixTime + $b);
-    } else {
-        die new Exception("Only a time span can be added to the DateTime object",$b);
-    }
-}
-
-sub GetDate {
-    my ($this) = @_;
-    
-    return DateTime->new_ISO($this->AsFormatString('%Y-%m-%d'));
-}
-
-sub opSubtract {
-    my ($a,$b,$flag) = @_;
-    
-    if (UNIVERSAL::isa($b,'DateTime')) {
-        return new DateTime::Span(Seconds => $a->{$UnixTime}-$b->{$UnixTime});
-    } elsif (UNIVERSAL::isa($b,'DateTime::Span')) {
-        return new DateTime(UnixTime => $flag ? $b->SecondsSpan - $a->UnixTime: $a->UnixTime - $b->SecondsSpan);
-    } elsif (not ref $b){
-        return new DateTime(UnixTime => $flag ? $b - $a->UnixTime : $a->UnixTime - $b);
-    } else {
-        die new Exception("Only an another DateTime object or a time span can be subtracted from the DateTime",$b);
-    }
-}
-
-sub opCompare {
-    my ($a,$b,$flag) = @_;
-    
-    if (UNIVERSAL::isa($b,'DateTime')) {
-        return $flag ? $b->{$UnixTime} <=> $a->{$UnixTime} : $a->{$UnixTime} <=> $b->{$UnixTime};
-    } else {
-        die new Exception("Only a DateTime object can be compared to the DateTime object", $b);
-    }
-}
-
-sub opAsString {
-    my $this = shift;
-    $this->AsISOString('+000');
-}
-
-sub opAsBool {
-    1;
-}
-
-package DateTime::Span;
-use Common;
-our @ISA = qw(Object);
-
-use overload
-    '-' => \&opSub,
-    '+' => \&opAdd,
-    '<=>' => \&opCmp,
-    'fallback' => 1;
-
-BEGIN {
-    DeclareProperty SecondsSpan=>ACCESS_READ;
-}
-
-sub CTOR {
-    my ($this,%args) = @_;
-    
-    $this->{$SecondsSpan} = ($args{'Seconds'} || 0) + ($args{'Minutes'} || 0)*60 + ($args{'Hours'} || 0)*3600 + ($args{'Days'} || 0)*86400;
-}
-
-sub Days {
-    my ($this) = @_;
-    
-    return int($this->{$SecondsSpan}/86400);
-}
-
-sub Hours {
-    my ($this) = @_;
-    
-    return int($this->{$SecondsSpan}/3600);
-}
-sub Minutes {
-    my ($this) = @_;
-    
-    return int($this->{$SecondsSpan}/60);
-}
-
-sub opAdd {
-    my ($a,$b,$flag) = @_;
-    
-    if (UNIVERSAL::isa($b,'DateTime::Span')) {
-        return new DateTime::Span(Seconds => $a->{$SecondsSpan} + $b->{$SecondsSpan});
-    } elsif (not ref $b) {
-        return new DateTime::Span(Seconds => $a->{$SecondsSpan} + $b);
-    } else {
-        die new Exception("Only a time span can be added to the time span");
-    }
-}
-
-sub opSub {
-    my ($a,$b,$flag) = @_;
-    
-    if (UNIVERSAL::isa($b,'DateTime::Span')) {
-        return new DateTime::Span(Seconds => $flag ? $b->{$SecondsSpan} - $a->{$SecondsSpan} : $a->{$SecondsSpan} - $b->{$SecondsSpan});
-    } elsif (not ref $b) {
-        return new DateTime::Span(Seconds => $flag ? $b - $a->{$SecondsSpan} : $a->{$SecondsSpan} - $b);
-    } else {
-        die new Exception("Only a time span can be subtracted from the time span");
-    }
-}
-
-sub opCmp {
-    my ($a,$b,$flag) = @_;
-    
-    if (UNIVERSAL::isa($b,'DateTime::Span')) {
-        return $flag ? $b->{$SecondsSpan} <=> $a->{$SecondsSpan} : $a->{$SecondsSpan} <=> $b->{$SecondsSpan};
-    } elsif (not ref $b) {
-    return $flag ? $b <=> $a->{$SecondsSpan} : $a->{$SecondsSpan} <=> $b;
-    } else {
-        die new Exception("Only a time span can be compared to the time span");
-    }
-}
-
-package DateTime::TimeLine;
-use Common;
-our @ISA = qw(Object);
-
-BEGIN {
-    DeclareProperty Timeline => ACCESS_READ;
-}
-
-sub CTOR {
-    my ($this) = @_;
-
-    $this->{$Timeline} = [ {Date => undef} ];
-}
-
-# рекурсивно копирует простые структуры
-sub SimpleCopy {
-    my ($refObject,$cache) = @_;
-
-    return undef if not defined $refObject;
-
-    $cache ||= {};
-
-    if ($cache->{$refObject}) {
-        return $cache->{$refObject};
-    }
-
-    local $_;
-
-    if (ref $refObject eq 'HASH' ) {
-        return ($cache->{$refObject} = { map { $_, SimpleCopy($refObject->{$_},$cache) } keys %$refObject });
-    } elsif (ref $refObject eq 'ARRAY' ) {
-        return ($cache->{$refObject} = [ map { SimpleCopy($_,$cache) } @$refObject]);
-    } else {
-        return ($cache->{$refObject} = $refObject);
-    }
-}
-
-sub Split {
-    my ($this,$date) = @_;
-
-    die new Exception('Can\'t split the timeline with an undefined date') unless $date;
-    
-    for (my $i = 0; $i < @{$this->{$Timeline}}; $i++) {
-        my $Elem = $this->{$Timeline}[$i];
-        if ($Elem->{Date} and $Elem->{Date} >= $date ) {
-            if ($Elem->{Date} == $date) {
-                return $Elem;
-            } else {
-                my $newElem = SimpleCopy($this->{$Timeline}[$i-1]);
-                $newElem->{Date} = $date;
-        use Data::Dumper;
-        
-                splice @{$this->{$Timeline}},$i,0,$newElem;
-                return $newElem;
-            }
-        }
-    }
-    my $Elem = { Date => $date };
-    push @{$this->{$Timeline}},$Elem;
-    return $Elem;
-}
-
-sub Select {
-    my ($this,$start,$end) = @_;
-
-    my @result;
-
-    for (my $i=0; $i< @{$this->{$Timeline}}; $i++) {
-        my $Elem = $this->{$Timeline}[$i];
-        my $Next = $this->{$Timeline}[$i+1];
-        if (
-            (not $Elem->{Date} or not $start or $Elem->{Date} < $start)
-            and
-            (not $Next->{Date} or not $start or $Next->{Date} > $start)
-        ) {
-            # ------*++++(++++*----...--)---
-            push @result,$Elem;
-        } elsif (
-            $Elem->{Date}
-            and
-            (not $start or $Elem->{Date} >= $start)
-            and
-            (not $end or $Elem->{Date} < $end )
-        ) {
-            # ------*---(----*++...++*++)+++*----
-            push @result,$Elem;
-        } elsif ( $Elem->{Date} and $end and $Elem->{Date} >= $end) {
-            last;
-        }
-    }
-
-    return @result;
-}
-
-sub SelectStrict {
-    my ($this,$start,$end) = @_;
-    $this->Split($start);
-    $this->Split($end);
-    return grep {
-        $_->{Date}
-        and
-        $start ? $_->{Date} >= $start : 1
-        and
-        $end ? $_->{Date} < $end : 1
-    } @{$this->{$Timeline}};
-}
-
-sub SelectAsPeriod {
-    my ($this,$start,$end) = @_;
-    
-    my @Dates = $this->Select($start,$end);
-    for (my $i = 0; $i< @Dates; $i++) {
-        $Dates[$i]->{Start} = $Dates[$i]->{Date};
-        $Dates[$i]->{End} = $Dates[$i+1] ? $Dates[$i+1]->{Date} : undef
-    }
-    
-    return @Dates;
-}
-
-1;
+use strict;
+package DateTime::Span;
+package DateTime;
+use Common;
+use Time::Local;
+use Time::Zone;
+use Date::Format;
+our @ISA = qw(Object);
+
+use overload
+    '+' => \&opAdd,
+    '-' => \&opSubtract,
+    '<=>' => \&opCompare,
+    'bool' => \&opAsBool,
+    'fallback' => 1,
+    '""' => \&opAsString;
+
+BEGIN {
+    DeclareProperty UnixTime => ACCESS_READ;
+}
+
+sub CTOR {
+    my $this = shift;
+    
+    if (@_ >= 2) {
+        my(%args) = @_;
+        
+        $this->{$UnixTime} = $args{UnixTime} or die new Exception("A correct unix time value is required");
+    } else {
+        $this->{$UnixTime} = $this->ParseISOTime(shift,'+000');
+    }
+}
+
+sub ParseISOTime {
+    my ($class,$time,$timezone) = @_;
+    
+    if ($time =~ /^(\d{4})-(\d{2})-(\d{2})(?:.(\d{2}):(\d{2}):(\d{2})(?:\.\d{3})?)?/ ) {
+        my ($yyyy,$mm,$dd,$hh,$MM,$SS) = ($1-1900,$2-1,$3,$4 || 0,$5 || 0,$6 || 0);
+        if ($timezone) {
+            return tz_offset($timezone) + timegm($SS,$MM,$hh,$dd,$mm,$yyyy);
+        } else {
+            return timelocal($SS,$MM,$hh,$dd,$mm,$yyyy);
+        }
+    } else {
+        die new Exception("The specified string isn\'t a correct ISO date",$time);
+    }
+}
+
+sub new_ISO {
+    my ($class,$ISOTime,$zone) = @_;
+    return $class->new(UnixTime => $class->ParseISOTime($ISOTime,$zone));
+}
+
+sub now {
+    my ($class) = @_;
+    return $class->new(UnixTime => time);
+}
+
+sub AsISOString {
+    my ($this,$zone) = @_;
+    return time2str("%Y-%m-%dT%H:%M:%S",$this->{$UnixTime},$zone);
+}
+
+sub AsFormatString {
+    my ($this,$format,$zone) = @_;
+    return time2str($format,$this->{$UnixTime},$zone);
+}
+
+sub opAdd {
+    my ($a,$b,$flag) = @_;
+    
+    if (UNIVERSAL::isa($b,'DateTime::Span')) {
+        return new DateTime(UnixTime => $a->{$UnixTime} + $b->SecondsSpan);
+    } elsif (not ref $b){
+        return new DateTime(UnixTime => $a->UnixTime + $b);
+    } else {
+        die new Exception("Only a time span can be added to the DateTime object",$b);
+    }
+}
+
+sub GetDate {
+    my ($this) = @_;
+    
+    return DateTime->new_ISO($this->AsFormatString('%Y-%m-%d'));
+}
+
+sub opSubtract {
+    my ($a,$b,$flag) = @_;
+    
+    if (UNIVERSAL::isa($b,'DateTime')) {
+        return new DateTime::Span(Seconds => $a->{$UnixTime}-$b->{$UnixTime});
+    } elsif (UNIVERSAL::isa($b,'DateTime::Span')) {
+        return new DateTime(UnixTime => $flag ? $b->SecondsSpan - $a->UnixTime: $a->UnixTime - $b->SecondsSpan);
+    } elsif (not ref $b){
+        return new DateTime(UnixTime => $flag ? $b - $a->UnixTime : $a->UnixTime - $b);
+    } else {
+        die new Exception("Only an another DateTime object or a time span can be subtracted from the DateTime",$b);
+    }
+}
+
+sub opCompare {
+    my ($a,$b,$flag) = @_;
+    
+    if (UNIVERSAL::isa($b,'DateTime')) {
+        return $flag ? $b->{$UnixTime} <=> $a->{$UnixTime} : $a->{$UnixTime} <=> $b->{$UnixTime};
+    } else {
+        die new Exception("Only a DateTime object can be compared to the DateTime object", $b);
+    }
+}
+
+sub opAsString {
+    my $this = shift;
+    $this->AsISOString('+000');
+}
+
+sub opAsBool {
+    1;
+}
+
+package DateTime::Span;
+use Common;
+our @ISA = qw(Object);
+
+use overload
+    '-' => \&opSub,
+    '+' => \&opAdd,
+    '<=>' => \&opCmp,
+    'fallback' => 1;
+
+BEGIN {
+    DeclareProperty SecondsSpan=>ACCESS_READ;
+}
+
+sub CTOR {
+    my ($this,%args) = @_;
+    
+    $this->{$SecondsSpan} = ($args{'Seconds'} || 0) + ($args{'Minutes'} || 0)*60 + ($args{'Hours'} || 0)*3600 + ($args{'Days'} || 0)*86400;
+}
+
+sub Days {
+    my ($this) = @_;
+    
+    return int($this->{$SecondsSpan}/86400);
+}
+
+sub Hours {
+    my ($this) = @_;
+    
+    return int($this->{$SecondsSpan}/3600);
+}
+sub Minutes {
+    my ($this) = @_;
+    
+    return int($this->{$SecondsSpan}/60);
+}
+
+sub opAdd {
+    my ($a,$b,$flag) = @_;
+    
+    if (UNIVERSAL::isa($b,'DateTime::Span')) {
+        return new DateTime::Span(Seconds => $a->{$SecondsSpan} + $b->{$SecondsSpan});
+    } elsif (not ref $b) {
+        return new DateTime::Span(Seconds => $a->{$SecondsSpan} + $b);
+    } else {
+        die new Exception("Only a time span can be added to the time span");
+    }
+}
+
+sub opSub {
+    my ($a,$b,$flag) = @_;
+    
+    if (UNIVERSAL::isa($b,'DateTime::Span')) {
+        return new DateTime::Span(Seconds => $flag ? $b->{$SecondsSpan} - $a->{$SecondsSpan} : $a->{$SecondsSpan} - $b->{$SecondsSpan});
+    } elsif (not ref $b) {
+        return new DateTime::Span(Seconds => $flag ? $b - $a->{$SecondsSpan} : $a->{$SecondsSpan} - $b);
+    } else {
+        die new Exception("Only a time span can be subtracted from the time span");
+    }
+}
+
+sub opCmp {
+    my ($a,$b,$flag) = @_;
+    
+    if (UNIVERSAL::isa($b,'DateTime::Span')) {
+        return $flag ? $b->{$SecondsSpan} <=> $a->{$SecondsSpan} : $a->{$SecondsSpan} <=> $b->{$SecondsSpan};
+    } elsif (not ref $b) {
+    return $flag ? $b <=> $a->{$SecondsSpan} : $a->{$SecondsSpan} <=> $b;
+    } else {
+        die new Exception("Only a time span can be compared to the time span");
+    }
+}
+
+package DateTime::TimeLine;
+use Common;
+our @ISA = qw(Object);
+
+BEGIN {
+    DeclareProperty Timeline => ACCESS_READ;
+}
+
+sub CTOR {
+    my ($this) = @_;
+
+    $this->{$Timeline} = [ {Date => undef} ];
+}
+
+# рекурсивно копирует простые структуры
+sub SimpleCopy {
+    my ($refObject,$cache) = @_;
+
+    return undef if not defined $refObject;
+
+    $cache ||= {};
+
+    if ($cache->{$refObject}) {
+        return $cache->{$refObject};
+    }
+
+    local $_;
+
+    if (ref $refObject eq 'HASH' ) {
+        return ($cache->{$refObject} = { map { $_, SimpleCopy($refObject->{$_},$cache) } keys %$refObject });
+    } elsif (ref $refObject eq 'ARRAY' ) {
+        return ($cache->{$refObject} = [ map { SimpleCopy($_,$cache) } @$refObject]);
+    } else {
+        return ($cache->{$refObject} = $refObject);
+    }
+}
+
+sub Split {
+    my ($this,$date) = @_;
+
+    die new Exception('Can\'t split the timeline with an undefined date') unless $date;
+    
+    for (my $i = 0; $i < @{$this->{$Timeline}}; $i++) {
+        my $Elem = $this->{$Timeline}[$i];
+        if ($Elem->{Date} and $Elem->{Date} >= $date ) {
+            if ($Elem->{Date} == $date) {
+                return $Elem;
+            } else {
+                my $newElem = SimpleCopy($this->{$Timeline}[$i-1]);
+                $newElem->{Date} = $date;
+        use Data::Dumper;
+        
+                splice @{$this->{$Timeline}},$i,0,$newElem;
+                return $newElem;
+            }
+        }
+    }
+    my $Elem = { Date => $date };
+    push @{$this->{$Timeline}},$Elem;
+    return $Elem;
+}
+
+sub Select {
+    my ($this,$start,$end) = @_;
+
+    my @result;
+
+    for (my $i=0; $i< @{$this->{$Timeline}}; $i++) {
+        my $Elem = $this->{$Timeline}[$i];
+        my $Next = $this->{$Timeline}[$i+1];
+        if (
+            (not $Elem->{Date} or not $start or $Elem->{Date} < $start)
+            and
+            (not $Next->{Date} or not $start or $Next->{Date} > $start)
+        ) {
+            # ------*++++(++++*----...--)---
+            push @result,$Elem;
+        } elsif (
+            $Elem->{Date}
+            and
+            (not $start or $Elem->{Date} >= $start)
+            and
+            (not $end or $Elem->{Date} < $end )
+        ) {
+            # ------*---(----*++...++*++)+++*----
+            push @result,$Elem;
+        } elsif ( $Elem->{Date} and $end and $Elem->{Date} >= $end) {
+            last;
+        }
+    }
+
+    return @result;
+}
+
+sub SelectStrict {
+    my ($this,$start,$end) = @_;
+    $this->Split($start);
+    $this->Split($end);
+    return grep {
+        $_->{Date}
+        and
+        $start ? $_->{Date} >= $start : 1
+        and
+        $end ? $_->{Date} < $end : 1
+    } @{$this->{$Timeline}};
+}
+
+sub SelectAsPeriod {
+    my ($this,$start,$end) = @_;
+    
+    my @Dates = $this->Select($start,$end);
+    for (my $i = 0; $i< @Dates; $i++) {
+        $Dates[$i]->{Start} = $Dates[$i]->{Date};
+        $Dates[$i]->{End} = $Dates[$i+1] ? $Dates[$i+1]->{Date} : undef
+    }
+    
+    return @Dates;
+}
+
+1;