From 319f82d054c50c96034e5b0b06bb927140c59bf6 Mon Sep 17 00:00:00 2001
From: Mike Rylander <mrylander@gmail.com>
Date: Mon, 31 Jul 2017 15:55:34 -0400
Subject: [PATCH] LP#1635737 Apply DST-aware timezone to context dates

Do our best to enforce the rule required by OpenSRF's interval_to_seconds
that when a context date is in use, and you care about DST awareness, you
must set the timezone to a DST-aware value, e.g., 'America/New_York'. In
most situations, 'local' will suffice for this, as the server is typically
configured with a DST-aware timezone in its environment.  However, we will
look for an org unit setting called 'lib.timezone' and use that where we
can.  See LP#1705524 for info on that setting.

Signed-off-by: Mike Rylander <mrylander@gmail.com>

Conflicts:
	Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm
	Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/NonCat.pm

Signed-off-by: Dan Wells <dbw2@calvin.edu>
Signed-off-by: Bill Erickson <berickxx@gmail.com>
---
 .../lib/OpenILS/Application/Circ/Circulate.pm      | 23 ++++++++++++++++++----
 .../lib/OpenILS/Application/Circ/NonCat.pm         | 11 ++++++++++-
 2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm
index 990c3a75ee..fab7796625 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/Circulate.pm
@@ -2387,15 +2387,30 @@ sub apply_modified_due_date {
 sub create_due_date {
     my( $self, $duration, $date_ceiling, $force_date, $start_time ) = @_;
 
-    # for now, use the server timezone.  TODO: use workstation org timezone
-    my $due_date = DateTime->now(time_zone => 'local');
-    $due_date = DateTime::Format::ISO8601->new->parse_datetime(clean_ISO8601($start_time)) if $start_time;
+    # Look up circulating library's TZ, or else use client TZ, falling
+    # back to server TZ
+    my $tz = $U->ou_ancestor_setting_value(
+        $self->circ_lib,
+        'lib.timezone',
+        $self->editor
+    ) || 'local';
+
+    my $due_date = $start_time ?
+        DateTime->now(time_zone => $tz) :
+        $due_date = DateTime::Format::ISO8601
+            ->new
+            ->parse_datetime(clean_ISO8601($start_time))
+            ->set_time_zone($tz);
 
     # add the circ duration
     $due_date->add(seconds => OpenILS::Utils::DateTime->interval_to_seconds($duration, $due_date));
 
     if($date_ceiling) {
-        my $cdate = DateTime::Format::ISO8601->new->parse_datetime(clean_ISO8601($date_ceiling));
+        my $cdate = DateTime::Format::ISO8601
+            ->new
+            ->parse_datetime(clean_ISO8601($date_ceiling))
+            ->set_time_zone($tz);
+
         if ($cdate > DateTime->now and ($cdate < $due_date or $U->is_true( $force_date ))) {
             $logger->info("circulator: overriding due date with date ceiling: $date_ceiling");
             $due_date = $cdate;
diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/NonCat.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/NonCat.pm
index cdf9a6fed7..da23bf3e10 100644
--- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/NonCat.pm
+++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Circ/NonCat.pm
@@ -186,7 +186,16 @@ sub noncat_due_date {
     my $otype = $e->retrieve_config_non_cataloged_type($circ->item_type) 
         or return $e->die_event;
 
-    my $duedate = $_dt_parser->parse_datetime( clean_ISO8601($circ->circ_time) );
+    my $tz = $U->ou_ancestor_setting_value(
+        $circ->circ_lib,
+        'lib.timezone',
+        $self->editor
+    ) || 'local';
+
+    my $duedate = $_dt_parser
+        ->parse_datetime( clean_ISO8601($circ->circ_time) )
+        ->set_time_zone( $tz );
+
     $duedate = $duedate
         ->add( seconds => interval_to_seconds($otype->circ_duration, $duedate) )
         ->strftime('%FT%T%z');
-- 
2.11.0