From e0b516650cc5b535e60c021185f57c475308779f Mon Sep 17 00:00:00 2001 From: TJ-59 <85706453+TJ-59@users.noreply.github.com> Date: Sun, 10 Mar 2024 01:24:14 +0100 Subject: [PATCH 1/2] recording_date-fix core.py core.py for 0.9.x-recording_date-fix branch. --- eyed3/core.py | 56 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/eyed3/core.py b/eyed3/core.py index 1942144c..50a01a97 100644 --- a/eyed3/core.py +++ b/eyed3/core.py @@ -267,14 +267,24 @@ class Date: "%Y-%m-%d %H:%M:%S", "%Y-00-00", "%Y%m%d", + "D%d-%m", + "T%H:%M", ] """Valid time stamp formats per ISO 8601 and used by `strptime`.""" - def __init__(self, year, month=None, day=None, + @classmethod + def __new__(cls, *args, **kwargs): + if ([arg for arg in args[1:] if arg is not None]) or ([kwarg for kwarg in kwargs.values() if kwarg is not None]): + return super().__new__(cls) + else : + return + + def __init__(self, year=None, month=None, day=None, hour=None, minute=None, second=None): # Validate with datetime from datetime import datetime - _ = datetime(year, month if month is not None else 1, + _ = datetime(year if year is not None else 1899, + month if month is not None else 1, day if day is not None else 1, hour if hour is not None else 0, minute if minute is not None else 0, @@ -382,6 +392,8 @@ def parse(s): # Here is the difference with Python date/datetime objects, some # of the members can be None kwargs = {} + if "%Y" in fmt: + kwargs["year"] = pdate.tm_year if "%m" in fmt: kwargs["month"] = pdate.tm_mon if "%d" in fmt: @@ -393,23 +405,37 @@ def parse(s): if "%S" in fmt: kwargs["second"] = pdate.tm_sec - return Date(pdate.tm_year, **kwargs) + return Date(**kwargs) def __str__(self): """Returns date strings that conform to ISO-8601. The returned string will be no larger than 17 characters.""" - s = "%d" % self.year - if self.month: - s += "-%s" % str(self.month).rjust(2, '0') - if self.day: - s += "-%s" % str(self.day).rjust(2, '0') - if self.hour is not None: - s += "T%s" % str(self.hour).rjust(2, '0') - if self.minute is not None: - s += ":%s" % str(self.minute).rjust(2, '0') - if self.second is not None: - s += ":%s" % str(self.second).rjust(2, '0') - return s + s = "" #the string + c = "" #the separator character + if self.year is not None : #branch 1, aka "there is a year, maybe more" + s += "%d" % self.year + c = "-" + if self.month is not None : #there is a month + s += c + "%s" % str(self.month).rjust(2, '0') + if self.day is not None: #there is a day + s += c + "%s" % str(self.day).rjust(2, '0') + else : #branch 2, aka "we start without a year" aka "D%d-%m" format + c = "D" + if (self.day is not None) and (self.month is not None) : #checking both + s += c + "%s" % str(self.day).rjust(2, '0') + c = "-" + s += c + "%s" % str(self.month).rjust(2, '0') + return s #We send a "Ddd-mm" string for 'TDAT' + #Here is the 'TIME' part, which starts or continues the string from branch 1 + c = "T" + if self.hour is not None: + s += c + "%s" % str(self.hour).rjust(2, '0') + c = ":" + if self.minute is not None: + s += c + "%s" % str(self.minute).rjust(2, '0') +## if self.second is not None: #Are seconds really needed, or at least used ? +## s += c + "%s" % str(self.second).rjust(2, '0') + return s #We send either a YYYY-mm-ddTHH:MM, or just a THH:MM (for 'TIME') def parseError(ex) -> None: From 4f77cebad7eb27e7b13b31d4c4c428fb7e9cf274 Mon Sep 17 00:00:00 2001 From: TJ-59 <85706453+TJ-59@users.noreply.github.com> Date: Sun, 10 Mar 2024 01:26:03 +0100 Subject: [PATCH 2/2] recording_date-fix frames.py and tag.py id3/frames.py and id3/tag.py for 0.9.x-recording_date-fix branch. --- eyed3/id3/frames.py | 6 +++++- eyed3/id3/tag.py | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/eyed3/id3/frames.py b/eyed3/id3/frames.py index 7930b124..4b1bb46e 100644 --- a/eyed3/id3/frames.py +++ b/eyed3/id3/frames.py @@ -411,7 +411,11 @@ def date(self, date): self.text = "" return - self.text = str(date) + str_date = str(date) + if ((DorT := str_date[0]) in ("D","T")) and (len(str_date) <= 6): #maxlength 6, not using seconds, modify if needed + str_date = str_date.replace(DorT, "", 1) + str_date = str_date.replace("-" if DorT =="D" else ":", "") + self.text = str_date def _initEncoding(self): # Dates are always latin1 since they are always represented in ISO 8601 diff --git a/eyed3/id3/tag.py b/eyed3/id3/tag.py index 98157ea9..feda3296 100644 --- a/eyed3/id3/tag.py +++ b/eyed3/id3/tag.py @@ -556,11 +556,11 @@ def _setRecordingDate(self, date): date = core.Date.parse(date) self._setDate(b"TYER", str(date.year)) if None not in (date.month, date.day): - date_str = "%s%s" % (str(date.day).rjust(2, "0"), + date_str = "D%s-%s" % (str(date.day).rjust(2, "0"), str(date.month).rjust(2, "0")) self._setDate(b"TDAT", date_str) if None not in (date.hour, date.minute): - date_str = "%s%s" % (str(date.hour).rjust(2, "0"), + date_str = "T%s:%s" % (str(date.hour).rjust(2, "0"), str(date.minute).rjust(2, "0")) self._setDate(b"TIME", date_str)