[PYTHON] Mutual conversion between date and days elapsed from January 1, 2000

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

Mutual conversion between date and days elapsed from January 1, 2000
Mutual conversion between Qiita articles and Jupyter notebook
Conversion between Julian day and Gregorian calendar date
Mutual conversion between fixed point and binary numbers
Mutual conversion between JSON and YAML / TOML in Python
Conversion between unixtime and datetime
Conversion between singular and plural of words
Relationship between Firestore and Go data type conversion
[Python] Conversion memo between time data and numerical data