Subject: | Patch: support for string representation "iso8601 with time zone offset" |
Hi,
ISO8601 seems to allow for a string representation of dates where the
time zone offset is appended to the end of the string, like so:
2001-07-05T02:12:50+0200
It's fairly easy to reimplement with a couple method calls or a strftime
pattern (%FT%T%z), but it comes up often enough that I end up writing a
sub DateTime::iso8601tz { ... } in multiple projects at $work.
This patch (includes a few tests and documentation) implements a basic
$dt->iso8601tz method that will croak when $dt is using a floating time
zone, and output the ISO8601 with time zone representation otherwise.
Having almost no experience with Git and only some with Github, I tried
to use format-patch but it doesn't seem like it includes a reference to
the parent commit. This commit should apply cleanly on top of
4a43a9b998ffe9642cfcd41b4850e94675dc4cf8, which was your HEAD on master
at the time of writing.
Subject: | 0001-Add-method-iso8601tz-to-DateTime-objects.patch |
From c56695c3933c9d460755bb711348041596081c55 Mon Sep 17 00:00:00 2001
From: Fabrice Gabolde <fabrice.gabolde@uperto.com>
Date: Thu, 28 Feb 2013 17:07:30 +0100
Subject: [PATCH] Add method ->iso8601tz to DateTime objects.
Like iso8601, but appends time zone offset and croaks on floating time zones.
---
lib/DateTime.pm | 16 ++++++++++++++
t/45iso8601tz.t | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 78 insertions(+), 0 deletions(-)
create mode 100644 t/45iso8601tz.t
diff --git a/lib/DateTime.pm b/lib/DateTime.pm
index 3d716b7..6fb2c83 100644
--- a/lib/DateTime.pm
+++ b/lib/DateTime.pm
@@ -858,6 +858,13 @@ sub hms {
sub iso8601 { join 'T', $_[0]->ymd('-'), $_[0]->hms(':') }
*datetime = \&iso8601;
+sub iso8601tz {
+ my $self = shift;
+ Carp::croak("ISO 8601 (with time zone) representation makes no sense for floating time zones\n")
+ if $self->time_zone->is_floating;
+ return $self->iso8601 . $self->time_zone->offset_as_string($self->offset);
+}
+
sub is_leap_year { $_[0]->_is_leap_year( $_[0]->year ) }
sub week {
@@ -2652,6 +2659,15 @@ This method is equivalent to:
Also available as C<< $dt->iso8601() >>.
+=head3 $dt->iso8601tz()
+
+This method returns the ISO8601-formatted date like C<< $d->iso8601()
+>>, but it appends the current time zone offset like so:
+"2013-02-28T11:02:53+0100".
+
+If the DateTime object is using a floating time zone, the method will
+throw an exception.
+
=head3 $dt->is_leap_year()
This method returns a true or false indicating whether or not the
diff --git a/t/45iso8601tz.t b/t/45iso8601tz.t
new file mode 100644
index 0000000..d4963d5
--- /dev/null
+++ b/t/45iso8601tz.t
@@ -0,0 +1,62 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Test::Exception;
+
+use DateTime;
+
+my $d_utc = DateTime->new(
+ year => 2001,
+ month => 7,
+ day => 5,
+ hour => 2,
+ minute => 12,
+ second => 50,
+ time_zone => 'UTC',
+);
+
+is( $d_utc->iso8601tz, '2001-07-05T02:12:50+0000', '->iso8601tz for an UTC time zone' );
+
+my $d_paris = DateTime->new(
+ year => 2001,
+ month => 7,
+ day => 5,
+ hour => 2,
+ minute => 12,
+ second => 50,
+ time_zone => 'Europe/Paris',
+);
+
+is( $d_paris->iso8601tz, '2001-07-05T02:12:50+0200', '->iso8601tz for a string time zone' );
+
+my $d_ohtwohundred = DateTime->new(
+ year => 2001,
+ month => 7,
+ day => 5,
+ hour => 2,
+ minute => 12,
+ second => 50,
+ time_zone => '+0200',
+);
+
+is( $d_ohtwohundred->iso8601tz, '2001-07-05T02:12:50+0200', '->iso8601tz for an explicit time zone' );
+
+my $d_floating = DateTime->new(
+ year => 2001,
+ month => 7,
+ day => 5,
+ hour => 2,
+ minute => 12,
+ second => 50,
+);
+
+# would use throws_ok here if Test::Exception was available
+eval { $d_floating->iso8601tz };
+my $error = $@;
+ok( $error,
+ '->iso8601tz for a floating time zone throws an exception' );
+like( $error, qr /ISO 8601 \(with time zone\) representation makes no sense for floating time zones/,
+ '... and the exception has the expected contents' );
+
+done_testing();
--
1.7.5.4