This is the best that I have come up with so far. I am not entirely happy with it because I have to use a % 100 to prevent an overflow of the year byte. As a result I have to add 2000 back to the year in the reverse function. Can anyone improve these functions?
def datetime_to_bcd(dt):
"""Converts a datetime object to BCD (Binary-Coded Decimal) format."""
year_bcd = ((dt.year % 100) // 10) << 4 | (dt.year % 10)
month_bcd = (dt.month // 10) << 4 | (dt.month % 10)
day_bcd = (dt.day // 10) << 4 | (dt.day % 10)
hour_bcd = (dt.hour // 10) << 4 | (dt.hour % 10)
minute_bcd = (dt.minute // 10) << 4 | (dt.minute % 10)
second_bcd = (dt.second // 10) << 4 | (dt.second % 10)
return bytes([year_bcd, month_bcd, day_bcd, hour_bcd, minute_bcd, second_bcd])
def bcd_to_datetime(bcd_bytes):
"""Converts a BCD (Binary-Coded Decimal) format in bytes to a datetime object."""
year_bcd, month_bcd, day_bcd, hour_bcd, minute_bcd, second_bcd = bcd_bytes
year = 2000 + (year_bcd >> 4) * 10 + (year_bcd & 0x0F)
month = (month_bcd >> 4) * 10 + (month_bcd & 0x0F)
day = (day_bcd >> 4) * 10 + (day_bcd & 0x0F)
hour = (hour_bcd >> 4) * 10 + (hour_bcd & 0x0F)
minute = (minute_bcd >> 4) * 10 + (minute_bcd & 0x0F)
second = (second_bcd >> 4) * 10 + (second_bcd & 0x0F)
return datetime.datetime(year, month, day, hour, minute, second)