Palm::Progect::Date - utility routines for converting dates


Palm-Progect documentation Contained in the Palm-Progect distribution.

Index


Code Index:

NAME

Top

Palm::Progect::Date - utility routines for converting dates

SYNOPSIS

Top

    use Palm::Progect::Date;

    $date_due = parse_date('2038/12/31', 'yyyy/mm/dd');
    $date_due = parse_date('12-31-38', 'mm-dd-yy');

    my $formatted_date = format_date($time_in_unix_format, 'yyyy/mm/dd');

DESCRIPTION

Top

These routines are used by the Palm::Progect::* modules to parse and format dates.

SUBROUTINES

Top

format_date($time, $date_format)

Given a time in Unix format (i.e. seconds since the epoch), return a string representation of the date based on the given format:

    my $formatted_date = format_date($time_in_unix_format, 'yyyy/mm/dd');

    print format_date(0, 'yyyy-mm-dd'); # prints "1969-12-31"

The format can include the following symbols:

yyyy

Four digit year

yy

Last two digits of year

mm

Month number

dd

Day number

parse_date($date_string, $date_format)

Attempt to parse $date_string as a textual representation of a date, using template supplied in $date_format:

    my $time = parse_date('2038/10/24', 'yyyy/mm/dd')

    print parse_date('12-31, 1969', 'mm-dd, yyyy'); # prints 0

No attempt is made to guess the format of $date_string; it is assumed that you know its format.

$date_format can include the following symbols:

yyyy

Four digit year

yy

Last two digits of year

mm

Month number

dd

Day number

BUGS and CAVEATS

Top

The two digit date format will fail for dates before 1950 or after 2049 :).

AUTHOR

Top

Michael Graham <mag-perl@occamstoothbrush.com>

Copyright (C) 2002-2005 Michael Graham. All rights reserved. This program is free software. You can use, modify, and distribute it under the same terms as Perl itself.

The latest version of this module can be found on http://www.occamstoothbrush.com/perl/

SEE ALSO

Top

progconv

Palm::PDB(3)

http://progect.sourceforge.net/


Palm-Progect documentation Contained in the Palm-Progect distribution.
package Palm::Progect::Date;
use strict;


use Time::Local;
use Exporter;

use vars qw(@ISA @EXPORT);

@ISA = 'Exporter';

@EXPORT = qw(
    parse_date
    format_date
);

my %Date_Cache;

sub format_date {
    my ($time, $date_format) = @_;

    $time ||= 0;

    return $Date_Cache{$time . $date_format} if exists $Date_Cache{$time . $date_format};

    my ($day, $month, $year) = (localtime $time)[3,4,5];

    $day   = sprintf '%02d', $day;
    $month = sprintf '%02d', $month + 1;
    $year  = sprintf '%04d', $year  + 1900;
    my $shortyear = substr $year, -2, 2;

    my $date_string = $date_format;

    $date_string =~ s/dd/$day/gi;
    $date_string =~ s/mm/$month/gi;
    $date_string =~ s/yyyy/$year/gi;
    $date_string =~ s/yy/$shortyear/gi;

    return $Date_Cache{$time . $date_format} = $date_string;
}

sub parse_date {
    my ($date_string, $date_format) = @_;


    my %values;

    # This parser is very convoluted.
    # For each token, we build a regexp
    # that matches it and all other tokens in the
    # format string, but we put parens around
    # the single token we're interested in
    # so we can capture its value.
    #
    # e.g. (assuming template of dd/mm/yy)
    #   first regex is  \d\d/\d\d/(\d\d)
    #   second regex is \d\d/(\d\d)/\d\d
    #   etc.
    #
    # So we build a regex for each token,
    # then run them all in sequence,
    # extracting one token for each regex
    #
    # We have to do 16 searches to construct
    # the regexes and then we also have to
    # search the date string 4 times.
    #
    # I'm sure there are better ways of
    # doing this.

    my @tokens = ('yyyy','mm','dd','yy');
    foreach my $token (@tokens) {
        my $format = $date_format;
        $format =~ s/$token/'(' . '\\d' x length($token) . ')'/ge;
        foreach my $token (@tokens) {
            $format =~ s/$token/'\\d' x length($token)/ge;
        }
        if ($date_string =~ /^$format$/) {
            $values{$token} = $1;
        }
    }

    my $day   = $values{'dd'};
    my $month = $values{'mm'};
    my $year  = $values{'yyyy'};

    # Y2K complient, but not Y2K+50 or Y2K-50 complient
    # no one's forcing you to use two-digit dates, you know.
    if ($values{'yy'} and $values{'yy'} < 50) {
        $values{'yy'} += 2000;
    }
    $year   ||= $values{'yy'};

    my $date;
    if ($day and $month and $year) {
        eval {
            $date = timelocal(0,0,0,$day,$month-1,$year);
        };
    }
    return $date;
}

1;