From af84df164ff7d39a686e7a9b872656baecdaa481 Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Wed, 23 May 2018 16:29:05 -0400
Subject: [PATCH] Move VuFind\Date to external package; update vufind-org
 dependencies.

---
 composer.json                                 |   7 +-
 composer.lock                                 | 127 ++++++---
 module/VuFind/config/module.config.php        |   2 +-
 module/VuFind/src/VuFind/Date/Converter.php   | 248 ------------------
 module/VuFind/src/VuFind/Db/Row/Resource.php  |   2 +-
 module/VuFind/src/VuFind/Exception/Date.php   |  41 ---
 module/VuFind/src/VuFind/ILS/Driver/Aleph.php |  12 +-
 .../VuFind/src/VuFind/ILS/Driver/Amicus.php   |   8 +-
 module/VuFind/src/VuFind/ILS/Driver/Demo.php  |   2 +-
 .../src/VuFind/ILS/Driver/Evergreen.php       |   8 +-
 .../VuFind/src/VuFind/ILS/Driver/Horizon.php  |  12 +-
 .../src/VuFind/ILS/Driver/Innovative.php      |   2 +-
 module/VuFind/src/VuFind/ILS/Driver/Koha.php  |  10 +-
 .../src/VuFind/ILS/Driver/KohaILSDI.php       |  14 +-
 module/VuFind/src/VuFind/ILS/Driver/LBS4.php  |   6 +-
 .../src/VuFind/ILS/Driver/NewGenLib.php       |   8 +-
 .../VuFind/src/VuFind/ILS/Driver/Unicorn.php  |   8 +-
 .../VuFind/src/VuFind/ILS/Driver/Virtua.php   |   8 +-
 .../VuFind/src/VuFind/ILS/Driver/Voyager.php  |   2 +-
 .../src/VuFind/ILS/Driver/VoyagerRestful.php  |   2 +-
 .../VuFind/src/VuFind/ILS/Driver/XCNCIP2.php  |  10 +-
 .../VuFind/Service/DateConverterFactory.php   |  70 +++++
 .../src/VuFind/View/Helper/Root/Citation.php  |   2 +-
 .../src/VuFind/View/Helper/Root/DateTime.php  |   2 +-
 .../src/VuFindTest/Date/ConverterTest.php     | 149 -----------
 25 files changed, 223 insertions(+), 539 deletions(-)
 delete mode 100644 module/VuFind/src/VuFind/Date/Converter.php
 delete mode 100644 module/VuFind/src/VuFind/Exception/Date.php
 create mode 100644 module/VuFind/src/VuFind/Service/DateConverterFactory.php
 delete mode 100644 module/VuFind/tests/unit-tests/src/VuFindTest/Date/ConverterTest.php

diff --git a/composer.json b/composer.json
index 697e88d1d32..7da1e1e9492 100644
--- a/composer.json
+++ b/composer.json
@@ -29,9 +29,10 @@
         "serialssolutions/summon": "1.1.0",
         "symfony/yaml": "3.4.10",
         "swagger-api/swagger-ui": "2.2.10",
-        "vufind-org/vufindcode": "1.0.3",
-        "vufind-org/vufindharvest": "2.3.0",
-        "vufind-org/vufindhttp": "2.1.1",
+        "vufind-org/vufindcode": "1.1.0",
+        "vufind-org/vufinddate": "1.0.0",
+        "vufind-org/vufindharvest": "2.4.0",
+        "vufind-org/vufindhttp": "2.2.0",
         "yajra/laravel-pdo-via-oci8": "1.3.6",
         "zendframework/zend-cache": "2.8.2",
         "zendframework/zend-captcha": "2.8.0",
diff --git a/composer.lock b/composer.lock
index cd13dde330a..96fd7b85318 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "content-hash": "85e3c4925c32acdc3f23a507dab92146",
+    "content-hash": "9706d8ee125df82ee07e87ac799d82a1",
     "packages": [
         {
             "name": "aferrandini/phpqrcode",
@@ -1651,28 +1651,30 @@
         },
         {
             "name": "vufind-org/vufindcode",
-            "version": "v1.0.3",
+            "version": "v1.1.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/vufind-org/vufindcode.git",
-                "reference": "f50091c35f50865b926bac549e671347c4d4389d"
+                "reference": "3a0a7628b7422e32a1313108f7aa972488c95e01"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/vufind-org/vufindcode/zipball/f50091c35f50865b926bac549e671347c4d4389d",
-                "reference": "f50091c35f50865b926bac549e671347c4d4389d",
+                "url": "https://api.github.com/repos/vufind-org/vufindcode/zipball/3a0a7628b7422e32a1313108f7aa972488c95e01",
+                "reference": "3a0a7628b7422e32a1313108f7aa972488c95e01",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.3.0"
+                "php": ">=7.0.8"
             },
             "require-dev": {
-                "friendsofphp/php-cs-fixer": "1.11.3",
-                "phploc/phploc": "2.0.6",
-                "phpmd/phpmd": "1.5.0",
-                "phpunit/phpunit": "4.8.4",
-                "sebastian/phpcpd": "1.4.3",
-                "squizlabs/php_codesniffer": "2.6.0"
+                "friendsofphp/php-cs-fixer": "2.11.1",
+                "pear/http_request2": "2.3.0",
+                "phing/phing": "2.16.1",
+                "phploc/phploc": "4.0.1",
+                "phpmd/phpmd": "2.6.0",
+                "phpunit/phpunit": "6.5.8",
+                "sebastian/phpcpd": "3.0.1",
+                "squizlabs/php_codesniffer": "3.2.3"
             },
             "type": "library",
             "autoload": {
@@ -1692,36 +1694,83 @@
             ],
             "description": "Class for representing ISBNs (a VuFind support library)",
             "homepage": "https://vufind.org/",
-            "time": "2016-06-06T19:12:16+00:00"
+            "time": "2018-05-23T18:48:59+00:00"
+        },
+        {
+            "name": "vufind-org/vufinddate",
+            "version": "v1.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/vufind-org/vufinddate.git",
+                "reference": "1bec5458b48d96fa8ff87123584042780f4c3c24"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/vufind-org/vufinddate/zipball/1bec5458b48d96fa8ff87123584042780f4c3c24",
+                "reference": "1bec5458b48d96fa8ff87123584042780f4c3c24",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.0.8"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "2.11.1",
+                "pear/http_request2": "2.3.0",
+                "phing/phing": "2.16.1",
+                "phploc/phploc": "4.0.1",
+                "phpmd/phpmd": "2.6.0",
+                "phpunit/phpunit": "6.5.8",
+                "sebastian/phpcpd": "3.0.1",
+                "squizlabs/php_codesniffer": "3.2.3"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "VuFind\\Date\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "GPL-2.0"
+            ],
+            "authors": [
+                {
+                    "name": "Demian Katz",
+                    "email": "demian.katz@villanova.edu"
+                }
+            ],
+            "description": "Date formatting tools for the VuFind project",
+            "homepage": "https://vufind.org/",
+            "time": "2018-05-23T19:59:10+00:00"
         },
         {
             "name": "vufind-org/vufindharvest",
-            "version": "v2.3.0",
+            "version": "v2.4.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/vufind-org/vufindharvest.git",
-                "reference": "c59e0a64b59873120c5cda32cbb8654629a8320e"
+                "reference": "a7391a2e3b9efc031c4e223debf7a56678e420a8"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/vufind-org/vufindharvest/zipball/c59e0a64b59873120c5cda32cbb8654629a8320e",
-                "reference": "c59e0a64b59873120c5cda32cbb8654629a8320e",
+                "url": "https://api.github.com/repos/vufind-org/vufindharvest/zipball/a7391a2e3b9efc031c4e223debf7a56678e420a8",
+                "reference": "a7391a2e3b9efc031c4e223debf7a56678e420a8",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.6",
+                "php": ">=7.0.8",
                 "zendframework/zend-console": ">=2.2",
                 "zendframework/zend-http": ">=2.2"
             },
             "require-dev": {
-                "friendsofphp/php-cs-fixer": "1.11.6",
-                "phing/phing": "2.16.0",
-                "phpdocumentor/phpdocumentor": "2.9.0",
-                "phploc/phploc": "3.0.1",
+                "friendsofphp/php-cs-fixer": "2.11.1",
+                "pear/http_request2": "2.3.0",
+                "phing/phing": "2.16.1",
+                "phploc/phploc": "4.0.1",
                 "phpmd/phpmd": "2.6.0",
-                "phpunit/phpunit": "5.7.15",
-                "sebastian/phpcpd": "2.0.4",
-                "squizlabs/php_codesniffer": "2.8.1"
+                "phpunit/phpunit": "6.5.8",
+                "sebastian/phpcpd": "3.0.1",
+                "squizlabs/php_codesniffer": "3.2.3"
             },
             "type": "library",
             "autoload": {
@@ -1742,33 +1791,35 @@
             ],
             "description": "VuFind Harvest Tools",
             "homepage": "https://vufind.org/",
-            "time": "2017-04-06T18:31:39+00:00"
+            "time": "2018-05-23T19:14:41+00:00"
         },
         {
             "name": "vufind-org/vufindhttp",
-            "version": "v2.1.1",
+            "version": "v2.2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/vufind-org/vufindhttp.git",
-                "reference": "b1b7dcd5f2c87a199fd3d6d439898cc7ddd0d7ca"
+                "reference": "2415b70424156ef9ebcbcff7900500c5fa62789b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/vufind-org/vufindhttp/zipball/b1b7dcd5f2c87a199fd3d6d439898cc7ddd0d7ca",
-                "reference": "b1b7dcd5f2c87a199fd3d6d439898cc7ddd0d7ca",
+                "url": "https://api.github.com/repos/vufind-org/vufindhttp/zipball/2415b70424156ef9ebcbcff7900500c5fa62789b",
+                "reference": "2415b70424156ef9ebcbcff7900500c5fa62789b",
                 "shasum": ""
             },
             "require": {
-                "php": ">=5.4",
+                "php": ">=7.0.8",
                 "zendframework/zend-http": ">=2.2"
             },
             "require-dev": {
-                "friendsofphp/php-cs-fixer": "1.11.3",
-                "phploc/phploc": "2.0.6",
-                "phpmd/phpmd": "1.5.0",
-                "phpunit/phpunit": "4.8.4",
-                "sebastian/phpcpd": "2.0.0",
-                "squizlabs/php_codesniffer": "2.6.0",
+                "friendsofphp/php-cs-fixer": "2.11.1",
+                "pear/http_request2": "2.3.0",
+                "phing/phing": "2.16.1",
+                "phploc/phploc": "4.0.1",
+                "phpmd/phpmd": "2.6.0",
+                "phpunit/phpunit": "6.5.8",
+                "sebastian/phpcpd": "3.0.1",
+                "squizlabs/php_codesniffer": "3.2.3",
                 "zendframework/zend-uri": ">=2.2"
             },
             "type": "library",
@@ -1795,7 +1846,7 @@
             ],
             "description": "VuFind HTTP service library",
             "homepage": "https://vufind.org/",
-            "time": "2016-09-23T12:51:36+00:00"
+            "time": "2018-05-23T17:51:55+00:00"
         },
         {
             "name": "yajra/laravel-pdo-via-oci8",
diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php
index 338e50c7883..e6e0f2ffd9e 100644
--- a/module/VuFind/config/module.config.php
+++ b/module/VuFind/config/module.config.php
@@ -311,7 +311,7 @@ $config = [
             'VuFind\Cookie\CookieManager' => 'VuFind\Cookie\CookieManagerFactory',
             'VuFind\Cover\Router' => 'VuFind\Cover\RouterFactory',
             'VuFind\Crypt\HMAC' => 'VuFind\Crypt\HMACFactory',
-            'VuFind\Date\Converter' => 'VuFind\Service\ServiceWithConfigIniFactory',
+            'VuFind\Date\Converter' => 'VuFind\Service\DateConverterFactory',
             'VuFind\Db\AdapterFactory' => 'VuFind\Service\ServiceWithConfigIniFactory',
             'VuFind\Db\Row\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory',
             'VuFind\Db\Table\PluginManager' => 'VuFind\ServiceManager\AbstractPluginManagerFactory',
diff --git a/module/VuFind/src/VuFind/Date/Converter.php b/module/VuFind/src/VuFind/Date/Converter.php
deleted file mode 100644
index d7b1e0300f5..00000000000
--- a/module/VuFind/src/VuFind/Date/Converter.php
+++ /dev/null
@@ -1,248 +0,0 @@
-<?php
-/**
- * Date/time conversion functionality.
- *
- * PHP version 7
- *
- * Copyright (C) Villanova University 2011.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * @category VuFind
- * @package  Date
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @author   Luke O'Sullivan <l.osullivan@swansea.ac.uk>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development Wiki
- */
-namespace VuFind\Date;
-
-use DateTime;
-use DateTimeZone;
-use VuFind\Exception\Date as DateException;
-
-/**
- * Date/time conversion functionality.
- *
- * @category VuFind
- * @package  Date
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @author   Luke O'Sullivan <l.osullivan@swansea.ac.uk>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development Wiki
- */
-class Converter
-{
-    /**
-     * Format string for dates
-     *
-     * @var string
-     */
-    protected $displayDateFormat;
-
-    /**
-     * Format string for times
-     *
-     * @var string
-     */
-    protected $displayTimeFormat;
-
-    /**
-     * Time zone to use for conversions
-     *
-     * @var DateTimeZone
-     */
-    protected $timezone;
-
-    /**
-     * Constructor
-     *
-     * @param \Zend\Config\Config $config Configuration to use (set to null to use
-     * defaults)
-     */
-    public function __construct($config = null)
-    {
-        // Set Display Date Format
-        $this->displayDateFormat
-            = isset($config->Site->displayDateFormat)
-            ? $config->Site->displayDateFormat : "m-d-Y";
-
-        // Set Display Date Format
-        $this->displayTimeFormat
-            = isset($config->Site->displayTimeFormat)
-            ? $config->Site->displayTimeFormat : "H:i";
-
-        // Set time zone
-        $zone = isset($config->Site->timezone)
-            ? $config->Site->timezone : 'America/New_York';
-        $this->timezone = new DateTimeZone($zone);
-    }
-
-    /**
-     * Generic method for conversion of a time / date string
-     *
-     * @param string $inputFormat  The format of the time string to be changed
-     * @param string $outputFormat The desired output format
-     * @param string $dateString   The date string
-     *
-     * @throws DateException
-     * @return string               A re-formatted time string
-     */
-    public function convert($inputFormat, $outputFormat, $dateString)
-    {
-        // These are date formats that we definitely know how to handle, and some
-        // benefit from special processing. However, items not found in this list
-        // will still be attempted in a generic fashion before giving up.
-        $validFormats = [
-            "m-d-Y", "m-d-y", "m/d/Y", "m/d/y", "U", "m-d-y H:i", "Y-m-d",
-            "Y-m-d H:i"
-        ];
-        $isValid = in_array($inputFormat, $validFormats);
-        if ($isValid) {
-            if ($inputFormat == 'U') {
-                // Special case for Unix timestamps (including workaround for
-                // floating point numbers):
-                $dateString = '@'
-                    . (is_float($dateString) ? intval($dateString) : $dateString);
-            } else {
-                // Strip leading zeroes from date string and normalize date separator
-                // to slashes:
-                $regEx = '/0*([0-9]+)(-|\/)0*([0-9]+)(-|\/)0*([0-9]+)/';
-                $dateString = trim(preg_replace($regEx, '$1/$3/$5', $dateString));
-            }
-            $errors = [
-                'warning_count' => 0, 'error_count' => 0, 'errors' => []
-            ];
-            try {
-                $date = new DateTime($dateString, $this->timezone);
-            } catch (\Exception $e) {
-                $errors['error_count']++;
-                $errors['errors'][] = $e->getMessage();
-            }
-        } else {
-            $date = DateTime::createFromFormat(
-                $inputFormat, $dateString, $this->timezone
-            );
-            $errors = DateTime::getLastErrors();
-        }
-
-        if ($errors['warning_count'] == 0 && $errors['error_count'] == 0 && $date) {
-            $date->setTimeZone($this->timezone);
-            return $date->format($outputFormat);
-        }
-        throw new DateException($this->getDateExceptionMessage($errors));
-    }
-
-    /**
-     * Build an exception message from a detailed error array.
-     *
-     * @param array $details Error details
-     *
-     * @return string
-     */
-    protected function getDateExceptionMessage($details)
-    {
-        $errors = "Date/time problem: Details: ";
-        if (is_array($details['errors']) && $details['error_count'] > 0) {
-            foreach ($details['errors'] as $error) {
-                $errors .= $error . " ";
-            }
-        } elseif (is_array($details['warnings'])) {
-            foreach ($details['warnings'] as $warning) {
-                $errors .= $warning . " ";
-            }
-        }
-        return $errors;
-    }
-
-    /**
-     * Convert a date string to admin-defined format.
-     *
-     * @param string $createFormat The format of the date string to be changed
-     * @param string $dateString   The date string
-     *
-     * @throws DateException
-     * @return string               A re-formatted date string
-     */
-    public function convertToDisplayDate($createFormat, $dateString)
-    {
-        return $this->convert($createFormat, $this->displayDateFormat, $dateString);
-    }
-
-    /**
-     * Public method for conversion of an admin defined date string
-     * to a driver required date string
-     *
-     * @param string $outputFormat The format of the required date string
-     * @param string $displayDate  The display formatted date string
-     *
-     * @throws DateException
-     * @return string               A re-formatted date string
-     */
-    public function convertFromDisplayDate($outputFormat, $displayDate)
-    {
-        return $this->convert(
-            $this->displayDateFormat, $outputFormat, $displayDate
-        );
-    }
-
-    /**
-     * Public support method for conversion of a time string to admin defined
-     * time string.
-     *
-     * @param string $createFormat The format of the time string to be changed
-     * @param string $timeString   The time string
-     *
-     * @throws DateException
-     * @return string               A re-formatted time string
-     */
-    public function convertToDisplayTime($createFormat, $timeString)
-    {
-        return $this->convert($createFormat, $this->displayTimeFormat, $timeString);
-    }
-
-    /**
-     * Public method for getting a date prepended to a time.
-     *
-     * @param string $createFormat The format of the time string to be changed
-     * @param string $timeString   The time string
-     * @param string $separator    String between time/date
-     *
-     * @throws DateException
-     * @return string               A re-formatted time string
-     */
-    public function convertToDisplayDateAndTime($createFormat, $timeString,
-        $separator = ' '
-    ) {
-        return $this->convertToDisplayDate($createFormat, $timeString)
-            . $separator . $this->convertToDisplayTime($createFormat, $timeString);
-    }
-
-    /**
-     * Public method for getting a time prepended to a date.
-     *
-     * @param string $createFormat The format of the time string to be changed
-     * @param string $timeString   The time string
-     * @param string $separator    String between time/date
-     *
-     * @throws DateException
-     * @return string               A re-formatted time string
-     */
-    public function convertToDisplayTimeAndDate($createFormat, $timeString,
-        $separator = ' '
-    ) {
-        return $this->convertToDisplayTime($createFormat, $timeString)
-            . $separator . $this->convertToDisplayDate($createFormat, $timeString);
-    }
-}
diff --git a/module/VuFind/src/VuFind/Db/Row/Resource.php b/module/VuFind/src/VuFind/Db/Row/Resource.php
index f15d2ca4da8..e2ecfd618b7 100644
--- a/module/VuFind/src/VuFind/Db/Row/Resource.php
+++ b/module/VuFind/src/VuFind/Db/Row/Resource.php
@@ -27,7 +27,7 @@
  */
 namespace VuFind\Db\Row;
 
-use VuFind\Exception\Date as DateException;
+use VuFind\Date\DateException;
 use VuFind\Exception\LoginRequired as LoginRequiredException;
 
 /**
diff --git a/module/VuFind/src/VuFind/Exception/Date.php b/module/VuFind/src/VuFind/Exception/Date.php
deleted file mode 100644
index f7763501385..00000000000
--- a/module/VuFind/src/VuFind/Exception/Date.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-/**
- * Date Exception
- *
- * PHP version 7
- *
- * Copyright (C) Villanova University 2011.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * @category VuFind
- * @package  Exceptions
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development Wiki
- */
-namespace VuFind\Exception;
-
-/**
- * Date Exception
- *
- * @category VuFind
- * @package  Exceptions
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org/wiki/development Wiki
- */
-class Date extends \Exception
-{
-}
diff --git a/module/VuFind/src/VuFind/ILS/Driver/Aleph.php b/module/VuFind/src/VuFind/ILS/Driver/Aleph.php
index d478a0465c6..527c3792e98 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/Aleph.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/Aleph.php
@@ -37,7 +37,7 @@
  */
 namespace VuFind\ILS\Driver;
 
-use VuFind\Exception\Date as DateException;
+use VuFind\Date\DateException;
 use VuFind\Exception\ILS as ILSException;
 
 /**
@@ -719,7 +719,7 @@ class Aleph extends AbstractBase implements \Zend\Log\LoggerAwareInterface,
      * @param string $id     The record id to retrieve the holdings for
      * @param array  $patron Patron data
      *
-     * @throws \VuFind\Exception\Date
+     * @throws DateException
      * @throws ILSException
      * @return array         On success, an associative array with the following
      * keys: id, availability (boolean), status, location, reserve, callnumber,
@@ -847,7 +847,7 @@ class Aleph extends AbstractBase implements \Zend\Log\LoggerAwareInterface,
      * @param array $user   The patron array from patronLogin
      * @param array $params Parameters
      *
-     * @throws \VuFind\Exception\Date
+     * @throws DateException
      * @throws ILSException
      * @return array      Array of the patron's historic loans on success.
      */
@@ -952,7 +952,7 @@ class Aleph extends AbstractBase implements \Zend\Log\LoggerAwareInterface,
      *
      * @param array $user The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws DateException
      * @throws ILSException
      * @return array        Array of the patron's transactions on success.
      */
@@ -1067,7 +1067,7 @@ class Aleph extends AbstractBase implements \Zend\Log\LoggerAwareInterface,
      *
      * @param array $user The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws DateException
      * @throws ILSException
      * @return array      Array of the patron's holds on success.
      */
@@ -1198,7 +1198,7 @@ class Aleph extends AbstractBase implements \Zend\Log\LoggerAwareInterface,
      *
      * @param array $user The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws DateException
      * @throws ILSException
      * @return mixed      Array of the patron's fines on success.
      */
diff --git a/module/VuFind/src/VuFind/ILS/Driver/Amicus.php b/module/VuFind/src/VuFind/ILS/Driver/Amicus.php
index b7a64938430..e267986e82a 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/Amicus.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/Amicus.php
@@ -440,7 +440,7 @@ class Amicus extends AbstractBase implements TranslatorAwareInterface
      * @param string $id     The record id to retrieve the holdings for
      * @param array  $patron Patron data
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array         On success, an associative array with the following
      * keys: id, availability (boolean), status, location, reserve, callnumber,
@@ -595,7 +595,7 @@ class Amicus extends AbstractBase implements TranslatorAwareInterface
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's transactions on success.
      */
@@ -628,7 +628,7 @@ class Amicus extends AbstractBase implements TranslatorAwareInterface
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return mixed        Array of the patron's fines on success.
      */
@@ -665,7 +665,7 @@ class Amicus extends AbstractBase implements TranslatorAwareInterface
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's holds on success.
      */
diff --git a/module/VuFind/src/VuFind/ILS/Driver/Demo.php b/module/VuFind/src/VuFind/ILS/Driver/Demo.php
index 855f43c36b4..eda909acabe 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/Demo.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/Demo.php
@@ -34,7 +34,7 @@
 namespace VuFind\ILS\Driver;
 
 use ArrayObject;
-use VuFind\Exception\Date as DateException;
+use VuFind\Date\DateException;
 use VuFind\Exception\ILS as ILSException;
 use VuFindSearch\Query\Query;
 use VuFindSearch\Service as SearchService;
diff --git a/module/VuFind/src/VuFind/ILS/Driver/Evergreen.php b/module/VuFind/src/VuFind/ILS/Driver/Evergreen.php
index 2c74282f179..76d002315f0 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/Evergreen.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/Evergreen.php
@@ -191,7 +191,7 @@ HERE;
      * @param string $id     The record id to retrieve the holdings for
      * @param array  $patron Patron data
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array         On success, an associative array with the following
      * keys: id, availability (boolean), status, location, reserve, callnumber,
@@ -353,7 +353,7 @@ HERE;
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's transactions on success.
      */
@@ -397,7 +397,7 @@ HERE;
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return mixed        Array of the patron's fines on success.
      */
@@ -454,7 +454,7 @@ HERE;
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's holds on success.
      */
diff --git a/module/VuFind/src/VuFind/ILS/Driver/Horizon.php b/module/VuFind/src/VuFind/ILS/Driver/Horizon.php
index 8470b9d506a..953767656f3 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/Horizon.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/Horizon.php
@@ -335,7 +335,7 @@ class Horizon extends AbstractBase implements LoggerAwareInterface
      * @param string $id     The record id to retrieve the holdings for
      * @param array  $patron Patron data
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array         On success, an associative array with the following
      * keys: id, availability (boolean), status, location, reserve, callnumber,
@@ -632,7 +632,7 @@ class Horizon extends AbstractBase implements LoggerAwareInterface
      *
      * @param array $row An sql row
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @return array Keyed data
      */
     protected function processHoldsRow($row)
@@ -690,7 +690,7 @@ class Horizon extends AbstractBase implements LoggerAwareInterface
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's holds on success.
      */
@@ -724,7 +724,7 @@ class Horizon extends AbstractBase implements LoggerAwareInterface
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return mixed        Array of the patron's fines on success.
      */
@@ -935,7 +935,7 @@ class Horizon extends AbstractBase implements LoggerAwareInterface
      *
      * @param array $row An array of keyed data
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @return array Keyed data for display by template files
      */
     protected function processTransactionsRow($row)
@@ -981,7 +981,7 @@ class Horizon extends AbstractBase implements LoggerAwareInterface
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's transactions on success.
      */
diff --git a/module/VuFind/src/VuFind/ILS/Driver/Innovative.php b/module/VuFind/src/VuFind/ILS/Driver/Innovative.php
index 097d97c2803..127b000e90f 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/Innovative.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/Innovative.php
@@ -270,7 +270,7 @@ class Innovative extends AbstractBase implements
      * @param string $id     The record id to retrieve the holdings for
      * @param array  $patron Patron data
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array         On success, an associative array with the following
      * keys: id, availability (boolean), status, location, reserve, callnumber,
diff --git a/module/VuFind/src/VuFind/ILS/Driver/Koha.php b/module/VuFind/src/VuFind/ILS/Driver/Koha.php
index 2517480f84c..7999f80d411 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/Koha.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/Koha.php
@@ -160,7 +160,7 @@ class Koha extends AbstractBase
      * @param string $id     The record id to retrieve the holdings for
      * @param array  $patron Patron data
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array         On success, an associative array with the following
      * keys: id, availability (boolean), status, location, reserve, callnumber,
@@ -284,7 +284,7 @@ class Koha extends AbstractBase
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return mixed        Array of the patron's fines on success.
      */
@@ -330,7 +330,7 @@ class Koha extends AbstractBase
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's holds on success.
      */
@@ -412,7 +412,7 @@ class Koha extends AbstractBase
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's transactions on success.
      */
@@ -495,7 +495,7 @@ class Koha extends AbstractBase
      * @param array $patron The patron array from patronLogin
      * @param array $params Parameters
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's transactions on success.
      */
diff --git a/module/VuFind/src/VuFind/ILS/Driver/KohaILSDI.php b/module/VuFind/src/VuFind/ILS/Driver/KohaILSDI.php
index 766fdc70817..268745b5e04 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/KohaILSDI.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/KohaILSDI.php
@@ -30,7 +30,7 @@ namespace VuFind\ILS\Driver;
 
 use PDO;
 use PDOException;
-use VuFind\Exception\Date as DateException;
+use VuFind\Date\DateException;
 use VuFind\Exception\ILS as ILSException;
 use Zend\Log\LoggerInterface;
 
@@ -781,7 +781,7 @@ class KohaILSDI extends \VuFind\ILS\Driver\AbstractBase implements
      * @param string $id     The record id to retrieve the holdings for
      * @param array  $patron Patron data
      *
-     * @throws \VuFind\Exception\Date
+     * @throws DateException
      * @throws ILSException
      * @return array         On success, an associative array with the following
      * keys: id, availability (boolean), status, location, reserve, callnumber,
@@ -1076,7 +1076,7 @@ class KohaILSDI extends \VuFind\ILS\Driver\AbstractBase implements
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws DateException
      * @throws ILSException
      * @return mixed        Array of the patron's fines on success.
      */
@@ -1189,7 +1189,7 @@ class KohaILSDI extends \VuFind\ILS\Driver\AbstractBase implements
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws DateException
      * @throws ILSException
      * @return mixed        Array of the patron's fines on success.
      */
@@ -1229,7 +1229,7 @@ class KohaILSDI extends \VuFind\ILS\Driver\AbstractBase implements
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws DateException
      * @throws ILSException
      * @return array        Array of the patron's holds on success.
      */
@@ -1411,7 +1411,7 @@ class KohaILSDI extends \VuFind\ILS\Driver\AbstractBase implements
      * @param array $patron The patron array from patronLogin
      * @param array $params Parameters
      *
-     * @throws \VuFind\Exception\Date
+     * @throws DateException
      * @throws ILSException
      * @return array        Array of the patron's transactions on success.
      */
@@ -1493,7 +1493,7 @@ class KohaILSDI extends \VuFind\ILS\Driver\AbstractBase implements
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws DateException
      * @throws ILSException
      * @return array        Array of the patron's transactions on success.
      */
diff --git a/module/VuFind/src/VuFind/ILS/Driver/LBS4.php b/module/VuFind/src/VuFind/ILS/Driver/LBS4.php
index 779463612b3..4959844d699 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/LBS4.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/LBS4.php
@@ -271,7 +271,7 @@ class LBS4 extends DAIA implements TranslatorAwareInterface
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's transactions on success.
      */
@@ -313,7 +313,7 @@ class LBS4 extends DAIA implements TranslatorAwareInterface
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array Array of the patron's holds on success.
      */
@@ -382,7 +382,7 @@ class LBS4 extends DAIA implements TranslatorAwareInterface
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return mixed        Array of the patron's fines on success.
      */
diff --git a/module/VuFind/src/VuFind/ILS/Driver/NewGenLib.php b/module/VuFind/src/VuFind/ILS/Driver/NewGenLib.php
index 967d5c033e1..2d0e9a67382 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/NewGenLib.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/NewGenLib.php
@@ -85,7 +85,7 @@ class NewGenLib extends AbstractBase
      * @param string $RecordID The record id to retrieve the holdings for
      * @param array  $patron   Patron data
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array           On success, an associative array with the following
      * keys: id, availability (boolean), status, location, reserve, callnumber,
@@ -129,7 +129,7 @@ class NewGenLib extends AbstractBase
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return mixed        Array of the patron's fines on success.
      */
@@ -197,7 +197,7 @@ class NewGenLib extends AbstractBase
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's holds on success.
      */
@@ -334,7 +334,7 @@ class NewGenLib extends AbstractBase
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's transactions on success.
      */
diff --git a/module/VuFind/src/VuFind/ILS/Driver/Unicorn.php b/module/VuFind/src/VuFind/ILS/Driver/Unicorn.php
index a3d54e1d6c1..8f76f26b523 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/Unicorn.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/Unicorn.php
@@ -397,7 +397,7 @@ class Unicorn extends AbstractBase implements \VuFindHttp\HttpServiceAwareInterf
      * @param string $id     The record id to retrieve the holdings for
      * @param array  $patron Patron data
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array         On success, an associative array with the following
      * keys: id, availability (boolean), status, location, reserve, callnumber,
@@ -576,7 +576,7 @@ class Unicorn extends AbstractBase implements \VuFindHttp\HttpServiceAwareInterf
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return mixed        Array of the patron's fines on success.
      */
@@ -634,7 +634,7 @@ class Unicorn extends AbstractBase implements \VuFindHttp\HttpServiceAwareInterf
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's holds on success.
      */
@@ -761,7 +761,7 @@ class Unicorn extends AbstractBase implements \VuFindHttp\HttpServiceAwareInterf
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's transactions on success.
      */
diff --git a/module/VuFind/src/VuFind/ILS/Driver/Virtua.php b/module/VuFind/src/VuFind/ILS/Driver/Virtua.php
index 0a86f61a33d..c71de284dc6 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/Virtua.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/Virtua.php
@@ -326,7 +326,7 @@ class Virtua extends AbstractBase implements \VuFindHttp\HttpServiceAwareInterfa
      * @param string $id     The record id to retrieve the holdings for
      * @param array  $patron Patron data
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array         On success, an associative array with the following
      * keys: id, availability (boolean), status, location, reserve, callnumber,
@@ -1240,7 +1240,7 @@ class Virtua extends AbstractBase implements \VuFindHttp\HttpServiceAwareInterfa
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return mixed        Array of the patron's fines on success.
      */
@@ -1281,7 +1281,7 @@ class Virtua extends AbstractBase implements \VuFindHttp\HttpServiceAwareInterfa
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's holds on success.
      */
@@ -1320,7 +1320,7 @@ class Virtua extends AbstractBase implements \VuFindHttp\HttpServiceAwareInterfa
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's transactions on success.
      */
diff --git a/module/VuFind/src/VuFind/ILS/Driver/Voyager.php b/module/VuFind/src/VuFind/ILS/Driver/Voyager.php
index 8c86e40f4ef..cc7992e3f0f 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/Voyager.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/Voyager.php
@@ -33,7 +33,7 @@ namespace VuFind\ILS\Driver;
 use File_MARC;
 use PDO;
 use PDOException;
-use VuFind\Exception\Date as DateException;
+use VuFind\Date\DateException;
 use VuFind\Exception\ILS as ILSException;
 use VuFind\I18n\Translator\TranslatorAwareInterface;
 use Yajra\Pdo\Oci8;
diff --git a/module/VuFind/src/VuFind/ILS/Driver/VoyagerRestful.php b/module/VuFind/src/VuFind/ILS/Driver/VoyagerRestful.php
index 6970f6a380f..92921883d2c 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/VoyagerRestful.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/VoyagerRestful.php
@@ -33,7 +33,7 @@ namespace VuFind\ILS\Driver;
 
 use PDO;
 use PDOException;
-use VuFind\Exception\Date as DateException;
+use VuFind\Date\DateException;
 use VuFind\Exception\ILS as ILSException;
 
 /**
diff --git a/module/VuFind/src/VuFind/ILS/Driver/XCNCIP2.php b/module/VuFind/src/VuFind/ILS/Driver/XCNCIP2.php
index 0ae314ba119..e7c7d2101f6 100644
--- a/module/VuFind/src/VuFind/ILS/Driver/XCNCIP2.php
+++ b/module/VuFind/src/VuFind/ILS/Driver/XCNCIP2.php
@@ -489,7 +489,7 @@ class XCNCIP2 extends AbstractBase implements \VuFindHttp\HttpServiceAwareInterf
      * @param array  $patron Patron data
      * @param array  $ids    The (consortial) source records for the record id
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array         On success, an associative array with the following
      * keys: id, availability (boolean), status, location, reserve, callnumber,
@@ -568,7 +568,7 @@ class XCNCIP2 extends AbstractBase implements \VuFindHttp\HttpServiceAwareInterf
      * @param string $id     The record id to retrieve the holdings for
      * @param array  $patron Patron data
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array         On success, an associative array with the following
      * keys: id, availability (boolean), status, location, reserve, callnumber,
@@ -672,7 +672,7 @@ class XCNCIP2 extends AbstractBase implements \VuFindHttp\HttpServiceAwareInterf
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's transactions on success.
      */
@@ -732,7 +732,7 @@ class XCNCIP2 extends AbstractBase implements \VuFindHttp\HttpServiceAwareInterf
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return mixed        Array of the patron's fines on success.
      */
@@ -794,7 +794,7 @@ class XCNCIP2 extends AbstractBase implements \VuFindHttp\HttpServiceAwareInterf
      *
      * @param array $patron The patron array from patronLogin
      *
-     * @throws \VuFind\Exception\Date
+     * @throws VuFind\Date\DateException;
      * @throws ILSException
      * @return array        Array of the patron's holds on success.
      */
diff --git a/module/VuFind/src/VuFind/Service/DateConverterFactory.php b/module/VuFind/src/VuFind/Service/DateConverterFactory.php
new file mode 100644
index 00000000000..2df544f7bad
--- /dev/null
+++ b/module/VuFind/src/VuFind/Service/DateConverterFactory.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Factory for \VuFind\Date\Converter
+ *
+ * PHP version 7
+ *
+ * Copyright (C) Villanova University 2018.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * @category VuFind
+ * @package  Service
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development Wiki
+ */
+namespace VuFind\Service;
+
+use Interop\Container\ContainerInterface;
+use Zend\ServiceManager\Factory\FactoryInterface;
+
+/**
+ * Factory for \VuFind\Date\Converter
+ *
+ * @category VuFind
+ * @package  Service
+ * @author   Demian Katz <demian.katz@villanova.edu>
+ * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
+ * @link     https://vufind.org/wiki/development Wiki
+ */
+class DateConverterFactory implements FactoryInterface
+{
+    /**
+     * Create an object
+     *
+     * @param ContainerInterface $container     Service manager
+     * @param string             $requestedName Service being created
+     * @param null|array         $options       Extra options (optional)
+     *
+     * @return object
+     *
+     * @throws ServiceNotFoundException if unable to resolve the service.
+     * @throws ServiceNotCreatedException if an exception is raised when
+     * creating a service.
+     * @throws ContainerException if any other error occurs
+     */
+    public function __invoke(ContainerInterface $container, $requestedName,
+        array $options = null
+    ) {
+        if (!empty($options)) {
+            throw new \Exception('Unexpected options passed to factory.');
+        }
+        // Pass along key [Site] settings: displayDateFormat, displayTimeFormat,
+        // timezone
+        $config = $container->get('VuFind\Config\PluginManager')->get('config');
+        $settings = isset($config->Site) ? $config->Site->toArray() : [];
+        return new $requestedName($settings);
+    }
+}
diff --git a/module/VuFind/src/VuFind/View/Helper/Root/Citation.php b/module/VuFind/src/VuFind/View/Helper/Root/Citation.php
index c3a2ffc529c..dff3e52860b 100644
--- a/module/VuFind/src/VuFind/View/Helper/Root/Citation.php
+++ b/module/VuFind/src/VuFind/View/Helper/Root/Citation.php
@@ -27,7 +27,7 @@
  */
 namespace VuFind\View\Helper\Root;
 
-use VuFind\Exception\Date as DateException;
+use VuFind\Date\DateException;
 
 /**
  * Citation view helper
diff --git a/module/VuFind/src/VuFind/View/Helper/Root/DateTime.php b/module/VuFind/src/VuFind/View/Helper/Root/DateTime.php
index 8fe27dee242..3dd5139b9b7 100644
--- a/module/VuFind/src/VuFind/View/Helper/Root/DateTime.php
+++ b/module/VuFind/src/VuFind/View/Helper/Root/DateTime.php
@@ -67,7 +67,7 @@ class DateTime extends \Zend\View\Helper\AbstractHelper
     {
         try {
             return $this->converter->convertFromDisplayDate('Y', $date);
-        } catch (\VuFind\Exception\Date $e) {
+        } catch (\VuFind\Date\DateException $e) {
             // bad date? just ignore it!
             return false;
         }
diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Date/ConverterTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Date/ConverterTest.php
deleted file mode 100644
index 9e5d81a2289..00000000000
--- a/module/VuFind/tests/unit-tests/src/VuFindTest/Date/ConverterTest.php
+++ /dev/null
@@ -1,149 +0,0 @@
-<?php
-/**
- * VuFindDate Test Class
- *
- * PHP version 7
- *
- * Copyright (C) Villanova University 2011.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * @category VuFind
- * @package  Tests
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org Main Page
- */
-namespace VuFindTest\Date;
-
-use VuFind\Date\Converter;
-use VuFind\Exception\Date as DateException;
-use Zend\Config\Config;
-
-/**
- * VuFindDate Test Class
- *
- * @category VuFind
- * @package  Tests
- * @author   Demian Katz <demian.katz@villanova.edu>
- * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
- * @link     https://vufind.org Main Page
- */
-class ConverterTest extends \VuFindTest\Unit\TestCase
-{
-    protected $savedDateFormat = null;
-    protected $savedTimeFormat = null;
-
-    /**
-     * Test citation generation
-     *
-     * @return void
-     */
-    public function testDates()
-    {
-        // Get current default time zone
-        $real_zone = date_default_timezone_get();
-
-        // Try all the tests in different time zones to ensure consistency:
-        foreach (['America/New_York', 'Europe/Helsinki'] as $zone) {
-            date_default_timezone_set($zone);
-            $this->runTests();
-        }
-
-        // Restore original time zone
-        date_default_timezone_set($real_zone);
-    }
-
-    /**
-     * Support method for testDates()
-     *
-     * @return void
-     */
-    protected function runTests()
-    {
-        // Build an object to test with (using empty configuration to ensure default
-        // settings):
-        $date = new Converter(new Config([]));
-
-        // Try some conversions:
-        $this->assertEquals(
-            '11-29-1973', $date->convertToDisplayDate('U', 123456879)
-        );
-        $this->assertEquals(
-            '11-29-1973', $date->convertToDisplayDate('U', 123456879.1234)
-        );
-        $this->assertEquals(
-            '11-29-1973--16:34',
-            $date->convertToDisplayDateAndTime('U', 123456879, '--')
-        );
-        $this->assertEquals(
-            '16:34 11-29-1973', $date->convertToDisplayTimeAndDate('U', 123456879)
-        );
-        $this->assertEquals(
-            '11-29-1973', $date->convertToDisplayDate('m-d-y', '11-29-73')
-        );
-        $this->assertEquals(
-            '11-29-1973', $date->convertToDisplayDate('m-d-y', '11-29-1973')
-        );
-        $this->assertEquals(
-            '11-29-1973', $date->convertToDisplayDate('m-d-y H:i', '11-29-73 23:01')
-        );
-        $this->assertEquals(
-            '23:01', $date->convertToDisplayTime('m-d-y H:i', '11-29-73 23:01')
-        );
-        $this->assertEquals(
-            '01-02-2001', $date->convertToDisplayDate('m-d-y', '01-02-01')
-        );
-        $this->assertEquals(
-            '01-02-2001', $date->convertToDisplayDate('m-d-y', '01-02-2001')
-        );
-        $this->assertEquals(
-            '01-02-2001', $date->convertToDisplayDate('m-d-y H:i', '01-02-01 05:11')
-        );
-        $this->assertEquals(
-            '05:11', $date->convertToDisplayTime('m-d-y H:i', '01-02-01 05:11')
-        );
-        $this->assertEquals(
-            '01-02-2001', $date->convertToDisplayDate('Y-m-d', '2001-01-02')
-        );
-        $this->assertEquals(
-            '01-02-2001',
-            $date->convertToDisplayDate('Y-m-d H:i', '2001-01-02 05:11')
-        );
-        $this->assertEquals(
-            '05:11', $date->convertToDisplayTime('Y-m-d H:i', '2001-01-02 05:11')
-        );
-        $this->assertEquals(
-            '01-2001', $date->convertFromDisplayDate('m-Y', '01-02-2001')
-        );
-
-        // Check for proper handling of known problems:
-        try {
-            $bad = $date->convertToDisplayDate('U', 'invalid');
-            $this->fail('Expected exception did not occur');
-        } catch (DateException $e) {
-            $this->assertTrue(
-                (bool)stristr($e->getMessage(), 'failed to parse time string')
-            );
-        }
-        try {
-            $bad = $date->convertToDisplayDate('d-m-Y', '31-02-2001');
-            $this->fail('Expected exception did not occur');
-        } catch (DateException $e) {
-            $this->assertTrue(
-                (bool)stristr($e->getMessage(), 'parsed date was invalid')
-            );
-        }
-    }
-}
-- 
GitLab