Last active
June 8, 2023 22:28
-
-
Save moreati/7bae3f25378004b1f18238c2a9136834 to your computer and use it in GitHub Desktop.
Year, month, day, hour, minute, and second packed into 64 bits
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 00000000 11111111 22222222 33333333 44444444 55555555 66666666 77777777 | |
# YYYYYYYY YYYYYYYY YYYYYYYY YYYYYYYY YYYYYYMM MMDDDDDh hhhhmmmm mmssssss | |
class cal64: | |
__slots__ = ('_cal64') | |
_cal64: int | |
def __new__(cls, year:int, month:int, day:int, hour:int, minute:int, second:int): | |
assert 0 <= year <= 2**38-1 | |
assert 1 <= month <= 12 | |
assert 1 <= day <= 31 | |
assert 0 <= hour <= 23 | |
assert 0 <= minute <= 59 | |
assert 0 <= second <= 60 | |
self = object.__new__(cls) | |
i = 0 | |
i |= (0b111111 & second) | |
i |= (0b111111 & minute) << 6 | |
i |= (0b11111 & hour) << 6 + 6 | |
i |= (0b11111 & day) << 6 + 6 + 5 | |
i |= (0b1111 & month) << 6 + 6 + 5 + 5 | |
i |= (0b11111111111111111111111111111111111111 & year) << 6 + 6 + 5 + 5 + 4 | |
self._cal64 = i | |
return self | |
@property | |
def year(self): return (0xffffffff_fc000000 & self._cal64) >> 26 | |
@property | |
def month(self): return (0x00000000_03c00000 & self._cal64) >> 22 | |
@property | |
def day(self): return (0x00000000_003e0000 & self._cal64) >> 17 | |
@property | |
def hour(self): return (0x00000000_0001f000 & self._cal64) >> 12 | |
@property | |
def minute(self): return (0x00000000_00000fc0 & self._cal64) >> 6 | |
@property | |
def second(self): return (0x00000000_0000003f & self._cal64) >> 0 | |
def __repr__(self): | |
return ( | |
f'{self.__class__.__module__}.{self.__class__.__name__}' | |
f'({self.year}, {self.month}, {self.day}, {self.hour}, {self.minute}, {self.second})' | |
) | |
if __name__ == '__main__': | |
import time | |
print(cal64(*time.localtime()[:6])) | |
print(cal64(10_000_000_000, 12, 31, 23, 59, 59)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# <--- leap year ---> <--- normal year ---> | |
# De_NoOcSeAu_JuJuMaAp_MaFeJa De_NoOcSeAu_JuJuMaAp_MaFeJa | |
DIM64 = 0b00000011_10111011_11101110_11011100_00000011_10111011_11101110_11001100 | |
def dim64(year:int, month:int) -> int: | |
"""Return number of days in the month (1-12) for a given year.""" | |
is_leap = year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) | |
#not_leap = year % 4 or (year % 100 == 0 and year % 400) | |
lshift = month * 2 + is_leap*32 | |
return 28 + (0b11 & (DIM64 >> lshift)) | |
# Dec Nov Oct Sep Aug Jul Jun May Apr Mar Feb Jan | |
DIM65= 0b0000_11111_11110_11111_11110_11111_11111_11110_11111_11110_11111_11100_11111 | |
def dim65(year:int, month:int) -> int: | |
"""Return number of days in the month (1-12) for a given year.""" | |
is_leap = year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) | |
lshift = (month - 1) * 5 | |
return (0b11111 & (DIM65 >> lshift)) + (is_leap and month == 2) | |
# De NoOcSeAu JuJuMaAp MaFeJa | |
DIM32 = 0b00000011_10111011_11101110_11001100 | |
def dim32(year:int, month:int) -> int: | |
"""Return number of days in the month (1-12) for a given year.""" | |
is_leap = year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) | |
lshift = month * 2 | |
return 28 + (0b11 & (DIM32 >> lshift)) + (is_leap and month == 2) | |
#[1, 0, 1, 0, 1, 1, 0, 1, 0, 1, -2, 1] | |
# DNOSU_JJMAMFJ | |
DIM16 = 0b00010101_10101010 | |
def dim16(year:int, month:int): | |
"""Return number of days in the month (1-12) for a given year.""" | |
not_leap = (year % 4 or year % 100 == 0 and year % 400) > 0 | |
return 30 + (1 & (DIM16 >> month)) - (month==2) - (month==2 and not_leap) | |
def dim0(year:int, month:int) -> int: | |
"""Return number of days in the month (1-12) for a given year.""" | |
is_leap = year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) | |
# month is 1-12, just the 4 lowest bits vary - labelled a, b, c, d. | |
# result is 28-31, only the 2 lowest bits vary - labelled x, y. | |
# In a non leap year (a, b, d) determine (x, y) by the boolean equations | |
# x = a | b | d y = ~a & d | a & ~d | |
# The truth tables and simplified equations circuits can be seen at | |
# http://32x8.com/sop4_____A-B-C-D_____m_1-3-4-5-6-7-8-9-10-11-12_____d_0-13-14-15_____option-0_____999781975371824592721 | |
# http://32x8.com/sop4_____A-B-C-D_____m_1-3-5-7-8-10-12_____d_0-13-14-15_____option-0_____989781966578850595664 | |
a, b, d = bool(month & 8), bool(month & 4), bool(month & 1) | |
return 0b11100 | (a|b|d)<<1 | (~a&d|a&~d) | (is_leap and month == 2) | |
if __name__ == '__main__': | |
import datetime | |
import itertools | |
years = [0, 1, 2, 3, 4, 100, 400, 2000, 2020, 2021, 2024, 2100, 20000, 20001] | |
months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 12] | |
years_months = list(itertools.product(years, months)) | |
for y, m in years_months: | |
assert datetime._days_in_month(y, m) == dim64(y, m), f'dim64({y},{m})={dim64(y,m)}' | |
assert datetime._days_in_month(y, m) == dim65(y, m), f'dim65({y},{m})={dim65(y,m)}' | |
assert datetime._days_in_month(y, m) == dim32(y, m), f'dim32({y},{m})={dim32(y,m)}' | |
assert datetime._days_in_month(y, m) == dim16(y, m), f'dim16({y},{m})={dim16(y,m)}' | |
assert datetime._days_in_month(y, m) == dim0(y, m), f'dim0({y},{m})={dim0(y,m)}' |
Author
moreati
commented
Jun 4, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment