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

Remove dependency on pytz #774

Merged
merged 1 commit into from
Oct 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ Unreleased

* feat: Lowercase the ``null_values`` provided to individual data types, since all comparisons to ``null_values`` are case-insensitive. (#770)
* feat: :class:`.Mean` works with :class:`.TimeDelta`. (#761)
* Switch from ``pytz`` to ``ZoneInfo``.

1.7.1 - Jan 4, 2023
-------------------
Expand Down
3 changes: 1 addition & 2 deletions agate/data_types/date_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ class DateTime(DataType):
A formatting string for :meth:`datetime.datetime.strptime` to use
instead of using regex-based parsing.
:param timezone:
A `pytz <https://pytz.sourceforge.net/>`_ timezone to apply to each
parsed date.
A ``ZoneInfo`` timezone to apply to each parsed date.
:param locale:
A locale specification such as :code:`en_US` or :code:`de_DE` to use
for parsing formatted datetimes.
Expand Down
18 changes: 13 additions & 5 deletions docs/cookbook/datetime.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,13 @@ The second way is to specify a timezone as an argument to the type constructor:

.. code-block:: python

import pytz
try:
from zoneinfo import ZoneInfo
except ImportError:
# Fallback for Python < 3.9
from backports.zoneinfo import ZoneInfo

eastern = pytz.timezone('US/Eastern')
eastern = ZoneInfo('US/Eastern')
datetime_type = agate.DateTime(timezone=eastern)

In this case all timezones that are processed will be set to have the Eastern timezone. Note, the timezone will be **set**, not converted. You cannot use this method to convert your timezones from UTC to another timezone. To do that see :ref:`convert_timezones`.
Expand All @@ -60,17 +64,21 @@ If you load data from a spreadsheet in one timezone and you need to convert it t

.. code-block:: python

import pytz
try:
from zoneinfo import ZoneInfo
except ImportError:
# Fallback for Python < 3.9
from backports.zoneinfo import ZoneInfo

us_eastern = pytz.timezone('US/Eastern')
us_eastern = ZoneInfo('US/Eastern')
datetime_type = agate.DateTime(timezone=us_eastern)

column_names = ['what', 'when']
column_types = [text_type, datetime_type]

table = agate.Table.from_csv('events.csv', columns)

rome = timezone('Europe/Rome')
rome = ZoneInfo('Europe/Rome')
timezone_shifter = agate.Formula(lambda r: r['when'].astimezone(rome))

table = agate.Table.compute([
Expand Down
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
'parsedatetime>=2.1,!=2.5',
'python-slugify>=1.2.1',
'pytimeparse>=1.1.5',
'tzdata>=2023.3;platform_system=="Windows"',
],
extras_require={
'test': [
Expand All @@ -54,7 +55,7 @@
'PyICU>=2.4.2;sys_platform=="linux"',
'pytest',
'pytest-cov',
'pytz>=2015.4',
'backports.zoneinfo;python_version<"3.9"',
],
}
)
15 changes: 10 additions & 5 deletions tests/test_data_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
from decimal import Decimal

import parsedatetime
import pytz

try:
from zoneinfo import ZoneInfo
except ImportError:
# Fallback for Python < 3.9
from backports.zoneinfo import ZoneInfo

from agate.data_types import Boolean, Date, DateTime, Number, Text, TimeDelta
from agate.exceptions import CastError
Expand Down Expand Up @@ -352,16 +357,16 @@ def test_cast_parser(self):
))

def test_cast_parser_timezone(self):
tzinfo = pytz.timezone('US/Pacific')
tzinfo = ZoneInfo('US/Pacific')
datetime_type = DateTime(timezone=tzinfo)

values = ('3/1/1994 12:30 PM', '2/17/2011 06:30', None, 'January 5th, 1984 22:37', 'n/a')
casted = tuple(datetime_type.cast(v) for v in values)
self.assertSequenceEqual(casted, (
tzinfo.localize(datetime.datetime(1994, 3, 1, 12, 30, 0, 0)),
tzinfo.localize(datetime.datetime(2011, 2, 17, 6, 30, 0, 0)),
datetime.datetime(1994, 3, 1, 12, 30, 0, 0, tzinfo=tzinfo),
datetime.datetime(2011, 2, 17, 6, 30, 0, 0, tzinfo=tzinfo),
None,
tzinfo.localize(datetime.datetime(1984, 1, 5, 22, 37, 0, 0)),
datetime.datetime(1984, 1, 5, 22, 37, 0, 0, tzinfo=tzinfo),
None
))

Expand Down