Is there no way to parse an ISO datetime object in MicroPython? My Raspberry Pi Pico calls a REST API that contains date items in the ISO 8601 format:
{"title":"Green","date":"2023-10-18T00:00:00"}
but MicroPython only appears to have a time function, not a datetime function and the time function doesn't seem to be capable of parsing strings.
I basically need to turn ISO strings into "Wednesday 18" for example.
There's an algorithm for determining the day of the week for a given date that works for dates back to 1753.
sample = {"title":"Green","date":"2023-10-18T00:00:00"}
def day_string_from_iso8601_date(date_str):
month_keys = (1,4,4,0,2,5,0,3,6,1,4,6)
days_of_week = ("Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday")
[yyyy, mm, dd] = [int(i) for i in date_str.split('T')[0].split('-')]
leap_year_modifier = 0
if ((yyyy % 400 == 0) or (yyyy % 100 != 0) and (yyyy % 4 == 0)) and mm in (1, 2):
leap_year_modifier = -1
a = yyyy % 100
b = a // 4
year_modifier = 0
if yyyy < 1800:
year_modifier = 4
elif 1799 < yyyy < 1900:
year_modifier = 2
elif 1999 < yyyy < 2100:
year_modifier = -1
day = (a + b + dd + month_keys[mm-1] + leap_year_modifier + year_modifier) % 7
return f"{days_of_week[day]} {dd}"
day_string_from_iso8601_date(sample["date"])
Output:
'Wednesday 18'
EDIT: There is a simpler way to solve this using the time
module in Python or utime
in Micropython. January 1 2000 fell on a Saturday. This piece of information along with the number of days to the date to be parsed can be used to calculate the week day.
Python's time.mktime()
function takes a tuple containing 9 elements corresponding to struct_time
as an argument and returns the seconds passed since epoch (1 January 1970).
import time
# January 1 2000 as dummy time struct
jan_1_2000 = (2000, 1, 1, 1, 0, 0, 0, 0, 0)
seconds_in_a_day = 24 * 60 * 60 # 86400
days_since_epoch = time.mktime(jan_1_2000) // seconds_in_a_day # 10957.0
Saturday, 1 January 2000 was 10,957 days after Thursday, 1 January 1970. The 86400
and 10957
constants can be used to save a little bit of computing power on the micro processor.
import utime
def day_string_from_iso8601(date_str):
days_of_week = ("Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday")
[yyyy, mm, dd] = [int(i) for i in date_str.split('T')[0].split('-')]
the_date = (yyyy, mm, dd, 1, 0, 0, 0, 0, 0)
day = int((utime.mktime(the_date) // 86400) - 10957) % 7
return f"{days_of_week[day]} {dd}"