def test_ewsdatetime(self):
        # Test a static timezone
        tz = EWSTimeZone('Etc/GMT-5')
        dt = EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=tz)
        self.assertIsInstance(dt, EWSDateTime)
        self.assertIsInstance(dt.tzinfo, EWSTimeZone)
        self.assertEqual(dt.tzinfo.ms_id, tz.ms_id)
        self.assertEqual(dt.tzinfo.ms_name, tz.ms_name)
        self.assertEqual(str(dt), '2000-01-02 03:04:05+05:00')
        self.assertEqual(
            repr(dt),
            "EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=EWSTimeZone(key='Etc/GMT-5'))"
        )

        # Test a DST timezone
        tz = EWSTimeZone('Europe/Copenhagen')
        dt = EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=tz)
        self.assertIsInstance(dt, EWSDateTime)
        self.assertIsInstance(dt.tzinfo, EWSTimeZone)
        self.assertEqual(dt.tzinfo.ms_id, tz.ms_id)
        self.assertEqual(dt.tzinfo.ms_name, tz.ms_name)
        self.assertEqual(str(dt), '2000-01-02 03:04:05+01:00')
        self.assertEqual(
            repr(dt),
            "EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=EWSTimeZone(key='Europe/Copenhagen'))"
        )

        # Test from_string
        with self.assertRaises(NaiveDateTimeNotAllowed):
            EWSDateTime.from_string('2000-01-02T03:04:05')
        self.assertEqual(EWSDateTime.from_string('2000-01-02T03:04:05+01:00'),
                         EWSDateTime(2000, 1, 2, 2, 4, 5, tzinfo=UTC))
        self.assertEqual(EWSDateTime.from_string('2000-01-02T03:04:05Z'),
                         EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=UTC))
        self.assertIsInstance(
            EWSDateTime.from_string('2000-01-02T03:04:05+01:00'), EWSDateTime)
        self.assertIsInstance(EWSDateTime.from_string('2000-01-02T03:04:05Z'),
                              EWSDateTime)

        # Test addition, subtraction, summertime etc
        self.assertIsInstance(dt + datetime.timedelta(days=1), EWSDateTime)
        self.assertIsInstance(dt - datetime.timedelta(days=1), EWSDateTime)
        self.assertIsInstance(dt - EWSDateTime.now(tz=tz), datetime.timedelta)
        self.assertIsInstance(EWSDateTime.now(tz=tz), EWSDateTime)

        # Test various input for from_datetime()
        self.assertEqual(
            dt,
            EWSDateTime.from_datetime(
                datetime.datetime(2000,
                                  1,
                                  2,
                                  3,
                                  4,
                                  5,
                                  tzinfo=EWSTimeZone('Europe/Copenhagen'))))
        self.assertEqual(
            dt,
            EWSDateTime.from_datetime(
                datetime.datetime(
                    2000,
                    1,
                    2,
                    3,
                    4,
                    5,
                    tzinfo=zoneinfo.ZoneInfo('Europe/Copenhagen'))))
        self.assertEqual(
            dt,
            EWSDateTime.from_datetime(
                datetime.datetime(
                    2000,
                    1,
                    2,
                    3,
                    4,
                    5,
                    tzinfo=dateutil.tz.gettz('Europe/Copenhagen'))))
        self.assertEqual(
            dt,
            EWSDateTime.from_datetime(
                datetime.datetime(2000,
                                  1,
                                  2,
                                  3,
                                  4,
                                  5,
                                  tzinfo=pytz.timezone('Europe/Copenhagen'))))

        self.assertEqual(dt.ewsformat(), '2000-01-02T03:04:05+01:00')
        utc_tz = EWSTimeZone('UTC')
        self.assertEqual(
            dt.astimezone(utc_tz).ewsformat(), '2000-01-02T02:04:05Z')
        # Test summertime
        dt = EWSDateTime(2000, 8, 2, 3, 4, 5, tzinfo=tz)
        self.assertEqual(
            dt.astimezone(utc_tz).ewsformat(), '2000-08-02T01:04:05Z')

        # Test in-place add and subtract
        dt = EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=tz)
        dt += datetime.timedelta(days=1)
        self.assertIsInstance(dt, EWSDateTime)
        self.assertEqual(dt, EWSDateTime(2000, 1, 3, 3, 4, 5, tzinfo=tz))
        dt = EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=tz)
        dt -= datetime.timedelta(days=1)
        self.assertIsInstance(dt, EWSDateTime)
        self.assertEqual(dt, EWSDateTime(2000, 1, 1, 3, 4, 5, tzinfo=tz))

        # Test ewsformat() failure
        dt = EWSDateTime(2000, 1, 2, 3, 4, 5)
        with self.assertRaises(ValueError):
            dt.ewsformat()
        # Test wrong tzinfo type
        with self.assertRaises(ValueError):
            EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=zoneinfo.ZoneInfo('UTC'))
        with self.assertRaises(ValueError):
            EWSDateTime.from_datetime(EWSDateTime(2000, 1, 2, 3, 4, 5))
    def test_ewsdatetime(self):
        # Test a static timezone
        tz = EWSTimeZone.timezone('Etc/GMT-5')
        dt = tz.localize(EWSDateTime(2000, 1, 2, 3, 4, 5))
        self.assertIsInstance(dt, EWSDateTime)
        self.assertIsInstance(dt.tzinfo, EWSTimeZone)
        self.assertEqual(dt.tzinfo.ms_id, tz.ms_id)
        self.assertEqual(dt.tzinfo.ms_name, tz.ms_name)
        self.assertEqual(str(dt), '2000-01-02 03:04:05+05:00')
        self.assertEqual(
            repr(dt),
            "EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=<StaticTzInfo 'Etc/GMT-5'>)"
        )

        # Test a DST timezone
        tz = EWSTimeZone.timezone('Europe/Copenhagen')
        dt = tz.localize(EWSDateTime(2000, 1, 2, 3, 4, 5))
        self.assertIsInstance(dt, EWSDateTime)
        self.assertIsInstance(dt.tzinfo, EWSTimeZone)
        self.assertEqual(dt.tzinfo.ms_id, tz.ms_id)
        self.assertEqual(dt.tzinfo.ms_name, tz.ms_name)
        self.assertEqual(str(dt), '2000-01-02 03:04:05+01:00')
        self.assertEqual(
            repr(dt),
            "EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=<DstTzInfo 'Europe/Copenhagen' CET+1:00:00 STD>)"
        )

        # Test from_string
        with self.assertRaises(NaiveDateTimeNotAllowed):
            EWSDateTime.from_string('2000-01-02T03:04:05')
        self.assertEqual(EWSDateTime.from_string('2000-01-02T03:04:05+01:00'),
                         UTC.localize(EWSDateTime(2000, 1, 2, 2, 4, 5)))
        self.assertEqual(EWSDateTime.from_string('2000-01-02T03:04:05Z'),
                         UTC.localize(EWSDateTime(2000, 1, 2, 3, 4, 5)))
        self.assertIsInstance(
            EWSDateTime.from_string('2000-01-02T03:04:05+01:00'), EWSDateTime)
        self.assertIsInstance(EWSDateTime.from_string('2000-01-02T03:04:05Z'),
                              EWSDateTime)

        # Test addition, subtraction, summertime etc
        self.assertIsInstance(dt + datetime.timedelta(days=1), EWSDateTime)
        self.assertIsInstance(dt - datetime.timedelta(days=1), EWSDateTime)
        self.assertIsInstance(dt - EWSDateTime.now(tz=tz), datetime.timedelta)
        self.assertIsInstance(EWSDateTime.now(tz=tz), EWSDateTime)
        self.assertEqual(
            dt,
            EWSDateTime.from_datetime(
                tz.localize(datetime.datetime(2000, 1, 2, 3, 4, 5))))
        self.assertEqual(dt.ewsformat(), '2000-01-02T03:04:05+01:00')
        utc_tz = EWSTimeZone.timezone('UTC')
        self.assertEqual(
            dt.astimezone(utc_tz).ewsformat(), '2000-01-02T02:04:05Z')
        # Test summertime
        dt = tz.localize(EWSDateTime(2000, 8, 2, 3, 4, 5))
        self.assertEqual(
            dt.astimezone(utc_tz).ewsformat(), '2000-08-02T01:04:05Z')
        # Test normalize, for completeness
        self.assertEqual(
            tz.normalize(dt).ewsformat(), '2000-08-02T03:04:05+02:00')
        self.assertEqual(
            utc_tz.normalize(dt, is_dst=True).ewsformat(),
            '2000-08-02T01:04:05Z')

        # Test in-place add and subtract
        dt = tz.localize(EWSDateTime(2000, 1, 2, 3, 4, 5))
        dt += datetime.timedelta(days=1)
        self.assertIsInstance(dt, EWSDateTime)
        self.assertEqual(dt, tz.localize(EWSDateTime(2000, 1, 3, 3, 4, 5)))
        dt = tz.localize(EWSDateTime(2000, 1, 2, 3, 4, 5))
        dt -= datetime.timedelta(days=1)
        self.assertIsInstance(dt, EWSDateTime)
        self.assertEqual(dt, tz.localize(EWSDateTime(2000, 1, 1, 3, 4, 5)))

        # Test ewsformat() failure
        dt = EWSDateTime(2000, 1, 2, 3, 4, 5)
        with self.assertRaises(ValueError):
            dt.ewsformat()
        # Test wrong tzinfo type
        with self.assertRaises(ValueError):
            EWSDateTime(2000, 1, 2, 3, 4, 5, tzinfo=pytz.utc)
        with self.assertRaises(ValueError):
            EWSDateTime.from_datetime(EWSDateTime(2000, 1, 2, 3, 4, 5))