Although it is Python code, it is a program for date calculation logic verification. The logic itself is used for implementation in C, which is a free standing environment. Maybe Python has a decent date and time library so you don't need this.
Since the internal representation of the real-time clock (RTC) of the built-in MCU or a single device is usually in BCD format based on January 1, 2000, it is difficult to calculate the difference between dates if it is expressed as it is.
It will be easier if you convert the date read from the RTC to the number of days elapsed based on January 1, 2000, and then perform the calculation. Since the current time of RTC and settings such as alarms are in BCD format, we also implemented conversion to return to the date.
Remarks
calendar.py
__author__ = '[email protected]'
__version__ = '0.1'
#I referred to the article at the following URL.
# Going My C Way:Find the number of days that have passed since January 1, 2000
# https://cprogramming.g.hatena.ne.jp/lnznt/20110721/1311244811
#Leap year determination function for the year
def is_leapyear(year):
return ((year % 4) == 0) and ((year % 100) != 0) or ((year % 400) == 0)
#Year/Calculate the last day of the month.
def last_day_of_month(year, month):
if ((month == 2) and is_leapyear(year)):
return 29
return (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)[month]
#Monthly elapsed days from January 1st of the leap year
days_tbl = (
#January,February,March, ...December
0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, #leap year
366, 397, 425, 456, 486, 517, 547, 578, 609, 639, 670, 700, #leap year+1
731, 762, 790, 821, 851, 882, 912, 943, 974, 1004, 1035, 1065, #leap year+2
1096, 1127, 1155, 1186, 1216, 1247, 1277, 1308, 1339, 1369, 1400, 1430, #leap year+3
1461)
#From the number of days elapsed since January 1, 2000(yyyy, mm, dd)To calculate.
def to_date(elapsed_days):
y4 = int(elapsed_days / (1 + (365 * 4)))
d0 = elapsed_days % (1 + (365 * 4))
m0 = int(d0 / 30)
m1 = m0 - (1 if (d0 < days_tbl[m0]) else 0)
year = 2000 + (y4 * 4) + int(m1 / 12)
month = (m1 % 12) + 1
day = (d0 - days_tbl[m1]) + 1
return (year, month, day)
# (yyyy, mm, dd)Calculate the number of days elapsed from.
def calc_elapsed_days(date):
y = int((date[0] - 2000) / 4)
m = ((date[0] - 2000) % 4) * 12 + date[1] - 1
d = date[2] - 1
return ((y * (1 + 365 * 4)) + days_tbl[m] + d)
def check_days(date, days):
cdays = calc_elapsed_days(date)
result = 'OK' if (cdays == days) else 'NG'
print("{0} is {1}. calc={2}, correct={3}".format(date, result, cdays, days));
def check_ymd(days, date):
calc_date = to_date(days)
result = 'OK' if (calc_date[0] == date[0] and calc_date[1] == date[1] and calc_date[2] == date[2]) else'NG'
print("{0} is {1}. calc={2}, correct={3}".format(days, result, calc_date, date));
def main():
print('(yyyy,mm,dd) to elapsed days')
check_days((2000, 1, 1), 0)
check_days((2000, 12, 31), 365)
check_days((2001, 1, 1), 366)
check_days((2001, 12, 31), 730)
check_days((2002, 1, 1), 731)
check_days((2050, 12, 31), 18627)
check_days((2098, 12, 31), 36159)
check_days((2099, 1, 1), 36160)
check_days((2099, 11, 30), 36493)
check_days((2099, 12, 1), 36494)
check_days((2099, 12, 31), 36524)
print('elapsed days to (yyyy,mm,dd)')
check_ymd(0, (2000, 1, 1))
check_ymd(365, (2000, 12, 31))
check_ymd(366, (2001, 1, 1))
check_ymd(730, (2001, 12, 31))
check_ymd(731, (2002, 1, 1))
check_ymd(18627, (2050, 12, 31))
check_ymd(36159, (2098, 12, 31))
check_ymd(36160, (2099, 1, 1))
check_ymd(36493, (2099, 11, 30))
check_ymd(36494, (2099, 12, 1))
check_ymd(36524, (2099, 12, 31))
if __name__ == '__main__':
main()
Recommended Posts