Skip Menu |

This queue is for tickets about the DateTime-Format-Oracle CPAN distribution.

Report information
The Basics
Id: 36029
Status: resolved
Priority: 0/
Queue: DateTime-Format-Oracle

People
Owner: Nobody in particular
Requestors: jozef [...] kutej.net
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: 0.04
Fixed in: (no value)



Subject: timestamp with timezone
Hi Nathan, Can you please add timestamp with timezone support? A patch to do so is attached. Thank you, Jozef.
Subject: DateTime-Format-Oracle-timestamptz.patch
diff -Naur DateTime-Format-Oracle-0.04/lib/DateTime/Format/Oracle.pm DateTime-Format-Oracle/lib/DateTime/Format/Oracle.pm --- DateTime-Format-Oracle-0.04/lib/DateTime/Format/Oracle.pm 2008-02-27 17:09:41.000000000 +0100 +++ DateTime-Format-Oracle/lib/DateTime/Format/Oracle.pm 2008-05-20 10:38:41.000000000 +0200 @@ -7,9 +7,10 @@ use DateTime::Format::Builder; use Convert::NLS_DATE_FORMAT; -our $VERSION = '0.04'; +our $VERSION = '0.05'; our $nls_date_format = 'YYYY-MM-DD HH24:MI:SS'; our $nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS'; +our $nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS TZHTZM'; =head1 NAME @@ -100,6 +101,32 @@ sub nls_timestamp_format { $ENV{NLS_TIMESTAMP_FORMAT} || $nls_timestamp_format } +=item * nls_timestamp_tz_format + +This method is used to determine the current value of Oracle's +C<NLS_TIMESTAMP_TZ_FORMAT>. It currently just reads the value from + + $ENV{'NLS_TIMESTAMP_TZ_FORMAT'} + +or if that is not set, from the package variable C<$nls_timestamp_tz_format>, +which has a default value of C<YYYY-MM-DD HH24:MI:SS TZHTZM>. This is +a good default to have, but is not Oracle's default. Dates will fail +to parse if Oracle's NLS_TIMESTAMP_TZ_FORMAT and the value from this method +are not the same. + +If you want to use the default from this module, you can do something +like this after you connect to Oracle: + + $dbh->do( + "alter session set nls_timestamp_tz_format = '" . + DateTime::Format::Oracle->nls_timestamp_tz_format . + "'" + ); + +=cut + +sub nls_timestamp_tz_format { $ENV{NLS_TIMESTAMP_TZ_FORMAT} || $nls_timestamp_tz_format } + =item * parse_datetime Given a string containing a date and/or time representation @@ -133,6 +160,20 @@ sub parse_timestamp { $_[0]->current_timestamp_parser->(@_); } +=item * parse_timestamptz +=item * parse_timestamp_with_time_zone + +Given a string containing a date and/or time representation +matching C<NLS_TIMESTAMP_TZ_FORMAT>, this method will return a new +C<DateTime> object. + +If given an improperly formatted string, this method may die. + +=cut + +sub parse_timestamptz { $_[0]->current_timestamptz_parser->(@_); } +*parse_timestamp_with_time_zone = \&parse_timestamptz; + =item * current_date_parser The current C<DateTime::Format::Builder> generated parsing method @@ -151,6 +192,15 @@ *current_timestamp_parser = _parser_generator('current_timestamp_format'); +=item * current_timestamptz_parser + +The current C<DateTime::Format::Builder> generated parsing method +used by C<parse_timestamptz>. + +=cut + +*current_timestamptz_parser = _parser_generator('current_timestamptz_format'); + sub _parser_generator { # takes a method name for getting the current POSIX format @@ -236,6 +286,35 @@ return $dt->strftime($self->current_timestamp_format); } +=item * format_timestamptz +=item * format_timestamp_with_time_zone + +Given a C<DateTime> object, this method returns a string matching +the current value of C<NLS_TIMESTAMP_TZ_FORMAT>. + +It is important to keep the value of C<$ENV{'NLS_TIMESTAMP_TZ_FORMAT'}> the +same as the value of the Oracle session variable C<NLS_TIMESTAMP_TZ_FORMAT>. + +To determine the current value of Oracle's C<NLS_TIMESTAMP_TZ_FORMAT>: + + select NLS_TIMESTAMP_TZ_FORMAT from NLS_SESSION_PARAMETERS + +To reset Oracle's C<NLS_TIMESTAMP_TZ_FORMAT>: + + alter session set NLS_TIMESTAMP_TZ_FORMAT='YYYY-MM-DD HH24:MI:SS TZHTZM' + +It is generally a good idea to set C<NLS_TIMESTAMP_TZ_FORMAT> to an +unambiguos value, with four-digit year, and hour, minute, and second. + +=cut + +sub format_timestamptz { + my ($self, $dt) = @_; + return $dt->strftime($self->current_timestamptz_format); +} + +*format_timestamp_with_time_zone = \&format_timestamptz; + =item * current_date_format The current generated method used by C<format_datetime>, @@ -256,6 +335,16 @@ *current_timestamp_format = _format_generator('nls_timestamp_format'); +=item * current_timestamptz_format + +The current generated method used by C<format_timestamptz>, +C<format_timestamp_with_time_zone>, and C<current_timestamp_parser> to keep track of +the C<strptime> translation of C<NLS_TIMESTAMP_FORMAT>. + +=cut + +*current_timestamptz_format = _format_generator('nls_timestamp_tz_format'); + sub _format_generator { # takes a method name for getting the current Oracle format # returns a format generator code ref @@ -314,9 +403,6 @@ the C<DateTime> floating time zone, except for 'timestamp with time zone' columns. -I have not yet implemented C<parse_timestamp_with_timezone> nor -C<format_timestamp_with_timezone>. - =head2 INTERVAL ELEMENTS I have not implemented C<parse_duration>, C<format_duration>, diff -Naur DateTime-Format-Oracle-0.04/t/format_timestamptz.t DateTime-Format-Oracle/t/format_timestamptz.t --- DateTime-Format-Oracle-0.04/t/format_timestamptz.t 1970-01-01 01:00:00.000000000 +0100 +++ DateTime-Format-Oracle/t/format_timestamptz.t 2008-05-20 10:41:28.000000000 +0200 @@ -0,0 +1,38 @@ +use strict; +# Shamelessly stolen from DateTime::Format::MySQL - Thanks Dave +use Test::More tests => 8; +use DateTime::Format::Oracle; + +my $class = 'DateTime::Format::Oracle'; + +can_ok($class, qw( + format_timestamptz + format_timestamp_with_time_zone +)); + +my $dt = DateTime->new( + year => 2000, + month => 5, + day => 6, + hour => 15, + minute => 23, + second => 44, + time_zone => 'UTC', +); + +my %tests = ( + '2000-05-06 15:23:44' => 'YYYY-MM-DD HH24:MI:SS', + '2000-05-06 15:23:44 UTC' => 'YYYY-MM-DD HH24:MI:SS TZR', + '2000-05-06 15:23:44 +0000' => 'YYYY-MM-DD HH24:MI:SS TZHTZM', + '06-May-00' => 'DD-Mon-RR', + '06-May-00 03.23.44.000000 PM' => 'DD-Mon-RR HH.MI.SSXFF AM', + '06-May-00 03.23.44.000000 PM UTC' => 'DD-Mon-RR HH.MI.SSXFF AM TZR', + 'Saturday, 06 May 2000' => 'DAY, DD Mon YYYY', +); + +foreach my $result (keys %tests) { + my $nls_format = $tests{$result}; + local $ENV{NLS_TIMESTAMP_TZ_FORMAT} = $nls_format; + is($class->format_timestamptz($dt), $result, "format_timestamptz $nls_format"); +} + diff -Naur DateTime-Format-Oracle-0.04/t/parse_timestamptz.t DateTime-Format-Oracle/t/parse_timestamptz.t --- DateTime-Format-Oracle-0.04/t/parse_timestamptz.t 1970-01-01 01:00:00.000000000 +0100 +++ DateTime-Format-Oracle/t/parse_timestamptz.t 2008-05-20 10:41:48.000000000 +0200 @@ -0,0 +1,64 @@ +use strict; +use Test::More tests => 1 + 3 * 7; # strings * methods + +use DateTime::Format::Oracle; + +my $class = 'DateTime::Format::Oracle'; + +can_ok($class, qw( + parse_timestamptz + parse_timestamp_with_time_zone +)); + +my %tests = ( + '2003-02-15 14:39:06 -0600' => { + format => 'YYYY-MM-DD HH24:MI:SS TZHTZM', + year => 2003, + month => 2, + day => 15, + hour => 14, + minute => 39, + second => 6, + time_zone => '-0600', + }, + '15-FEB-03 02.39.06.167901 PM -0400' => { + format => 'DD-MON-RR HH.MI.SSXFF AM TZHTZM', + year => 2003, + month => 2, + day => 15, + hour => 14, + minute => 39, + second => 6, + time_zone => '-0400', + }, + '2003-02-15 14:39:06 +0200' => { + format => 'YYYY-MM-DD HH24:MI:SS TZHTZM', + year => 2003, + month => 2, + day => 15, + hour => 14, + minute => 39, + second => 6, + time_zone => '+0200', + }, +); + +foreach my $string (keys %tests) { + my $params = $tests{$string}; + my $nls_format = delete $params->{format}; + local $ENV{NLS_TIMESTAMP_TZ_FORMAT} = $nls_format; + my $dt; + eval { $dt = $class->parse_timestamptz($string) }; + if ($@) { + warn "failed to parse date '$string' via format '$nls_format' (" . $class->current_timestamp_format . ") ".$@; + next; + } + foreach my $method (keys %$params) { + if ($method eq 'time_zone') { + is($dt->$method->name, $params->{$method}, "$nls_format $method"); + } else { + is($dt->$method, $params->{$method}, "$nls_format $method"); + } + } +} +
Subject: Re: [rt.cpan.org #36029] timestamp with timezone
Date: Tue, 10 Jun 2008 14:20:06 -0400
To: Jozef Kutej via RT <bug-DateTime-Format-Oracle [...] rt.cpan.org>
From: Nathan Gray <kolibrie [...] graystudios.org>
The uploaded file DateTime-Format-Oracle-0.05.tar.gz has entered CPAN as file: $CPAN/authors/id/K/KO/KOLIBRIE/DateTime-Format-Oracle-0.05.tar.gz size: 5781 bytes md5: 1f594e0c78c00a6a69d36b6f4ac4c4b5
Download signature.asc
application/pgp-signature 189b

Message body not shown because it is not plain text.

Great! Thank you.