LP#1552778: add perldoc and unit tests for clean_ISO8601
authorGalen Charlton <gmc@equinoxinitiative.org>
Fri, 21 Sep 2018 18:04:24 +0000 (14:04 -0400)
committerKathy Lussier <klussier@masslnc.org>
Mon, 24 Sep 2018 18:41:04 +0000 (14:41 -0400)
To test
-------
[1] Apply patch.
[2] Verify new tests in t/14-OpenILS-Utils.t pass.

Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Signed-off-by: Kathy Lussier <klussier@masslnc.org>
Open-ILS/src/perlmods/lib/OpenILS/Utils/DateTime.pm
Open-ILS/src/perlmods/t/14-OpenILS-Utils.t

index d622480..69fec7a 100644 (file)
@@ -206,6 +206,41 @@ sub gmtime_ISO8601 {
        return sprintf('%d-%0.2d-%0.2dT%0.2d:%0.2d:%0.2d+00:00', $y, $M, $d, $h, $m, $s);
 }
 
+=head2 clean_ISO8601($date_string)
+
+Given a date string or a date/time string in a variety of ad-hoc
+formats, returns an ISO8601-formatted date/time string.
+
+The date portion of the input is expected to consist of a four-digit
+year, followed by a two-digit month, followed by a two-digit year,
+with each part optionally separated by a hyphen.  If there is
+only a date portion, it will be normalized to use hyphens.
+
+If there is no time portion in the input, "T00:00:00" is appended
+before the results are returned.
+
+For example, "20180917" would become "2018-09-17T00:00:00".
+
+If the input does not have a recognizable date, it is simply
+returned as is.
+
+If there is a time portion, it is expected to consist of two-digit
+hour, minutes, and seconds delimited by colons.  That time is
+appended to the return with "T" separting the date and time
+portions.
+
+If there is an ISO8601-style numeric timezone offset, it is
+normalized and appended to the return. If there is no timezone
+offset supplied in the input, the offset of the server's
+time zone is append to the return. Note that as implied above,
+if only a date is supplied, the return value does not include a
+timezone offset.
+
+For example, for a server running in U.S. Eastern Daylight
+Savings time, "20180917 08:31:15" would become "2018-09-17T08:31:15-04:00".
+
+=cut
+
 sub clean_ISO8601 {
        my $self = shift;
        my $date = shift || $self;
index dc6e2a1..ec164a7 100644 (file)
@@ -1,7 +1,9 @@
 #!perl -T
 
-use Test::More tests => 39;
+use Test::More tests => 42;
 use Test::Warn;
+use DateTime::TimeZone;
+use DateTime::Format::ISO8601;
 use utf8;
 
 use_ok( 'OpenILS::Utils::Configure' );
@@ -107,3 +109,15 @@ is (OpenILS::Utils::DateTime::interval_to_seconds('1 week'), 604800);
 is (OpenILS::Utils::DateTime::interval_to_seconds('1 month'), 2628000);
 is (OpenILS::Utils::DateTime::interval_to_seconds('1 year'), 31536000);
 is (OpenILS::Utils::DateTime::interval_to_seconds('1 year 1 second'), 31536001);
+
+# get current timezone offset for future use
+my $offset = DateTime::TimeZone::offset_as_string(
+                DateTime::TimeZone->new( name => 'local' )->offset_for_datetime(
+                    DateTime::Format::ISO8601->new()->parse_datetime('2018-09-17')
+                )
+            );
+$offset =~ s/^(.\d\d)(\d\d)+/$1:$2/;
+
+is (OpenILS::Utils::DateTime::clean_ISO8601('20180917'), '2018-09-17T00:00:00', 'plain date converted to ISO8601 timestamp');
+is (OpenILS::Utils::DateTime::clean_ISO8601('I am not a date'), 'I am not a date', 'non-date simply returned as is');
+is (OpenILS::Utils::DateTime::clean_ISO8601('20180917 08:31:15'), "2018-09-17T08:31:15$offset", 'time zone added to date/time');