The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Panda::Date::Rel - Relative date object.

DESCRIPTION

Relative date is a period of time not bound to any particular point in time and is used for date calculations. Reldate consists of 6 units - seconds, minutes, hours, days, months and years. Some units convert to another inaccurate.

CLASS METHODS

new([$rel_string | $seconds | \@rel_array | \%rel_hash | $reldate])

Creates a date object using one of these source data types:

123456 or "123456"

Treated as a number of seconds

[$year, $month, $day, $hour, $min, $sec]

Missing elements are considered = 0.

{year => x, month => x, day => x, hour => x, min => x, sec => x}

Missing elements are considered = 0.

string "1Y 2M 3D 4h 5m 6s"

Any part can be absent or negative.

Another relative date object

Clones another object

new($from, $till)

Creates relative date $rel so that $from + $rel == $till.

$from and $till can be Panda::Date objects or any data supported by Panda::Date constructor.

OBJECT METHODS

set($rel_string | $seconds | \@rel_array | \%rel_hash | $reldate)

set($from, $till)

Set relative date from data (data can be anything that constructor supports). This is much faster than creating new object.

year([$years]), years

Number of years in relative date

month([$months]), months, mon, mons

Number of month in relative date

day([$days]), days

Number of days in relative date

hour([$hours]), hours

Number of hours in relative date

min([$mins]), mins, minute, minutes

Number of minutes in relative date

sec([$secs]), secs, second, seconds

Number of seconds in relative date

to_sec(), to_second, to_secs, to_seconds, duration

Converts relative date to number of seconds. If any of day/month/year are non-zero then this value can be inaccurate because one need to know exact dates to calculate exact number of seconds.

For such calculations the following assumptions are made:

1M = 2_629_744s
1M = 2_629_744/86400 D
1D = 86400s

to_min(), to_minute, to_mins, to_minutes

Converts relative date to number of minutes. If any of day/month/year are non-zero then this value can be inaccurate, see to_sec().

to_hour(), to_hours

Converts relative date to number of hours. If any of day/month/year are non-zero then this value can be inaccurate, see to_sec().

to_day(), to_days

Converts relative date to number of days. If any of sec/min/hour/month/year are non-zero then this value can be inaccurate, see to_sec().

to_month(), to_months, to_mon, to_mons

Converts relative date to number of months. If any of sec/min/hour/day are non-zero then this value can be inaccurate, see to_sec().

to_year(), to_years

Converts relative date to number of years. If any of sec/min/hour/day are non-zero then this value can be inaccurate, see to_sec().

"", to_string(), string(), as_string()

Returns string in "4M 15D 123s" format, any of YMDhms can be absent or negative. If all the parts YMDhms are 0, then "" is returned.

'bool', to_bool()

Called implicitly in boolean context. Returns FALSE, if sec = 0 and min = 0 and .... year = 0, i.e. duration = 0. Otherwise TRUE.

'0+', to_number()

Returns to_sec().

'*', multiply_new($num)

Multiplies relative date by $num. $num can be fractional but the result is always integer.

Examples

    $rel = "1M 1D";
    print $rel * 2; # 2M 2D
    print rdate("10h")->multiply(10); # 100h

Relative date can only be multiplied by number (scalar).

No normalization are made, i.e. 12h*2 = 24h is not normalized to 1D because that would be inaccurate (on DST border day for example, 1D is 25 or 23h)

'*=', multiply($num)

Same as multiply_new(), but changes current object instead of creating new one.

'/', divide_new($num)

Divides relative date by $num. $num can be fractional but the result is always integer.

System will denormalize values if in another way (rounding) precision loses are bigger, for example "1Y" / 2 = "6M" (without denormalization it would be 0).

This applies even if units are not converted accurate. In this case assumptions mentioned in to_sec() are made.

Examples

    $rel = "2Y";
    print $rel/2; # 1Y
    print $rel/4; # 6M
    print rdate("1D")/3; # 8h
    print (rdate("1D")/3)*3; # 24h
    print MONTH/2; # "15D 5h 14m 32s"

P.S. Keep in mind that ($rel / N) * N is not always equals $rel, as well as ($rel * N) / N

'/=', divide($num)

Same as divide_new(), but changes current object instead of creating new one.

'+', add_new($reldate | $rel_string | $seconds | \@rel_array | \%rel_hash)

Adds another rel date to current. Another reldate can be Panda::Date::Rel object or any data valid for its constructor.

Examples

    my $rel = 2*MONTH;
    print $rel+MONTH; # 3M
    print $rel+'30D'; # 2M 30D
    print $rel+[1,2,3]; # 1Y 4M 3D
    

'+=', add($reldate | $rel_string | $seconds | \@rel_array | \%rel_hash)

Same as add_new(), but changes current object instead of creating new one.

Examples

    my $rel = 2*MONTH;
    $rel += '16h'; # 2M 16h
    $rel += {sec => 10, min => 20}; # 2M 16h 20m 10s
    $rel += $rel; # 4M 32h 40m 20s
    

'-', subtract_new($reldate | $rel_string | $seconds | \@rel_array | \%rel_hash)

Subtracts another reldate from current. Another reldate can be Panda::Date::Rel object or any data valid for its constructor.

Examples

    my $rel = 2*MONTH;
    print $rel-MONTH; # 1M
    print $rel-'30D'; # 2M -30D
    print $rel-[1,2,3]; # -1Y -3D
    

'-=', subtract($reldate | $rel_string | $seconds | \@rel_array | \%rel_hash)

Same as subtract_new(), but changes current object instead of creating new one.

'neg', negative_new() (unary '-')

Changes sign of YMDhms

negative()

Same as negative_new(), but changes current object instead of creating new one.

'<=>', compare($reldate | $rel_string | $seconds | \@rel_array | \%rel_hash)

Compares 2 relative dates and returns -1, 0 or 1. Another reldate can be Panda::Date::Rel object or any data valid for its constructor.

Dates are compared using to_sec(), therefore 2 dates can be equal even if they consist of different components. If you want full equality test, use 'eq'.

Examples

    MONTH > YEAR; # false
    rdate("1Y 1M") > YEAR; #true
    12*MONTH == YEAR; #true
    12*MONTH eq YEAR; #false
    

'eq', equals($reldate | $rel_string | $seconds | \@rel_array | \%rel_hash)

Same as '==' but returns TRUE only if 2 reldates are fully identical.

    $reldate = rdate("1Y 2M");
    $reldate == "1Y 2M"; # true
    $reldate == "14M";   # true
    $reldate eq "1Y 2M"; # true
    $reldate eq "14M";   # false
    

clone()

Clones object.

CLONE()

Hook for Panda::Lib::clone().

OPERATOR OVERLOAD RULES

See screenshot http://crazypanda.ru/v/clip2net/g/0/KfYbuNhu0b.png

STORABLE SERIALIZATION

Storable serialization is fully supported. That means you're able to freeze Panda::Date::Rel objects and thaw serialized data back without losing any information.

AUTHOR

Pronin Oleg <syber@cpan.org>, Crazy Panda, CP Decision LTD

LICENSE

You may distribute this code under the same terms as Perl itself.