Skip to content

Commit

Permalink
Handle ?? in date string. Closes #14
Browse files Browse the repository at this point in the history
  • Loading branch information
kernitus committed Oct 29, 2023
1 parent 7f0035f commit 17b798f
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 6 deletions.
22 changes: 16 additions & 6 deletions beetsplug/date_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
class DateWrapper(datetime.datetime):
"""
Wrapper class for datetime objects.
Allows comparison between dates taking into
account the month and day being optional.
Allows comparison between dates,
with the month and day being optional.
"""

def __new__(cls, y: int = None, m: int = None, d: int = None, iso_string: str = None):
Expand All @@ -23,10 +23,13 @@ def __new__(cls, y: int = None, m: int = None, d: int = None, iso_string: str =
month = m if (m is not None and 0 < m <= 12) else 1
day = d if (d is not None and 0 < d <= 31) else 1
elif iso_string is not None:
# Replace question marks with first valid field
iso_string = iso_string.replace("??", "01")

parsed = parser.isoparse(iso_string)
return datetime.datetime.__new__(cls, parsed.year, parsed.month, parsed.day)
else:
raise TypeError("Must specify a value for year or a date string")
raise TypeError("Must either specify a value for year, or a date string")

return datetime.datetime.__new__(cls, year, month, day)

Expand All @@ -52,11 +55,18 @@ def __init__(self, y=None, m=None, d=None, iso_string=None):
self.m = None
self.d = None

# Month and day are optional
# Month and day are optional. Sometimes fields are missing or contain ??
if length >= 6:
self.m = int(iso_string[4:6])
try:
self.m = int(iso_string[4:6])
except ValueError:
pass
if length >= 8:
self.d = int(iso_string[6:8])
try:
self.d = int(iso_string[6:8])
except ValueError:
pass

else:
raise TypeError("Must specify a value for year or a date string")

Expand Down
11 changes: 11 additions & 0 deletions tests/test_date_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@ def test_invalid_date(self):
self.assertEqual(10, result.m)
self.assertEqual(1, result.d)

def test_invalid_chars(self):
first = DateWrapper(iso_string="2022-??-10")
self.assertEqual(2022, first.y)
self.assertEqual(None, first.m)
self.assertEqual(10, first.d)
second = DateWrapper(iso_string="2022-10-??")
self.assertEqual(2022, second.y)
self.assertEqual(10, second.m)
self.assertEqual(None, second.d)
self.assertTrue(second < first)

# Force year to be within range 1 - 9999
def test_year_zero(self):
result = DateWrapper(0, 12, 10)
Expand Down

0 comments on commit 17b798f

Please sign in to comment.