CPython/MicroPython returns different result of time.localtime()

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
allankliu
Posts: 11
Joined: Fri Mar 30, 2018 11:13 am

CPython/MicroPython returns different result of time.localtime()

Post by allankliu » Tue Apr 10, 2018 7:12 am

I am trying to make a NTP clock with MicroPython. And I ported Arduino's NTP library to MicroPython, since it returns identical timestamp as CPython does. Now I find CPython and MicroPython on ESP8266 returns different result when I try to convert timestamp into time strings.

Code: Select all

> python
Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import time
>>> time.localtime(1523338307)
time.struct_time(tm_year=2018, tm_mon=4, tm_mday=10, tm_hour=13, tm_min=31, tm_sec=47, tm_wday=1, tm_yday=100, 

Code: Select all

PYB: soft reboot
MicroPython v1.9.3-500-gbc3a5f19 on 2018-03-30; ESP module with ESP8266
Type "help()" for more information.
>>> import time
>>> time.localtime(1523338307)
(2048, 4, 9, 5, 31, 47, 3, 100)
>>>
It seems tm_year, tm_mday, tm_hour are wrong from MicroPython. I also tried another pyb, which is identical to ESP8266 port.

So far I am using a dedicated functions to convert timestamp to tuple. Is it a bug ?

chuckbook
Posts: 135
Joined: Fri Oct 30, 2015 11:55 pm

Re: CPython/MicroPython returns different result of time.localtime()

Post by chuckbook » Tue Apr 10, 2018 9:22 am

MPY epoch is 2000-01-01 instead of unix epoch, which is 1970-01-01.

Code: Select all

>>> time.localtime(1523338307-time.UNIX_TIME)
(2018, 4, 10, 6, 31, 47, 1, 100)
Note:
I'm not sure if time.UNIX_TIME is defined in the master repository. It is just a constant

Code: Select all

>>> time.UNIX_TIME
946681200

allankliu
Posts: 11
Joined: Fri Mar 30, 2018 11:13 am

Re: CPython/MicroPython returns different result of time.localtime()

Post by allankliu » Tue Apr 10, 2018 11:41 am

Thanks for your reply. It is very interesting to know that differences.

However I got Exceptions from REPL console by ESP8266 and Pyboard.

Code: Select all

PYB: soft reboot
MicroPython v1.9.3-500-gbc3a5f19 on 2018-03-30; ESP module with ESP8266
Type "help()" for more information.

>>> import time
>>> time.UNIX_TIME
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'UNIX_TIME'
>>>

Code: Select all

 __  __ ___ _    ___
|  \/  | _ \ |  | _ \   MPLR v1.2, PYB Nano with STM32F401CE
| |\/| |  _/ |__|   /   MicroPythonv1.8.4-149-ge7d1dc3-dirty on 2016-10-08
|_|  |_|_| |____|_|_\   http://www.micropython.org.cn
                        Type "help()" for more information.
>>> import time
>>> time.localtime(1523338307-time.UNIX_TIME)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'UNIX_TIME'
Maybe the UNIX_TIME is available from latest versions?

But I can caculate the days between UNIX/MPY_EPOCH to get a constant by myself anyway. So I tried in CPython REPL

Code: Select all

>>> import datetime, time
>>> MPY_EPOCH = datetime.date(*time.gmtime(0)[0:3])
>>> MPY_EPOCH
datetime.date(1970, 1, 1)
>>> SYS_EPOCH = MPY_EPOCH
>>> MPY_EPOCH = datetime.date(2000,1,1)
>>> DELTA = (MPY_EPOCH - SYS_EPOCH).days * 24 *3600
>>> DELTA
946684800
Then I use the constant in MPY REPL.

Code: Select all

>>> import time
>>> time.localtime(1523338307 - 946684800)
(2018, 4, 10, 5, 31, 47, 1, 100)
Now most of the components are correct except for hour.

CPython gets 20180410, 13:31:47
uPython gets 20180410, 05:31:47

Does timezone count ? Since my timezone is +8. So localtime will reuse system timezone settings in my PC. I should use time.gmtime(1523338307) in CPython and time.localtime(1523338307 - 946684800) to get equal time.

Code: Select all

>>> time.gmtime(1523338307)
time.struct_time(tm_year=2018, tm_mon=4, tm_mday=10, tm_hour=5, tm_min=31, tm_sec=47, tm_wday=1, tm_yday=100, tm_isdst=0)
CPython gets 20180410, 05:31:47 GMT
uPython gets 20180410, 05:31:47 GMT

:D

Post Reply