Skip to content

Commit

Permalink
Handle datetime.utcnow() deprecation
Browse files Browse the repository at this point in the history
Following the deprecation of utcnow in Python 3.12, we add a
tzinfo timezone argument to date utils. For now this defaults to
None so as not to break comparisons against existing naive
datetimes. If and when naive datetimes are fully deprecated in
a future Python release, we can change the default argument for
tzinfo from None to timezone.utc.
  • Loading branch information
tw4l committed Oct 28, 2024
1 parent 92b08c5 commit ee8fa6c
Showing 1 changed file with 40 additions and 18 deletions.
58 changes: 40 additions & 18 deletions warcio/timeutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

import re
import time
import datetime
import calendar

from datetime import datetime, timezone
from email.utils import parsedate, formatdate

#=================================================================
Expand All @@ -25,7 +25,7 @@
PAD_MICRO = '000000'


def iso_date_to_datetime(string):
def iso_date_to_datetime(string, tzinfo: timezone = None):
"""
>>> iso_date_to_datetime('2013-12-26T10:11:12Z')
datetime.datetime(2013, 12, 26, 10, 11, 12)
Expand All @@ -47,6 +47,12 @@ def iso_date_to_datetime(string):
>>> iso_date_to_datetime('2013-12-26T10:11:12.000000Z')
datetime.datetime(2013, 12, 26, 10, 11, 12)
>>> iso_date_to_datetime('2013-12-26T10:11:12Z', tzinfo=timezone.utc)
datetime.datetime(2013, 12, 26, 10, 11, 12, tzinfo=datetime.timezone.utc)
>>> iso_date_to_datetime('2013-12-26T10:11:12.000000Z', tzinfo=timezone.utc)
datetime.datetime(2013, 12, 26, 10, 11, 12, tzinfo=datetime.timezone.utc)
"""

nums = DATE_TIMESPLIT.split(string)
Expand All @@ -57,21 +63,24 @@ def iso_date_to_datetime(string):
nums[6] = nums[6][:6]
nums[6] += PAD_MICRO[len(nums[6]):]

the_datetime = datetime.datetime(*(int(num) for num in nums))
the_datetime = datetime(*(int(num) for num in nums), tzinfo=tzinfo)
return the_datetime


def http_date_to_datetime(string):
def http_date_to_datetime(string, tzinfo: timezone = None):
"""
>>> http_date_to_datetime('Thu, 26 Dec 2013 09:50:10 GMT')
datetime.datetime(2013, 12, 26, 9, 50, 10)
>>> http_date_to_datetime('Thu, 26 Dec 2013 09:50:10 GMT', tzinfo=timezone.utc)
datetime.datetime(2013, 12, 26, 9, 50, 10, tzinfo=datetime.timezone.utc)
"""
return datetime.datetime(*parsedate(string)[:6])
return datetime(*parsedate(string)[:6], tzinfo=tzinfo)


def datetime_to_http_date(the_datetime):
"""
>>> datetime_to_http_date(datetime.datetime(2013, 12, 26, 9, 50, 10))
>>> datetime_to_http_date(datetime(2013, 12, 26, 9, 50, 10))
'Thu, 26 Dec 2013 09:50:10 GMT'
# Verify inverses
Expand All @@ -87,19 +96,19 @@ def datetime_to_http_date(the_datetime):

def datetime_to_iso_date(the_datetime, use_micros=False):
"""
>>> datetime_to_iso_date(datetime.datetime(2013, 12, 26, 10, 11, 12))
>>> datetime_to_iso_date(datetime(2013, 12, 26, 10, 11, 12))
'2013-12-26T10:11:12Z'
>>> datetime_to_iso_date(datetime.datetime(2013, 12, 26, 10, 11, 12, 456789))
>>> datetime_to_iso_date(datetime(2013, 12, 26, 10, 11, 12, 456789))
'2013-12-26T10:11:12Z'
>>> datetime_to_iso_date(datetime.datetime(2013, 12, 26, 10, 11, 12), use_micros=True)
>>> datetime_to_iso_date(datetime(2013, 12, 26, 10, 11, 12), use_micros=True)
'2013-12-26T10:11:12Z'
>>> datetime_to_iso_date(datetime.datetime(2013, 12, 26, 10, 11, 12, 456789), use_micros=True)
>>> datetime_to_iso_date(datetime(2013, 12, 26, 10, 11, 12, 456789), use_micros=True)
'2013-12-26T10:11:12.456789Z'
>>> datetime_to_iso_date(datetime.datetime(2013, 12, 26, 10, 11, 12, 1), use_micros=True)
>>> datetime_to_iso_date(datetime(2013, 12, 26, 10, 11, 12, 1), use_micros=True)
'2013-12-26T10:11:12.000001Z'
"""
Expand All @@ -112,7 +121,7 @@ def datetime_to_iso_date(the_datetime, use_micros=False):

def datetime_to_timestamp(the_datetime):
"""
>>> datetime_to_timestamp(datetime.datetime(2013, 12, 26, 10, 11, 12))
>>> datetime_to_timestamp(datetime(2013, 12, 26, 10, 11, 12))
'20131226101112'
"""

Expand All @@ -124,7 +133,7 @@ def timestamp_now():
>>> len(timestamp_now())
14
"""
return datetime_to_timestamp(datetime.datetime.utcnow())
return datetime_to_timestamp(datetime.now(timezone.utc))


def timestamp20_now():
Expand All @@ -139,7 +148,7 @@ def timestamp20_now():
20
"""
now = datetime.datetime.utcnow()
now = datetime.now(timezone.utc)
return now.strftime('%Y%m%d%H%M%S%f')


Expand Down Expand Up @@ -203,7 +212,7 @@ def pad_timestamp(string, pad_str=PAD_6_UP):
return string


def timestamp_to_datetime(string):
def timestamp_to_datetime(string, tzinfo: timezone = None):
"""
# >14-digit -- rest ignored
>>> timestamp_to_datetime('2014122609501011')
Expand Down Expand Up @@ -285,6 +294,18 @@ def timestamp_to_datetime(string):
>>> timestamp_to_datetime('2010abc')
datetime.datetime(2010, 12, 31, 23, 59, 59)
# 14-digit with tzinfo
>>> timestamp_to_datetime('20141226095010', tzinfo=timezone.utc)
datetime.datetime(2014, 12, 26, 9, 50, 10, tzinfo=datetime.timezone.utc)
# 6-digit padding with tzinfo
>>> timestamp_to_datetime('201410', tzinfo=timezone.utc)
datetime.datetime(2014, 10, 31, 23, 59, 59, tzinfo=datetime.timezone.utc)
# not a number! with tzinfo
>>> timestamp_to_datetime('2010abc', tzinfo=timezone.utc)
datetime.datetime(2010, 12, 31, 23, 59, 59, tzinfo=datetime.timezone.utc)
"""

# pad to 6 digits
Expand Down Expand Up @@ -312,12 +333,13 @@ def extract(string, start, end, min_, max_):
minute = extract(string, 10, 12, 0, 59)
second = extract(string, 12, 14, 0, 59)

return datetime.datetime(year=year,
return datetime(year=year,
month=month,
day=day,
hour=hour,
minute=minute,
second=second)
second=second,
tzinfo=tzinfo)

#return time.strptime(pad_timestamp(string), TIMESTAMP_14)

Expand All @@ -344,7 +366,7 @@ def sec_to_timestamp(secs):
'20141231235959'
"""

return datetime_to_timestamp(datetime.datetime.utcfromtimestamp(secs))
return datetime_to_timestamp(datetime.utcfromtimestamp(secs))


def timestamp_to_http_date(string):
Expand Down

0 comments on commit ee8fa6c

Please sign in to comment.