The parse_datetime routine in DateTime::Format::Excel is 100% when
converting dates from the Excel serial date format, but I found it
doesn't convert the time portion of a value, i.e. the decimal portion of
the float.  For example, the following code:

 

my $datetime = DateTime::Format::Excel->parse_datetime(39105.429861111);

print $datetime->strftime("%m/%d/%Y %H:%M:%S");

 

produces "01/23/2007 00:00:00" instead of the real date/time value of
"01/23/2007 10:19:00".  It appears that the DateTime add() routine
treats the float as an integer, thus cutting off the Excel time value,
which you wouldn't expect add() to understand anyway.  To address this,
I re-wrote the parse_datetime routine to handle the time values.  I
thought I'd share this with the community in case anyone else has needed
this.

 

sub parse_datetime

{

    my $self = shift;

    croak 'No date specified.' unless @_;

    croak 'Invalid number of days' unless $_[0] =~ /^ (\d+ (?: (\.\d+)
)? ) $/x;

    my $days = 0;

    my $secs = 0;

    $days = int($1) if defined $1;                      # int() not
really needed, but it's clean

    if (defined $2)

     {

      $secs = $2;

      $secs *= 86400;                                   # Convert
decimal value to whole seconds

      $secs = int($secs + .5);                          # Round the
seconds like Excel does

     }

 

    my $dt = DateTime->new( $self->epoch );

    $dt->add( days => $days, seconds => $secs );

 

    return $dt;

}

 

Bobby

 

Reply via email to