oc-develop_oneteam/venv/lib/python3.11/site-packages/DateTime/tests/test_datetime.py
2024-02-03 21:52:43 -05:00

747 lines
29 KiB
Python

##############################################################################
#
# Copyright (c) 2003 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
import math
import os
import pickle
import platform
import sys
import time
import unittest
from datetime import date
from datetime import datetime
from datetime import timedelta
from datetime import tzinfo
import pytz
from DateTime import DateTime
from DateTime.DateTime import _findLocalTimeZoneName
try:
__file__
except NameError: # pragma: no cover
f = sys.argv[0]
else:
f = __file__
IS_PYPY = getattr(platform, 'python_implementation', lambda: None)() == 'PyPy'
DATADIR = os.path.dirname(os.path.abspath(f))
del f
ZERO = timedelta(0)
class FixedOffset(tzinfo):
"""Fixed offset in minutes east from UTC."""
def __init__(self, offset, name):
self.__offset = timedelta(minutes=offset)
self.__name = name
def utcoffset(self, dt):
return self.__offset
def tzname(self, dt):
return self.__name
def dst(self, dt):
return ZERO
class DateTimeTests(unittest.TestCase):
def _compare(self, dt1, dt2):
'''Compares the internal representation of dt1 with
the representation in dt2. Allows sub-millisecond variations.
Primarily for testing.'''
self.assertEqual(round(dt1._t, 3), round(dt2._t, 3))
self.assertEqual(round(dt1._d, 9), round(dt2._d, 9))
self.assertEqual(round(dt1.time, 9), round(dt2.time, 9))
self.assertEqual(dt1.millis(), dt2.millis())
self.assertEqual(dt1._micros, dt2._micros)
def testBug1203(self):
# 01:59:60 occurred in old DateTime
dt = DateTime(7200, 'GMT')
self.assertTrue(str(dt).find('60') < 0, dt)
def testDSTInEffect(self):
# Checks GMT offset for a DST date in the US/Eastern time zone
dt = DateTime(2000, 5, 9, 15, 0, 0, 'US/Eastern')
self.assertEqual(dt.toZone('GMT').hour(), 19,
(dt, dt.toZone('GMT')))
def testDSTNotInEffect(self):
# Checks GMT offset for a non-DST date in the US/Eastern time zone
dt = DateTime(2000, 11, 9, 15, 0, 0, 'US/Eastern')
self.assertEqual(dt.toZone('GMT').hour(), 20,
(dt, dt.toZone('GMT')))
def testAddPrecision(self):
# Precision of serial additions
dt = DateTime()
self.assertEqual(str(dt + 0.10 + 3.14 + 6.76 - 10), str(dt),
dt)
# checks problem reported in
# https://github.com/zopefoundation/DateTime/issues/41
dt = DateTime(2038, 10, 7, 8, 52, 44.959840, "UTC")
self.assertEqual(str(dt + 0.10 + 3.14 + 6.76 - 10), str(dt),
dt)
def testConsistentSecondMicroRounding(self):
dt = DateTime(2038, 10, 7, 8, 52, 44.9598398, "UTC")
self.assertEqual(int(dt.second() * 1000000),
dt.micros() % 60000000)
def testConstructor3(self):
# Constructor from date/time string
dt = DateTime()
dt1s = '%d/%d/%d %d:%d:%f %s' % (
dt.year(),
dt.month(),
dt.day(),
dt.hour(),
dt.minute(),
dt.second(),
dt.timezone())
dt1 = DateTime(dt1s)
# Compare representations as it's the
# only way to compare the dates to the same accuracy
self.assertEqual(repr(dt), repr(dt1))
def testConstructor4(self):
# Constructor from time float
dt = DateTime()
dt1 = DateTime(float(dt))
self._compare(dt, dt1)
def testConstructor5(self):
# Constructor from time float and timezone
dt = DateTime()
dt1 = DateTime(float(dt), dt.timezone())
self.assertEqual(str(dt), str(dt1), (dt, dt1))
dt1 = DateTime(float(dt), str(dt.timezone()))
self.assertEqual(str(dt), str(dt1), (dt, dt1))
def testConstructor6(self):
# Constructor from year and julian date
# This test must normalize the time zone, or it *will* break when
# DST changes!
dt1 = DateTime(2000, 5.500000578705)
dt = DateTime('2000/1/5 12:00:00.050 pm %s' % dt1.localZone())
self._compare(dt, dt1)
def testConstructor7(self):
# Constructor from parts
dt = DateTime()
dt1 = DateTime(
dt.year(),
dt.month(),
dt.day(),
dt.hour(),
dt.minute(),
dt.second(),
dt.timezone())
# Compare representations as it's the
# only way to compare the dates to the same accuracy
self.assertEqual(repr(dt), repr(dt1))
def testDayOfWeek(self):
# Compare to the datetime.date value to make it locale independent
expected = date(2000, 6, 16).strftime('%A')
# strftime() used to always be passed a day of week of 0
dt = DateTime('2000/6/16')
s = dt.strftime('%A')
self.assertEqual(s, expected, (dt, s))
def testOldDate(self):
# Fails when an 1800 date is displayed with negative signs
dt = DateTime('1830/5/6 12:31:46.213 pm')
dt1 = dt.toZone('GMT+6')
self.assertTrue(str(dt1).find('-') < 0, (dt, dt1))
def testSubtraction(self):
# Reconstruction of a DateTime from its parts, with subtraction
# this also tests the accuracy of addition and reconstruction
dt = DateTime()
dt1 = dt - 3.141592653
dt2 = DateTime(
dt.year(),
dt.month(),
dt.day(),
dt.hour(),
dt.minute(),
dt.second())
dt3 = dt2 - 3.141592653
self.assertEqual(dt1, dt3, (dt, dt1, dt2, dt3))
def testTZ1add(self):
# Time zone manipulation: add to a date
dt = DateTime('1997/3/8 1:45am GMT-4')
dt1 = DateTime('1997/3/9 1:45pm GMT+8')
self.assertTrue((dt + 1.0).equalTo(dt1))
def testTZ1sub(self):
# Time zone manipulation: subtract from a date
dt = DateTime('1997/3/8 1:45am GMT-4')
dt1 = DateTime('1997/3/9 1:45pm GMT+8')
self.assertTrue((dt1 - 1.0).equalTo(dt))
def testTZ1diff(self):
# Time zone manipulation: diff two dates
dt = DateTime('1997/3/8 1:45am GMT-4')
dt1 = DateTime('1997/3/9 1:45pm GMT+8')
self.assertEqual(dt1 - dt, 1.0, (dt, dt1))
def test_compare_methods(self):
# Compare two dates using several methods
dt = DateTime('1997/1/1')
dt1 = DateTime('1997/2/2')
self.assertTrue(dt1.greaterThan(dt))
self.assertTrue(dt1.greaterThanEqualTo(dt))
self.assertTrue(dt.lessThan(dt1))
self.assertTrue(dt.lessThanEqualTo(dt1))
self.assertTrue(dt.notEqualTo(dt1))
self.assertFalse(dt.equalTo(dt1))
# Compare a date to float
dt = DateTime(1.0)
self.assertTrue(dt == DateTime(1.0)) # testing __eq__
self.assertFalse(dt != DateTime(1.0)) # testing __ne__
self.assertFalse(dt.greaterThan(1.0))
self.assertTrue(dt.greaterThanEqualTo(1.0))
self.assertFalse(dt.lessThan(1.0))
self.assertTrue(dt.lessThanEqualTo(1.0))
self.assertFalse(dt.notEqualTo(1.0))
self.assertTrue(dt.equalTo(1.0))
# Compare a date to int
dt = DateTime(1)
self.assertEqual(dt, DateTime(1.0))
self.assertTrue(dt == DateTime(1)) # testing __eq__
self.assertFalse(dt != DateTime(1)) # testing __ne__
self.assertFalse(dt.greaterThan(1))
self.assertTrue(dt.greaterThanEqualTo(1))
self.assertFalse(dt.lessThan(1))
self.assertTrue(dt.lessThanEqualTo(1))
self.assertFalse(dt.notEqualTo(1))
self.assertTrue(dt.equalTo(1))
# Compare a date to string; there is no implicit type conversion
# but behavior if consistent as when comparing, for example, an int
# and a string.
dt = DateTime("2023")
self.assertFalse(dt == "2023") # testing __eq__
self.assertTrue(dt != "2023") # testing __ne__
self.assertRaises(TypeError, dt.greaterThan, "2023")
self.assertRaises(TypeError, dt.greaterThanEqualTo, "2023")
self.assertRaises(TypeError, dt.lessThan, "2023")
self.assertRaises(TypeError, dt.lessThanEqualTo, "2023")
self.assertTrue(dt.notEqualTo("2023"))
self.assertFalse(dt.equalTo("2023"))
def test_compare_methods_none(self):
# Compare a date to None
for dt in (DateTime('1997/1/1'), DateTime(0)):
self.assertTrue(dt.greaterThan(None))
self.assertTrue(dt.greaterThanEqualTo(None))
self.assertFalse(dt.lessThan(None))
self.assertFalse(dt.lessThanEqualTo(None))
self.assertTrue(dt.notEqualTo(None))
self.assertFalse(dt.equalTo(None))
def test_pickle(self):
dt = DateTime()
data = pickle.dumps(dt, 1)
new = pickle.loads(data)
for key in DateTime.__slots__:
self.assertEqual(getattr(dt, key), getattr(new, key))
def test_pickle_with_tz(self):
dt = DateTime('2002/5/2 8:00am GMT+8')
data = pickle.dumps(dt, 1)
new = pickle.loads(data)
for key in DateTime.__slots__:
self.assertEqual(getattr(dt, key), getattr(new, key))
def test_pickle_asdatetime_with_tz(self):
dt = DateTime('2002/5/2 8:00am GMT+8')
data = pickle.dumps(dt.asdatetime(), 1)
new = DateTime(pickle.loads(data))
for key in DateTime.__slots__:
self.assertEqual(getattr(dt, key), getattr(new, key))
def test_pickle_with_numerical_tz(self):
for dt_str in ('2007/01/02 12:34:56.789 +0300',
'2007/01/02 12:34:56.789 +0430',
'2007/01/02 12:34:56.789 -1234'):
dt = DateTime(dt_str)
data = pickle.dumps(dt, 1)
new = pickle.loads(data)
for key in DateTime.__slots__:
self.assertEqual(getattr(dt, key), getattr(new, key))
def test_pickle_with_micros(self):
dt = DateTime('2002/5/2 8:00:14.123 GMT+8')
data = pickle.dumps(dt, 1)
new = pickle.loads(data)
for key in DateTime.__slots__:
self.assertEqual(getattr(dt, key), getattr(new, key))
def test_pickle_old(self):
dt = DateTime('2002/5/2 8:00am GMT+0')
data = (
'(cDateTime.DateTime\nDateTime\nq\x01Noq\x02}q\x03(U\x05'
'_amonq\x04U\x03Mayq\x05U\x05_adayq\x06U\x03Thuq\x07U\x05_pmonq'
'\x08h\x05U\x05_hourq\tK\x08U\x05_fmonq\nh\x05U\x05_pdayq\x0bU'
'\x04Thu.q\x0cU\x05_fdayq\rU\x08Thursdayq\x0eU\x03_pmq\x0fU\x02amq'
'\x10U\x02_tq\x11GA\xcehy\x00\x00\x00\x00U\x07_minuteq\x12K\x00U'
'\x07_microsq\x13L1020326400000000L\nU\x02_dq\x14G@\xe2\x12j\xaa'
'\xaa\xaa\xabU\x07_secondq\x15G\x00\x00\x00\x00\x00\x00\x00\x00U'
'\x03_tzq\x16U\x05GMT+0q\x17U\x06_monthq\x18K\x05U'
'\x0f_timezone_naiveq\x19I00\nU\x04_dayq\x1aK\x02U\x05_yearq'
'\x1bM\xd2\x07U\x08_nearsecq\x1cG\x00\x00\x00\x00\x00\x00\x00'
'\x00U\x07_pmhourq\x1dK\x08U\n_dayoffsetq\x1eK\x04U\x04timeq'
'\x1fG?\xd5UUUV\x00\x00ub.')
data = data.encode('latin-1')
new = pickle.loads(data)
for key in DateTime.__slots__:
self.assertEqual(getattr(dt, key), getattr(new, key))
def test_pickle_old_without_micros(self):
dt = DateTime('2002/5/2 8:00am GMT+0')
data = (
'(cDateTime.DateTime\nDateTime\nq\x01Noq\x02}q\x03(U\x05'
'_amonq\x04U\x03Mayq\x05U\x05_adayq\x06U\x03Thuq\x07U\x05_pmonq'
'\x08h\x05U\x05_hourq\tK\x08U\x05_fmonq\nh\x05U\x05_pdayq\x0bU'
'\x04Thu.q\x0cU\x05_fdayq\rU\x08Thursdayq\x0eU\x03_pmq\x0fU'
'\x02amq\x10U\x02_tq\x11GA\xcehy\x00\x00\x00\x00U\x07_minuteq'
'\x12K\x00U\x02_dq\x13G@\xe2\x12j\xaa\xaa\xaa\xabU\x07_secondq'
'\x14G\x00\x00\x00\x00\x00\x00\x00\x00U\x03_tzq\x15U\x05GMT+0q'
'\x16U\x06_monthq\x17K\x05U\x0f_timezone_naiveq\x18I00\nU'
'\x04_dayq\x19K\x02U\x05_yearq\x1aM\xd2\x07U\x08_nearsecq'
'\x1bG\x00\x00\x00\x00\x00\x00\x00\x00U\x07_pmhourq\x1cK\x08U'
'\n_dayoffsetq\x1dK\x04U\x04timeq\x1eG?\xd5UUUV\x00\x00ub.')
data = data.encode('latin-1')
new = pickle.loads(data)
for key in DateTime.__slots__:
self.assertEqual(getattr(dt, key), getattr(new, key))
def testTZ2(self):
# Time zone manipulation test 2
dt = DateTime()
dt1 = dt.toZone('GMT')
s = dt.second()
s1 = dt1.second()
self.assertEqual(s, s1, (dt, dt1, s, s1))
def testTZDiffDaylight(self):
# Diff dates across daylight savings dates
dt = DateTime('2000/6/8 1:45am US/Eastern')
dt1 = DateTime('2000/12/8 12:45am US/Eastern')
self.assertEqual(dt1 - dt, 183, (dt, dt1, dt1 - dt))
def testY10KDate(self):
# Comparison of a Y10K date and a Y2K date
dt = DateTime('10213/09/21')
dt1 = DateTime(2000, 1, 1)
dsec = (dt.millis() - dt1.millis()) / 1000.0
ddays = math.floor((dsec / 86400.0) + 0.5)
self.assertEqual(ddays, 3000000, ddays)
def test_tzoffset(self):
# Test time-zone given as an offset
# GMT
dt = DateTime('Tue, 10 Sep 2001 09:41:03 GMT')
self.assertEqual(dt.tzoffset(), 0)
# Timezone by name, a timezone that hasn't got daylightsaving.
dt = DateTime('Tue, 2 Mar 2001 09:41:03 GMT+3')
self.assertEqual(dt.tzoffset(), 10800)
# Timezone by name, has daylightsaving but is not in effect.
dt = DateTime('Tue, 21 Jan 2001 09:41:03 PST')
self.assertEqual(dt.tzoffset(), -28800)
# Timezone by name, with daylightsaving in effect
dt = DateTime('Tue, 24 Aug 2001 09:41:03 PST')
self.assertEqual(dt.tzoffset(), -25200)
# A negative numerical timezone
dt = DateTime('Tue, 24 Jul 2001 09:41:03 -0400')
self.assertEqual(dt.tzoffset(), -14400)
# A positive numerical timzone
dt = DateTime('Tue, 6 Dec 1966 01:41:03 +0200')
self.assertEqual(dt.tzoffset(), 7200)
# A negative numerical timezone with minutes.
dt = DateTime('Tue, 24 Jul 2001 09:41:03 -0637')
self.assertEqual(dt.tzoffset(), -23820)
# A positive numerical timezone with minutes.
dt = DateTime('Tue, 24 Jul 2001 09:41:03 +0425')
self.assertEqual(dt.tzoffset(), 15900)
def testISO8601(self):
# ISO8601 reference dates
ref0 = DateTime('2002/5/2 8:00am GMT')
ref1 = DateTime('2002/5/2 8:00am US/Eastern')
ref2 = DateTime('2006/11/6 10:30 GMT')
ref3 = DateTime('2004/06/14 14:30:15 GMT-3')
ref4 = DateTime('2006/01/01 GMT')
# Basic tests
# Though this is timezone naive and according to specification should
# be interpreted in the local timezone, to preserve backwards
# compatibility with previously expected behaviour.
isoDt = DateTime('2002-05-02T08:00:00')
self.assertTrue(ref0.equalTo(isoDt))
isoDt = DateTime('2002-05-02T08:00:00Z')
self.assertTrue(ref0.equalTo(isoDt))
isoDt = DateTime('2002-05-02T08:00:00+00:00')
self.assertTrue(ref0.equalTo(isoDt))
isoDt = DateTime('2002-05-02T08:00:00-04:00')
self.assertTrue(ref1.equalTo(isoDt))
isoDt = DateTime('2002-05-02 08:00:00-04:00')
self.assertTrue(ref1.equalTo(isoDt))
# Bug 1386: the colon in the timezone offset is optional
isoDt = DateTime('2002-05-02T08:00:00-0400')
self.assertTrue(ref1.equalTo(isoDt))
# Bug 2191: date reduced formats
isoDt = DateTime('2006-01-01')
self.assertTrue(ref4.equalTo(isoDt))
isoDt = DateTime('200601-01')
self.assertTrue(ref4.equalTo(isoDt))
isoDt = DateTime('20060101')
self.assertTrue(ref4.equalTo(isoDt))
isoDt = DateTime('2006-01')
self.assertTrue(ref4.equalTo(isoDt))
isoDt = DateTime('200601')
self.assertTrue(ref4.equalTo(isoDt))
isoDt = DateTime('2006')
self.assertTrue(ref4.equalTo(isoDt))
# Bug 2191: date/time separators are also optional
isoDt = DateTime('20020502T08:00:00')
self.assertTrue(ref0.equalTo(isoDt))
isoDt = DateTime('2002-05-02T080000')
self.assertTrue(ref0.equalTo(isoDt))
isoDt = DateTime('20020502T080000')
self.assertTrue(ref0.equalTo(isoDt))
# Bug 2191: timezones with only one digit for hour
isoDt = DateTime('20020502T080000+0')
self.assertTrue(ref0.equalTo(isoDt))
isoDt = DateTime('20020502 080000-4')
self.assertTrue(ref1.equalTo(isoDt))
isoDt = DateTime('20020502T080000-400')
self.assertTrue(ref1.equalTo(isoDt))
isoDt = DateTime('20020502T080000-4:00')
self.assertTrue(ref1.equalTo(isoDt))
# Bug 2191: optional seconds/minutes
isoDt = DateTime('2002-05-02T0800')
self.assertTrue(ref0.equalTo(isoDt))
isoDt = DateTime('2002-05-02T08')
self.assertTrue(ref0.equalTo(isoDt))
# Bug 2191: week format
isoDt = DateTime('2002-W18-4T0800')
self.assertTrue(ref0.equalTo(isoDt))
isoDt = DateTime('2002-W184T0800')
self.assertTrue(ref0.equalTo(isoDt))
isoDt = DateTime('2002W18-4T0800')
self.assertTrue(ref0.equalTo(isoDt))
isoDt = DateTime('2002W184T08')
self.assertTrue(ref0.equalTo(isoDt))
isoDt = DateTime('2004-W25-1T14:30:15-03:00')
self.assertTrue(ref3.equalTo(isoDt))
isoDt = DateTime('2004-W25T14:30:15-03:00')
self.assertTrue(ref3.equalTo(isoDt))
# Bug 2191: day of year format
isoDt = DateTime('2002-122T0800')
self.assertTrue(ref0.equalTo(isoDt))
isoDt = DateTime('2002122T0800')
self.assertTrue(ref0.equalTo(isoDt))
# Bug 2191: hours/minutes fractions
isoDt = DateTime('2006-11-06T10.5')
self.assertTrue(ref2.equalTo(isoDt))
isoDt = DateTime('2006-11-06T10,5')
self.assertTrue(ref2.equalTo(isoDt))
isoDt = DateTime('20040614T1430.25-3')
self.assertTrue(ref3.equalTo(isoDt))
isoDt = DateTime('2004-06-14T1430,25-3')
self.assertTrue(ref3.equalTo(isoDt))
isoDt = DateTime('2004-06-14T14:30.25-3')
self.assertTrue(ref3.equalTo(isoDt))
isoDt = DateTime('20040614T14:30,25-3')
self.assertTrue(ref3.equalTo(isoDt))
# ISO8601 standard format
iso8601_string = '2002-05-02T08:00:00-04:00'
iso8601DT = DateTime(iso8601_string)
self.assertEqual(iso8601_string, iso8601DT.ISO8601())
# ISO format with no timezone
isoDt = DateTime('2006-01-01 00:00:00')
self.assertTrue(ref4.equalTo(isoDt))
def testJulianWeek(self):
# Check JulianDayWeek function
fn = os.path.join(DATADIR, 'julian_testdata.txt')
with open(fn) as fd:
lines = fd.readlines()
for line in lines:
d = DateTime(line[:10])
result_from_mx = tuple(map(int, line[12:-2].split(',')))
self.assertEqual(result_from_mx[1], d.week())
def testCopyConstructor(self):
d = DateTime('2004/04/04')
self.assertEqual(DateTime(d), d)
self.assertEqual(str(DateTime(d)), str(d))
d2 = DateTime('1999/04/12 01:00:00')
self.assertEqual(DateTime(d2), d2)
self.assertEqual(str(DateTime(d2)), str(d2))
def testCopyConstructorPreservesTimezone(self):
# test for https://bugs.launchpad.net/zope2/+bug/200007
# This always worked in the local timezone, so we need at least
# two tests with different zones to be sure at least one of them
# is not local.
d = DateTime('2004/04/04')
self.assertEqual(DateTime(d).timezone(), d.timezone())
d2 = DateTime('2008/04/25 12:00:00 EST')
self.assertEqual(DateTime(d2).timezone(), d2.timezone())
self.assertEqual(str(DateTime(d2)), str(d2))
d3 = DateTime('2008/04/25 12:00:00 PST')
self.assertEqual(DateTime(d3).timezone(), d3.timezone())
self.assertEqual(str(DateTime(d3)), str(d3))
def testRFC822(self):
# rfc822 conversion
dt = DateTime('2002-05-02T08:00:00+00:00')
self.assertEqual(dt.rfc822(), 'Thu, 02 May 2002 08:00:00 +0000')
dt = DateTime('2002-05-02T08:00:00+02:00')
self.assertEqual(dt.rfc822(), 'Thu, 02 May 2002 08:00:00 +0200')
dt = DateTime('2002-05-02T08:00:00-02:00')
self.assertEqual(dt.rfc822(), 'Thu, 02 May 2002 08:00:00 -0200')
# Checking that conversion from local time is working.
dt = DateTime()
dts = dt.rfc822().split(' ')
times = dts[4].split(':')
_isDST = time.localtime(time.time())[8]
if _isDST:
offset = time.altzone
else:
offset = time.timezone
self.assertEqual(dts[0], dt.aDay() + ',')
self.assertEqual(int(dts[1]), dt.day())
self.assertEqual(dts[2], dt.aMonth())
self.assertEqual(int(dts[3]), dt.year())
self.assertEqual(int(times[0]), dt.h_24())
self.assertEqual(int(times[1]), dt.minute())
self.assertEqual(int(times[2]), int(dt.second()))
self.assertEqual(dts[5], "%+03d%02d" % divmod((-offset / 60), 60))
def testInternationalDateformat(self):
for year in (1990, 2001, 2020):
for month in (1, 12):
for day in (1, 12, 28, 31):
try:
d_us = DateTime("%d/%d/%d" % (year, month, day))
except Exception:
continue
d_int = DateTime("%d.%d.%d" % (day, month, year),
datefmt="international")
self.assertEqual(d_us, d_int)
d_int = DateTime("%d/%d/%d" % (day, month, year),
datefmt="international")
self.assertEqual(d_us, d_int)
def test_intl_format_hyphen(self):
d_jan = DateTime('2011-01-11 GMT')
d_nov = DateTime('2011-11-01 GMT')
d_us = DateTime('11-01-2011 GMT')
d_int = DateTime('11-01-2011 GMT', datefmt="international")
self.assertNotEqual(d_us, d_int)
self.assertEqual(d_us, d_nov)
self.assertEqual(d_int, d_jan)
def test_calcTimezoneName(self):
from DateTime.interfaces import TimeError
timezone_dependent_epoch = 2177452800
try:
DateTime()._calcTimezoneName(timezone_dependent_epoch, 0)
except TimeError:
self.fail('Zope Collector issue #484 (negative time bug): '
'TimeError raised')
def testStrftimeTZhandling(self):
# strftime timezone testing
# This is a test for collector issue #1127
format = '%Y-%m-%d %H:%M %Z'
dt = DateTime('Wed, 19 Nov 2003 18:32:07 -0215')
dt_string = dt.strftime(format)
dt_local = dt.toZone(_findLocalTimeZoneName(0))
dt_localstring = dt_local.strftime(format)
self.assertEqual(dt_string, dt_localstring)
def testStrftimeFarDates(self):
# Checks strftime in dates <= 1900 or >= 2038
dt = DateTime('1900/01/30')
self.assertEqual(dt.strftime('%d/%m/%Y'), '30/01/1900')
dt = DateTime('2040/01/30')
self.assertEqual(dt.strftime('%d/%m/%Y'), '30/01/2040')
def testZoneInFarDates(self):
# Checks time zone in dates <= 1900 or >= 2038
dt1 = DateTime('2040/01/30 14:33 GMT+1')
dt2 = DateTime('2040/01/30 11:33 GMT-2')
self.assertEqual(dt1.strftime('%d/%m/%Y %H:%M'),
dt2.strftime('%d/%m/%Y %H:%M'))
@unittest.skipIf(
IS_PYPY,
"Using Non-Ascii characters for strftime doesn't work in PyPy"
"https://bitbucket.org/pypy/pypy/issues/2161/pypy3-strftime-does-not-accept-unicode" # noqa: E501 line too long
)
def testStrftimeStr(self):
dt = DateTime('2002-05-02T08:00:00+00:00')
uchar = b'\xc3\xa0'.decode('utf-8')
ok = dt.strftime('Le %d/%m/%Y a %Hh%M').replace('a', uchar)
ustr = b'Le %d/%m/%Y \xc3\xa0 %Hh%M'.decode('utf-8')
self.assertEqual(dt.strftime(ustr), ok)
def testTimezoneNaiveHandling(self):
# checks that we assign timezone naivity correctly
dt = DateTime('2007-10-04T08:00:00+00:00')
self.assertFalse(dt.timezoneNaive(),
'error with naivity handling in __parse_iso8601')
dt = DateTime('2007-10-04T08:00:00Z')
self.assertFalse(dt.timezoneNaive(),
'error with naivity handling in __parse_iso8601')
dt = DateTime('2007-10-04T08:00:00')
self.assertTrue(dt.timezoneNaive(),
'error with naivity handling in __parse_iso8601')
dt = DateTime('2007/10/04 15:12:33.487618 GMT+1')
self.assertFalse(dt.timezoneNaive(),
'error with naivity handling in _parse')
dt = DateTime('2007/10/04 15:12:33.487618')
self.assertTrue(dt.timezoneNaive(),
'error with naivity handling in _parse')
dt = DateTime()
self.assertFalse(dt.timezoneNaive(),
'error with naivity for current time')
s = '2007-10-04T08:00:00'
dt = DateTime(s)
self.assertEqual(s, dt.ISO8601())
s = '2007-10-04T08:00:00+00:00'
dt = DateTime(s)
self.assertEqual(s, dt.ISO8601())
def testConversions(self):
sdt0 = datetime.now() # this is a timezone naive datetime
dt0 = DateTime(sdt0)
self.assertTrue(dt0.timezoneNaive(), (sdt0, dt0))
sdt1 = datetime(2007, 10, 4, 18, 14, 42, 580, pytz.utc)
dt1 = DateTime(sdt1)
self.assertFalse(dt1.timezoneNaive(), (sdt1, dt1))
# convert back
sdt2 = dt0.asdatetime()
self.assertEqual(sdt0, sdt2)
sdt3 = dt1.utcdatetime() # this returns a timezone naive datetime
self.assertEqual(sdt1.hour, sdt3.hour)
dt4 = DateTime('2007-10-04T10:00:00+05:00')
sdt4 = datetime(2007, 10, 4, 5, 0)
self.assertEqual(dt4.utcdatetime(), sdt4)
self.assertEqual(dt4.asdatetime(), sdt4.replace(tzinfo=pytz.utc))
dt5 = DateTime('2007-10-23 10:00:00 US/Eastern')
tz = pytz.timezone('US/Eastern')
sdt5 = datetime(2007, 10, 23, 10, 0, tzinfo=tz)
dt6 = DateTime(sdt5)
self.assertEqual(dt5.asdatetime(), sdt5)
self.assertEqual(dt6.asdatetime(), sdt5)
self.assertEqual(dt5, dt6)
self.assertEqual(dt5.asdatetime().tzinfo, tz)
self.assertEqual(dt6.asdatetime().tzinfo, tz)
def testBasicTZ(self):
# psycopg2 supplies it's own tzinfo instances, with no `zone` attribute
tz = FixedOffset(60, 'GMT+1')
dt1 = datetime(2008, 8, 5, 12, 0, tzinfo=tz)
DT = DateTime(dt1)
dt2 = DT.asdatetime()
offset1 = dt1.tzinfo.utcoffset(dt1)
offset2 = dt2.tzinfo.utcoffset(dt2)
self.assertEqual(offset1, offset2)
def testEDTTimezone(self):
# should be able to parse EDT timezones: see lp:599856.
dt = DateTime("Mon, 28 Jun 2010 10:12:25 EDT")
self.assertEqual(dt.Day(), 'Monday')
self.assertEqual(dt.day(), 28)
self.assertEqual(dt.Month(), 'June')
self.assertEqual(dt.timezone(), 'GMT-4')
def testParseISO8601(self):
parsed = DateTime()._parse_iso8601('2010-10-10')
self.assertEqual(parsed, (2010, 10, 10, 0, 0, 0, 'GMT+0000'))
def test_interface(self):
from DateTime.interfaces import IDateTime
self.assertTrue(IDateTime.providedBy(DateTime()))
def test_security(self):
dt = DateTime()
self.assertEqual(dt.__roles__, None)
self.assertEqual(dt.__allow_access_to_unprotected_subobjects__, 1)
def test_format(self):
dt = DateTime(1968, 3, 10, 23, 45, 0, 'Europe/Vienna')
fmt = '%d.%m.%Y %H:%M'
result = dt.strftime(fmt)
unformatted_result = '1968/03/10 23:45:00 Europe/Vienna'
self.assertEqual(result, f'{dt:%d.%m.%Y %H:%M}')
self.assertEqual(unformatted_result, f'{dt}')
self.assertEqual(unformatted_result, f'{dt}')
self.assertEqual(result, f'{dt:{fmt}}')
self.assertEqual(unformatted_result, f'{dt:}')
self.assertEqual(unformatted_result, f'{dt}')
def test_suite():
import doctest
return unittest.TestSuite([
unittest.defaultTestLoader.loadTestsFromTestCase(DateTimeTests),
doctest.DocFileSuite('DateTime.txt', package='DateTime'),
doctest.DocFileSuite('pytz.txt', package='DateTime'),
])