Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use tz.UTC in favor of tz.tzutc() where possible. #910

Merged
merged 11 commits into from Apr 25, 2019
2 changes: 2 additions & 0 deletions changelog.d/910.bugfix.rst
@@ -0,0 +1,2 @@
Updated many modules to use ``tz.UTC`` in favor of ``tz.tzutc()`` internally,
to avoid an unnecessary function call.
4 changes: 2 additions & 2 deletions dateutil/parser/_parser.py
Expand Up @@ -1195,10 +1195,10 @@ def _build_tzaware(self, naive, res, tzinfos):
# This is mostly relevant for winter GMT zones parsed in the UK
if (aware.tzname() != res.tzname and
res.tzname in self.info.UTCZONE):
aware = aware.replace(tzinfo=tz.tzutc())
aware = aware.replace(tzinfo=tz.UTC)

elif res.tzoffset == 0:
aware = naive.replace(tzinfo=tz.tzutc())
aware = naive.replace(tzinfo=tz.UTC)

elif res.tzoffset:
aware = naive.replace(tzinfo=tz.tzoffset(res.tzname, res.tzoffset))
Expand Down
4 changes: 2 additions & 2 deletions dateutil/parser/isoparser.py
Expand Up @@ -377,7 +377,7 @@ def _parse_isotime(self, timestr):

def _parse_tzstr(self, tzstr, zero_as_utc=True):
if tzstr == b'Z' or tzstr == b'z':
return tz.tzutc()
return tz.UTC

if len(tzstr) not in {3, 5, 6}:
raise ValueError('Time zone offset must be 1, 3, 5 or 6 characters')
Expand All @@ -396,7 +396,7 @@ def _parse_tzstr(self, tzstr, zero_as_utc=True):
minutes = int(tzstr[(4 if tzstr[3:4] == self._TIME_SEP else 3):])

if zero_as_utc and hours == 0 and minutes == 0:
return tz.tzutc()
return tz.UTC
else:
if minutes > 59:
raise ValueError('Invalid minutes in time zone offset')
Expand Down
1 change: 0 additions & 1 deletion dateutil/rrule.py
Expand Up @@ -21,7 +21,6 @@
import heapq

from ._common import weekday as weekdaybase
from .tz import tzutc, tzlocal

# For warning about deprecation of until and count
from warnings import warn
Expand Down
2 changes: 1 addition & 1 deletion dateutil/test/property/test_isoparse_prop.py
Expand Up @@ -7,7 +7,7 @@
import pytest

# Strategies
TIME_ZONE_STRATEGY = st.sampled_from([None, tz.tzutc()] +
TIME_ZONE_STRATEGY = st.sampled_from([None, tz.UTC] +
[tz.gettz(zname) for zname in ('US/Eastern', 'US/Pacific',
'Australia/Sydney', 'Europe/London')])
ASCII_STRATEGY = st.characters(max_codepoint=127)
Expand Down
12 changes: 6 additions & 6 deletions dateutil/test/test_isoparser.py
Expand Up @@ -4,13 +4,13 @@
from datetime import datetime, timedelta, date, time
import itertools as it

from dateutil.tz import tz
from dateutil import tz
from dateutil.tz import UTC
from dateutil.parser import isoparser, isoparse

import pytest
import six

UTC = tz.tzutc()

def _generate_tzoffsets(limited):
def _mkoffset(hmtuple, fmt):
Expand All @@ -36,7 +36,7 @@ def _mkoffset(hmtuple, fmt):
out += [_mkoffset(hm, fmt) for hm in hm_out for fmt in fmts]

# Also add in UTC and naive
out.append((tz.tzutc(), 'Z'))
out.append((UTC, 'Z'))
out.append((None, ''))

return out
Expand Down Expand Up @@ -227,9 +227,9 @@ def test_iso_ordinal(isoord, dt_expected):
(b'2014-02-04T12:30:15.224', datetime(2014, 2, 4, 12, 30, 15, 224000)),
(b'20140204T123015.224', datetime(2014, 2, 4, 12, 30, 15, 224000)),
(b'2014-02-04T12:30:15.224Z', datetime(2014, 2, 4, 12, 30, 15, 224000,
tz.tzutc())),
UTC)),
(b'2014-02-04T12:30:15.224z', datetime(2014, 2, 4, 12, 30, 15, 224000,
tz.tzutc())),
UTC)),
(b'2014-02-04T12:30:15.224+05:00',
datetime(2014, 2, 4, 12, 30, 15, 224000,
tzinfo=tz.tzoffset(None, timedelta(hours=5))))])
Expand Down Expand Up @@ -333,7 +333,7 @@ def test_parse_tzstr(tzoffset):
@pytest.mark.parametrize('zero_as_utc', [True, False])
def test_parse_tzstr_zero_as_utc(tzstr, zero_as_utc):
tzi = isoparser().parse_tzstr(tzstr, zero_as_utc=zero_as_utc)
assert tzi == tz.tzutc()
assert tzi == UTC
assert (type(tzi) == tz.tzutc) == zero_as_utc


Expand Down
6 changes: 3 additions & 3 deletions dateutil/test/test_parser.py
Expand Up @@ -890,7 +890,7 @@ def test_tzlocal_in_gmt(self):
# This is an imaginary datetime in tz.tzlocal() but should still
# parse using the GMT-as-alias-for-UTC rule
dt = parse('2004-05-01T12:00 GMT')
dt_exp = datetime(2004, 5, 1, 12, tzinfo=tz.tzutc())
dt_exp = datetime(2004, 5, 1, 12, tzinfo=tz.UTC)

assert dt == dt_exp

Expand All @@ -907,7 +907,7 @@ def test_tzlocal_parse_fold(self):
assert dt.tzname() == dt_exp.tzname()
assert dt.replace(tzinfo=None) == dt_exp.replace(tzinfo=None)
assert getattr(dt, 'fold') == getattr(dt_exp, 'fold')
assert dt.astimezone(tz.tzutc()) == dt_exp.astimezone(tz.tzutc())
assert dt.astimezone(tz.UTC) == dt_exp.astimezone(tz.UTC)


def test_parse_tzinfos_fold():
Expand All @@ -920,7 +920,7 @@ def test_parse_tzinfos_fold():
assert dt == dt_exp
assert dt.tzinfo is dt_exp.tzinfo
assert getattr(dt, 'fold') == getattr(dt_exp, 'fold')
assert dt.astimezone(tz.tzutc()) == dt_exp.astimezone(tz.tzutc())
assert dt.astimezone(tz.UTC) == dt_exp.astimezone(tz.UTC)


@pytest.mark.parametrize('dtstr,dt', [
Expand Down
44 changes: 22 additions & 22 deletions dateutil/test/test_tz.py
Expand Up @@ -198,8 +198,8 @@ def testFoldPositiveUTCOffset(self):
with self._gettz_context(tzname):
SYD = self.gettz(tzname)

t0_u = datetime(2012, 3, 31, 15, 30, tzinfo=tz.tzutc()) # AEST
t1_u = datetime(2012, 3, 31, 16, 30, tzinfo=tz.tzutc()) # AEDT
t0_u = datetime(2012, 3, 31, 15, 30, tzinfo=tz.UTC) # AEST
t1_u = datetime(2012, 3, 31, 16, 30, tzinfo=tz.UTC) # AEDT

t0_syd0 = t0_u.astimezone(SYD)
t1_syd1 = t1_u.astimezone(SYD)
Expand All @@ -220,8 +220,8 @@ def testGapPositiveUTCOffset(self):
with self._gettz_context(tzname):
SYD = self.gettz(tzname)

t0_u = datetime(2012, 10, 6, 15, 30, tzinfo=tz.tzutc()) # AEST
t1_u = datetime(2012, 10, 6, 16, 30, tzinfo=tz.tzutc()) # AEDT
t0_u = datetime(2012, 10, 6, 15, 30, tzinfo=tz.UTC) # AEST
t1_u = datetime(2012, 10, 6, 16, 30, tzinfo=tz.UTC) # AEDT

t0 = t0_u.astimezone(SYD)
t1 = t1_u.astimezone(SYD)
Expand All @@ -242,8 +242,8 @@ def testFoldNegativeUTCOffset(self):
with self._gettz_context(tzname):
TOR = self.gettz(tzname)

t0_u = datetime(2011, 11, 6, 5, 30, tzinfo=tz.tzutc())
t1_u = datetime(2011, 11, 6, 6, 30, tzinfo=tz.tzutc())
t0_u = datetime(2011, 11, 6, 5, 30, tzinfo=tz.UTC)
t1_u = datetime(2011, 11, 6, 6, 30, tzinfo=tz.UTC)

t0_tor = t0_u.astimezone(TOR)
t1_tor = t1_u.astimezone(TOR)
Expand All @@ -265,8 +265,8 @@ def testGapNegativeUTCOffset(self):
with self._gettz_context(tzname):
TOR = self.gettz(tzname)

t0_u = datetime(2011, 3, 13, 6, 30, tzinfo=tz.tzutc())
t1_u = datetime(2011, 3, 13, 7, 30, tzinfo=tz.tzutc())
t0_u = datetime(2011, 3, 13, 6, 30, tzinfo=tz.UTC)
t1_u = datetime(2011, 3, 13, 7, 30, tzinfo=tz.UTC)

t0 = t0_u.astimezone(TOR)
t1 = t1_u.astimezone(TOR)
Expand All @@ -286,7 +286,7 @@ def testFoldLondon(self):

with self._gettz_context(tzname):
LON = self.gettz(tzname)
UTC = tz.tzutc()
UTC = tz.UTC

t0_u = datetime(2013, 10, 27, 0, 30, tzinfo=UTC) # BST
t1_u = datetime(2013, 10, 27, 1, 30, tzinfo=UTC) # GMT
Expand All @@ -308,7 +308,7 @@ def testFoldIndependence(self):

with self._gettz_context(tzname):
NYC = self.gettz(tzname)
UTC = tz.tzutc()
UTC = tz.UTC
hour = timedelta(hours=1)

# Firmly 2015-11-01 0:30 EDT-4
Expand Down Expand Up @@ -339,7 +339,7 @@ def testInZoneFoldEquality(self):

with self._gettz_context(tzname):
NYC = self.gettz(tzname)
UTC = tz.tzutc()
UTC = tz.UTC

dt0 = datetime(2011, 11, 6, 1, 30, tzinfo=NYC)
dt1 = tz.enfold(dt0, fold=1)
Expand Down Expand Up @@ -425,7 +425,7 @@ def testEqualAmbiguousComparison(self):
SYD0 = self.gettz(tzname)
SYD1 = self.gettz(tzname)

t0_u = datetime(2012, 3, 31, 14, 30, tzinfo=tz.tzutc()) # AEST
t0_u = datetime(2012, 3, 31, 14, 30, tzinfo=tz.UTC) # AEST

t0_syd0 = t0_u.astimezone(SYD0)
t0_syd1 = t0_u.astimezone(SYD1)
Expand Down Expand Up @@ -454,13 +454,13 @@ def get_utc_transitions(self, tzi, year, gap):
if gap:
t_n = dston - timedelta(minutes=30)

t0_u = t_n.replace(tzinfo=tzi).astimezone(tz.tzutc())
t0_u = t_n.replace(tzinfo=tzi).astimezone(tz.UTC)
t1_u = t0_u + timedelta(hours=1)
else:
# Get 1 hour before the first ambiguous date
t_n = dstoff - timedelta(minutes=30)

t0_u = t_n.replace(tzinfo=tzi).astimezone(tz.tzutc())
t0_u = t_n.replace(tzinfo=tzi).astimezone(tz.UTC)
t_n += timedelta(hours=1) # Naive ambiguous date
t0_u = t0_u + timedelta(hours=1) # First ambiguous date
t1_u = t0_u + timedelta(hours=1) # Second ambiguous date
Expand Down Expand Up @@ -561,7 +561,7 @@ def testFoldIndependence(self):

with self.context(tzname):
NYC = self.tzclass(*args)
UTC = tz.tzutc()
UTC = tz.UTC
hour = timedelta(hours=1)

# Firmly 2015-11-01 0:30 EDT-4
Expand Down Expand Up @@ -596,7 +596,7 @@ def testInZoneFoldEquality(self):

with self.context(tzname):
NYC = self.tzclass(*args)
UTC = tz.tzutc()
UTC = tz.UTC

t_n, t0_u, t1_u = self.get_utc_transitions(NYC, 2011, False)

Expand Down Expand Up @@ -700,7 +700,7 @@ def testEquality(self):
self.assertEqual(utc, gmt)

def testUTCEquality(self):
utc = tz.tzutc()
utc = tz.UTC
o_utc = tz.tzoffset('UTC', 0)

self.assertEqual(utc, o_utc)
Expand Down Expand Up @@ -955,7 +955,7 @@ def testTimeOnlyDSTLocalDST(self):

def testUTCEquality(self):
with TZEnvContext(self.UTC):
assert tz.tzlocal() == tz.tzutc()
assert tz.tzlocal() == tz.UTC


# TODO: Maybe a better hack than this?
Expand Down Expand Up @@ -1316,7 +1316,7 @@ def testTimeOnlyRange(self):
def testBrokenIsDstHandling(self):
# tzrange._isdst() was using a date() rather than a datetime().
# Issue reported by Lennart Regebro.
dt = datetime(2007, 8, 6, 4, 10, tzinfo=tz.tzutc())
dt = datetime(2007, 8, 6, 4, 10, tzinfo=tz.UTC)
self.assertEqual(dt.astimezone(tz=tz.gettz("GMT+2")),
datetime(2007, 8, 6, 6, 10, tzinfo=tz.tzstr("GMT+2")))

Expand Down Expand Up @@ -2034,7 +2034,7 @@ def testGMTHasNoDaylight(self):
def testGMTOffset(self):
# GMT and UTC offsets have inverted signal when compared to the
# usual TZ variable handling.
dt = datetime(2007, 8, 6, 4, 10, tzinfo=tz.tzutc())
dt = datetime(2007, 8, 6, 4, 10, tzinfo=tz.UTC)
self.assertEqual(dt.astimezone(tz=tz.tzstr("GMT+2")),
datetime(2007, 8, 6, 6, 10, tzinfo=tz.tzstr("GMT+2")))
self.assertEqual(dt.astimezone(tz=tz.gettz("UTC-2")),
Expand Down Expand Up @@ -2175,7 +2175,7 @@ def testTzWinInequality(self):
def testTzWinEqualityInvalid(self):
# Compare to objects that do not implement comparison with this
# (should default to False)
UTC = tz.tzutc()
UTC = tz.UTC
EST = tz.tzwin('Eastern Standard Time')

self.assertFalse(EST == UTC)
Expand Down Expand Up @@ -2719,7 +2719,7 @@ def test_resolve_imaginary_ambiguous(dt):
datetime(2017, 12, 2, 12, 30, tzinfo=tz.gettz('America/New_York')),
datetime(2018, 12, 2, 9, 30, tzinfo=tz.gettz('Europe/London')),
datetime(2017, 6, 2, 16, 30, tzinfo=tz.gettz('Australia/Sydney')),
datetime(2025, 9, 25, 1, 17, tzinfo=tz.tzutc()),
datetime(2025, 9, 25, 1, 17, tzinfo=tz.UTC),
datetime(2025, 9, 25, 1, 17, tzinfo=tz.tzoffset('EST', -18000)),
datetime(2019, 3, 4, tzinfo=None)
])
Expand Down
2 changes: 1 addition & 1 deletion dateutil/test/test_utils.py
Expand Up @@ -6,11 +6,11 @@

from dateutil import tz
from dateutil import utils
from dateutil.tz import UTC
from dateutil.utils import within_delta

from freezegun import freeze_time

UTC = tz.tzutc()
NYC = tz.gettz("America/New_York")


Expand Down
5 changes: 0 additions & 5 deletions dateutil/tz/__init__.py
Expand Up @@ -2,11 +2,6 @@
from .tz import *
from .tz import __doc__

#: Convenience constant providing a :class:`tzutc()` instance
#:
#: .. versionadded:: 2.7.0
UTC = tzutc()

__all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange",
"tzstr", "tzical", "tzwin", "tzwinlocal", "gettz",
"enfold", "datetime_ambiguous", "datetime_exists",
Expand Down
10 changes: 8 additions & 2 deletions dateutil/tz/tz.py
Expand Up @@ -123,6 +123,12 @@ def __repr__(self):
__reduce__ = object.__reduce__


#: Convenience constant providing a :class:`tzutc()` instance
#:
#: .. versionadded:: 2.7.0
UTC = tzutc()


@six.add_metaclass(_TzOffsetFactory)
class tzoffset(datetime.tzinfo):
"""
Expand Down Expand Up @@ -1655,7 +1661,7 @@ def nocache(name=None):
break
else:
if name in ("GMT", "UTC"):
tz = tzutc()
tz = UTC
elif name in time.tzname:
tz = tzlocal()
return tz
Expand Down Expand Up @@ -1695,7 +1701,7 @@ def datetime_exists(dt, tz=None):

# This is essentially a test of whether or not the datetime can survive
# a round trip to UTC.
dt_rt = dt.replace(tzinfo=tz).astimezone(tzutc()).astimezone(tz)
dt_rt = dt.replace(tzinfo=tz).astimezone(UTC).astimezone(tz)
dt_rt = dt_rt.replace(tzinfo=None)

return dt == dt_rt
Expand Down
12 changes: 6 additions & 6 deletions docs/examples.rst
Expand Up @@ -1209,15 +1209,15 @@ tzutc examples
.. doctest:: tzutc

>>> from datetime import *
>>> from dateutil.tz import *
>>> from dateutil import tz

>>> datetime.now()
datetime.datetime(2003, 9, 27, 9, 40, 1, 521290)

>>> datetime.now(tzutc())
>>> datetime.now(tz.UTC)
datetime.datetime(2003, 9, 27, 12, 40, 12, 156379, tzinfo=tzutc())

>>> datetime.now(tzutc()).tzname()
>>> datetime.now(tz.UTC).tzname()
'UTC'


Expand All @@ -1237,7 +1237,7 @@ tzoffset examples
>>> datetime.now(tzoffset("BRST", -10800)).tzname()
'BRST'

>>> datetime.now(tzoffset("BRST", -10800)).astimezone(tzutc())
>>> datetime.now(tzoffset("BRST", -10800)).astimezone(UTC)
datetime.datetime(2003, 9, 27, 12, 53, 11, 446419,
tzinfo=tzutc())

Expand Down Expand Up @@ -1383,7 +1383,7 @@ tzfile examples
.. testsetup:: tzfile

from datetime import datetime
from dateutil.tz import tzfile, tzutc
from dateutil.tz import tzfile, UTC

.. doctest:: tzfile
:options: +NORMALIZE_WHITESPACE
Expand All @@ -1393,7 +1393,7 @@ tzfile examples
datetime.datetime(2003, 9, 27, 12, 3, 48, 392138,
tzinfo=tzfile('/etc/localtime'))

>>> datetime.now(tz).astimezone(tzutc())
>>> datetime.now(tz).astimezone(UTC)
datetime.datetime(2003, 9, 27, 15, 3, 53, 70863,
tzinfo=tzutc())

Expand Down