micropython / micropython/micropython-lib

datetime module has issue with year 2038 problem

Open
#842 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
2.9k
Forks
1.1k
Avg merge
7d 6h
Merged PRs (30d)
3

Description

When the time.gmtime() reaches January 19, 2038 03:14:08 UTC, a program using datetime.now() will crash with an

OverflowError: overflow converting long int to machine word

The line in question is in datetime.py line 638 in fromtimestamp

Here is a small program demonstrating the issue...

# ==================================
#           test2038.py
# ----------------------------------
# Written by G.D. Walters
# ==================================

import machine
import utime
import time
from time import sleep, localtime, gmtime
import sys
import gc

from datetime import MAXYEAR, MINYEAR, datetime, date, timedelta, timezone, tzinfo
    
# Simulate datetime to be January 19, 2038 03:14:00 UTC
def settime2038():
    tm=utime.gmtime(timelong)
    machine.RTC().datetime((tm[0], tm[1], tm[2], tm[6] + 1, tm[3], tm[4], tm[5], 0))
                    
# Return a local time based using datetime module datetime.datetime.now(timezone)                    
def showMyTime():
    import datetime
    my_timezone=timezone(timedelta(hours=-5))
    current_time = datetime.datetime.now(my_timezone)
    return current_time
    
timelong=2147483639  # January 19, 2038 03:14:00 UTC

# Do a garbage collect
gc.collect()
# Set the machine.RTC to Jan 19, 2038 03:14:00 UTC
settime2038()
print(f"{gmtime()=} - {showMyTime()=}")
#print(showMyTime())

while True:

    print(f"{gmtime()=} - {showMyTime()=}")
    #print(showMyTime())    
    time.sleep(1)

And the REPL output is ...

%Run -c $EDITOR_CONTENT

MPY: soft reboot
gmtime()=(2038, 1, 19, 3, 14, 0, 1, 19) - showMyTime()=2038-01-18 22:14:00-05:00
gmtime()=(2038, 1, 19, 3, 14, 0, 1, 19) - showMyTime()=2038-01-18 22:14:00-05:00
gmtime()=(2038, 1, 19, 3, 14, 1, 1, 19) - showMyTime()=2038-01-18 22:14:01-05:00
gmtime()=(2038, 1, 19, 3, 14, 2, 1, 19) - showMyTime()=2038-01-18 22:14:02-05:00
gmtime()=(2038, 1, 19, 3, 14, 3, 1, 19) - showMyTime()=2038-01-18 22:14:03-05:00
gmtime()=(2038, 1, 19, 3, 14, 4, 1, 19) - showMyTime()=2038-01-18 22:14:04-05:00
gmtime()=(2038, 1, 19, 3, 14, 5, 1, 19) - showMyTime()=2038-01-18 22:14:05-05:00
gmtime()=(2038, 1, 19, 3, 14, 6, 1, 19) - showMyTime()=2038-01-18 22:14:06-05:00
gmtime()=(2038, 1, 19, 3, 14, 7, 1, 19) - showMyTime()=2038-01-18 22:14:07-05:00
Traceback (most recent call last):
File "", line 39, in
File "", line 25, in showMyTime
File "datetime.py", line 644, in now
File "datetime.py", line 638, in fromtimestamp
OverflowError: overflow converting long int to machine word

This was tested on a RPi Pico-W running MicroPython v1.23.0-preview.322.g5114f2c1e and using Thonny as the IDE.
test2038.zip

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with datetime.py lines 638 and 644, then reproduce the failure using the attached test2038.py on the stated Raspberry Pi Pico-W setup. Check behavior as the timestamp passes January 19, 2038 03:14:08 UTC; done means datetime.now() no longer raises the reported OverflowError at that boundary.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
embedded-iot
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.