Remove odd assertion stopping TZ minutes being more than 30 or less than -30 (DoM...
[libdcp.git] / test / local_time_test.cc
index 0d498771c18ba9185e91be19e8ea782cb6613424..8d6d997eec8852375ad9b739229e3bcbc123c092 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014-2020 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2021 Carl Hetherington <cth@carlh.net>
 
     This file is part of libdcp.
 
     files in the program, then also delete it here.
 */
 
-#include <boost/test/unit_test.hpp>
-#include "local_time.h"
+
 #include "exceptions.h"
+#include "local_time.h"
+#include <boost/test/unit_test.hpp>
+
 
 /** Check that dcp::LocalTime works */
 BOOST_AUTO_TEST_CASE (local_time_basic_test)
@@ -48,6 +50,18 @@ BOOST_AUTO_TEST_CASE (local_time_basic_test)
 
        /* Correctly-formatted */
 
+       {
+               dcp::LocalTime t("2013-01-05T18:06:59");
+               BOOST_CHECK_EQUAL(t._year, 2013);
+               BOOST_CHECK_EQUAL(t._month, 1);
+               BOOST_CHECK_EQUAL(t._day, 5);
+               BOOST_CHECK_EQUAL(t._hour, 18);
+               BOOST_CHECK_EQUAL(t._minute, 6);
+               BOOST_CHECK_EQUAL(t._second, 59);
+               BOOST_CHECK(t._offset == dcp::UTCOffset(0, 0));
+               BOOST_CHECK_EQUAL(t.as_string(), "2013-01-05T18:06:59+00:00");
+       }
+
        {
                dcp::LocalTime t ("2013-01-05T18:06:59+04:00");
                BOOST_CHECK_EQUAL (t._year, 2013);
@@ -56,8 +70,7 @@ BOOST_AUTO_TEST_CASE (local_time_basic_test)
                BOOST_CHECK_EQUAL (t._hour, 18);
                BOOST_CHECK_EQUAL (t._minute, 6);
                BOOST_CHECK_EQUAL (t._second, 59);
-               BOOST_CHECK_EQUAL (t._tz_hour, 4);
-               BOOST_CHECK_EQUAL (t._tz_minute, 0);
+               BOOST_CHECK(t._offset == dcp::UTCOffset(4, 0));
                BOOST_CHECK_EQUAL (t.as_string(), "2013-01-05T18:06:59+04:00");
        }
 
@@ -69,8 +82,7 @@ BOOST_AUTO_TEST_CASE (local_time_basic_test)
                BOOST_CHECK_EQUAL (t._hour, 1);
                BOOST_CHECK_EQUAL (t._minute, 6);
                BOOST_CHECK_EQUAL (t._second, 59);
-               BOOST_CHECK_EQUAL (t._tz_hour, -9);
-               BOOST_CHECK_EQUAL (t._tz_minute, -30);
+               BOOST_CHECK(t._offset == dcp::UTCOffset(-9, -30));
                BOOST_CHECK_EQUAL (t.as_string(), "2011-11-20T01:06:59-09:30");
        }
 
@@ -83,11 +95,50 @@ BOOST_AUTO_TEST_CASE (local_time_basic_test)
                BOOST_CHECK_EQUAL (t._minute, 6);
                BOOST_CHECK_EQUAL (t._second, 59);
                BOOST_CHECK_EQUAL (t._millisecond, 456);
-               BOOST_CHECK_EQUAL (t._tz_hour, -9);
-               BOOST_CHECK_EQUAL (t._tz_minute, -30);
+               BOOST_CHECK(t._offset == dcp::UTCOffset(-9, -30));
                BOOST_CHECK_EQUAL (t.as_string(true), "2011-11-20T01:06:59.456-09:30");
        }
 
+       {
+               dcp::LocalTime t ("2011-11-20T01:06:59.456-09:30");
+               BOOST_CHECK_EQUAL (t._year, 2011);
+               BOOST_CHECK_EQUAL (t._month, 11);
+               BOOST_CHECK_EQUAL (t._day, 20);
+               BOOST_CHECK_EQUAL (t._hour, 1);
+               BOOST_CHECK_EQUAL (t._minute, 6);
+               BOOST_CHECK_EQUAL (t._second, 59);
+               BOOST_CHECK_EQUAL (t._millisecond, 456);
+               BOOST_CHECK(t._offset == dcp::UTCOffset(-9, -30));
+               BOOST_CHECK_EQUAL (t.as_string(true, false), "2011-11-20T01:06:59.456");
+       }
+
+       {
+               dcp::LocalTime t ("2011-11-20T01:06:59.456-09:30");
+               BOOST_CHECK_EQUAL (t._year, 2011);
+               BOOST_CHECK_EQUAL (t._month, 11);
+               BOOST_CHECK_EQUAL (t._day, 20);
+               BOOST_CHECK_EQUAL (t._hour, 1);
+               BOOST_CHECK_EQUAL (t._minute, 6);
+               BOOST_CHECK_EQUAL (t._second, 59);
+               BOOST_CHECK_EQUAL (t._millisecond, 456);
+               BOOST_CHECK(t._offset == dcp::UTCOffset(-9, -30));
+               BOOST_CHECK_EQUAL (t.as_string(false, false), "2011-11-20T01:06:59");
+       }
+
+       {
+               dcp::LocalTime t("2011-11-20T01:06:59.45678901-09:30");
+               BOOST_CHECK_EQUAL(t._year, 2011);
+               BOOST_CHECK_EQUAL(t._month, 11);
+               BOOST_CHECK_EQUAL(t._day, 20);
+               BOOST_CHECK_EQUAL(t._hour, 1);
+               BOOST_CHECK_EQUAL(t._minute, 6);
+               BOOST_CHECK_EQUAL(t._second, 59);
+               /* The fractional seconds here is truncated rather than rounded, for better or worse */
+               BOOST_CHECK_EQUAL(t._millisecond, 456);
+               BOOST_CHECK(t._offset == dcp::UTCOffset(-9, -30));
+               BOOST_CHECK_EQUAL(t.as_string(false, false), "2011-11-20T01:06:59");
+       }
+
        {
                /* Construction from boost::posix_time::ptime */
                dcp::LocalTime b (boost::posix_time::time_from_string ("2002-01-20 19:03:56"));
@@ -120,8 +171,7 @@ BOOST_AUTO_TEST_CASE (local_time_basic_test)
                BOOST_CHECK_EQUAL (b._minute, 26);
                BOOST_CHECK_EQUAL (b._second, 45);
                BOOST_CHECK_EQUAL (b._millisecond, 0);
-               BOOST_CHECK_EQUAL (b._tz_hour, 0);
-               BOOST_CHECK_EQUAL (b._tz_minute, 0);
+               BOOST_CHECK(b._offset == dcp::UTCOffset());
        }
 
        /* Check negative times with non-zero timezone offset minutes */
@@ -133,13 +183,29 @@ BOOST_AUTO_TEST_CASE (local_time_basic_test)
                BOOST_CHECK_EQUAL (t._hour, 18);
                BOOST_CHECK_EQUAL (t._minute, 6);
                BOOST_CHECK_EQUAL (t._second, 59);
-               BOOST_CHECK_EQUAL (t._tz_hour, -4);
-               BOOST_CHECK_EQUAL (t._tz_minute, -30);
+               BOOST_CHECK(t._offset == dcp::UTCOffset(-4, -30));
                BOOST_CHECK_EQUAL (t.as_string(), "2013-01-05T18:06:59-04:30");
        }
+
+       /* KDM seen with a TZ offset of -07:59, which we used to reject because
+        * we only accepted minutes between -30 and +30 (for some reason that I
+        * now can't find).
+        */
+       {
+               dcp::LocalTime t("2023-11-30T23:59:00-07:59");
+               BOOST_CHECK_EQUAL(t._year, 2023);
+               BOOST_CHECK_EQUAL(t._month, 11);
+               BOOST_CHECK_EQUAL(t._day, 30);
+               BOOST_CHECK_EQUAL(t._hour, 23);
+               BOOST_CHECK_EQUAL(t._minute, 59);
+               BOOST_CHECK_EQUAL(t._second, 00);
+               BOOST_CHECK(t._offset == dcp::UTCOffset(-7, -59));
+               BOOST_CHECK_EQUAL(t.as_string(), "2023-11-30T23:59:00-07:59");
+       }
 }
 
-BOOST_AUTO_TEST_CASE (local_time_addition_test)
+
+BOOST_AUTO_TEST_CASE (local_time_add_minutes_test)
 {
        {
                dcp::LocalTime t("2018-01-01T10:00:00+01:00");
@@ -176,5 +242,83 @@ BOOST_AUTO_TEST_CASE (local_time_addition_test)
                t.add_minutes (7);
                BOOST_CHECK_EQUAL (t.as_string(), "2018-02-01T00:02:00+01:00");
        }
+
+       {
+               dcp::LocalTime t("2018-01-31T23:55:00.123");
+               t.add_minutes (7);
+               BOOST_CHECK_EQUAL (t, dcp::LocalTime("2018-02-01T00:02:00.123"));
+       }
+}
+
+
+BOOST_AUTO_TEST_CASE (local_time_add_months_test)
+{
+       {
+               dcp::LocalTime t("2013-06-23T18:06:59.123");
+               t.add_months(-1);
+               BOOST_CHECK_EQUAL (t, dcp::LocalTime("2013-05-23T18:06:59.123"));
+               t.add_months(1);
+               BOOST_CHECK_EQUAL (t, dcp::LocalTime("2013-06-23T18:06:59.123"));
+               t.add_months(1);
+               BOOST_CHECK_EQUAL (t, dcp::LocalTime("2013-07-23T18:06:59.123"));
+               t.add_months(4);
+               BOOST_CHECK_EQUAL (t, dcp::LocalTime("2013-11-23T18:06:59.123"));
+               t.add_months(2);
+               BOOST_CHECK_EQUAL (t, dcp::LocalTime("2014-01-23T18:06:59.123"));
+               t.add_months(-14);
+               BOOST_CHECK_EQUAL (t, dcp::LocalTime("2012-11-23T18:06:59.123"));
+               t.add_months(14);
+               BOOST_CHECK_EQUAL (t, dcp::LocalTime("2014-01-23T18:06:59.123"));
+       }
+
+       {
+               dcp::LocalTime t("2018-01-30T11:00:00+01:00");
+               t.add_months (1);
+               BOOST_CHECK_EQUAL (t.as_string(), "2018-02-28T11:00:00+01:00");
+       }
+}
+
+
+BOOST_AUTO_TEST_CASE (local_time_from_asn1_utctime_test)
+{
+       BOOST_CHECK_EQUAL (dcp::LocalTime::from_asn1_utc_time("991231235952").as_string(), "1999-12-31T23:59:52+00:00");
+       BOOST_CHECK_EQUAL (dcp::LocalTime::from_asn1_utc_time("210215165952").as_string(), "2021-02-15T16:59:52+00:00");
+}
+
+
+BOOST_AUTO_TEST_CASE (local_time_from_asn1_generalized_time_test)
+{
+       BOOST_CHECK_EQUAL (dcp::LocalTime::from_asn1_generalized_time("19991231235952").as_string(), "1999-12-31T23:59:52+00:00");
+       BOOST_CHECK_EQUAL (dcp::LocalTime::from_asn1_generalized_time("20210215165952").as_string(), "2021-02-15T16:59:52+00:00");
 }
 
+
+BOOST_AUTO_TEST_CASE(local_time_comparison_test)
+{
+       BOOST_CHECK(dcp::LocalTime("2014-01-01T10:00:00") < dcp::LocalTime("2014-01-01T10:05:00"));
+       BOOST_CHECK(dcp::LocalTime("2014-01-01T10:00:00") < dcp::LocalTime("2015-01-01T10:00:00"));
+       BOOST_CHECK(dcp::LocalTime("2014-01-01T10:00:00") < dcp::LocalTime("2014-01-01T11:00:00"));
+       BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:00") < dcp::LocalTime("2014-10-10T10:00:01"));
+       BOOST_CHECK(!(dcp::LocalTime("2014-10-10T10:00:00") < dcp::LocalTime("2014-10-10T10:00:00")));
+       BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:00+01:00") < dcp::LocalTime("2014-10-10T10:00:00"));
+       BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:00+01:30") < dcp::LocalTime("2014-10-10T10:00:00"));
+       BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:00+01:00") < dcp::LocalTime("2014-10-10T10:00:01+01:00"));
+       BOOST_CHECK(dcp::LocalTime("2014-01-01T10:00:00") < dcp::LocalTime("2014-01-01T10:05:00"));
+       BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:00") < dcp::LocalTime("2014-10-10T10:00:00-01:30"));
+
+       BOOST_CHECK(dcp::LocalTime("2014-01-01T10:05:00") > dcp::LocalTime("2014-01-01T10:00:00"));
+       BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:00-01:30") > dcp::LocalTime("2014-10-10T10:00:00"));
+       BOOST_CHECK(dcp::LocalTime("2014-01-01T10:05:00") > dcp::LocalTime("2014-01-01T10:00:00"));
+       BOOST_CHECK(dcp::LocalTime("2015-01-01T10:00:00") > dcp::LocalTime("2014-01-01T10:00:00"));
+       BOOST_CHECK(dcp::LocalTime("2014-01-01T11:00:00") > dcp::LocalTime("2014-01-01T10:00:00"));
+       BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:01") > dcp::LocalTime("2014-10-10T10:00:00"));
+       BOOST_CHECK(!(dcp::LocalTime("2014-10-10T10:00:00") > dcp::LocalTime("2014-10-10T10:00:00")));
+       BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:00") > dcp::LocalTime("2014-10-10T10:00:00+01:00"));
+       BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:00") > dcp::LocalTime("2014-10-10T10:00:00+01:30"));
+       BOOST_CHECK(dcp::LocalTime("2014-10-10T10:00:01+01:00") > dcp::LocalTime("2014-10-10T10:00:00+01:00"));
+
+       BOOST_CHECK(dcp::LocalTime("2014-01-01T10:00:00") != dcp::LocalTime("2014-01-01T10:05:00"));
+       BOOST_CHECK(dcp::LocalTime("2014-01-01T10:00:00") == dcp::LocalTime("2014-01-01T10:00:00"));
+       BOOST_CHECK(dcp::LocalTime("2014-01-01T10:00:00+02:00") == dcp::LocalTime("2014-01-01T08:00:00"));
+       BOOST_CHECK(dcp::LocalTime("2014-01-01T10:00:00+02:00") == dcp::LocalTime("2014-01-01T11:00:00+03:00"));
+}