I am trying to figure out the best way to convert from epoch seconds (since NTP epoch 1900-01-01 00:00) to a datetime string (MM/DD/YY,hh:mm:ss) without any libraries/modules/external functions, as they are not available on an embedded device.
My first thought was to look at the Python datetime module source code, however that was not very useful to me.
My initial attempt in Python uses a conversion of days since 0001-01-01 to date using getDateFromJulianDay
adapted to Python from C++ source, combined with modulo operations to obtain time. It works, but is there a better way?
def getDateFromJulianDay(julianDay):
# Gregorian calendar starting from October 15, 1582
# This algorithm is from:
# Henry F. Fliegel and Thomas C. van Flandern. 1968.
# Letters to the editor:
# a machine algorithm for processing calendar dates.
# Commun. ACM 11, 10 (October 1968), 657-. DOI=10.1145/364096.364097
# http://doi.acm.org/10.1145/364096.364097
ell = julianDay + 68569;
n = (4 * ell) / 146097;
ell = ell - (146097 * n + 3) / 4;
i = (4000 * (ell + 1)) / 1461001;
ell = ell - (1461 * i) / 4 + 31;
j = (80 * ell) / 2447;
d = ell - (2447 * j) / 80;
ell = j / 11;
m = j + 2 - (12 * ell);
y = 100 * (n - 49) + i + ell;
return y,m,d
# NTP response (integer portion) for Monday, March 25, 2013 at 6:40:43 PM
sec_since_1900 = 3573225643
# 2415021 is the number of days between 0001-01-01 and 1900-01-01,
# the start of the NTP epoch
(year,month,day) = getDateFromJulianDay(2415021 + sec_since_1900/60/60/24)
seconds_into_day = sec_since_1900 % 86400
(hour, sec_past_hour) = divmod(seconds_into_day,3600)
(min, sec) = divmod(sec_past_hour,60)
print 'year:',year,'month:',month,'day:',day
print 'hour:',hour,'min:',min,'sec:',sec
Why I'm doing this: I am getting the current time from an NTP server, and taking this time at face value for updating a hardware real time clock (RTC) that only accepts the date, time and time zone: MM/DD/YY,hh:mm:ss,±zz. I plan to implement true NTP capabilities at a later date. A discussion of time synchronization methods is best left elsewhere, such as this question.
Notes:
- My embedded device is a Telit GC-864 cellular modem that runs Python 1.5.2+ and only has limited operators (mostly just C operators), no modules, and some of the expected built-in Python types. The exact capabilities are here, if you're interested. I write Python for this device as if I'm writing C code - not very Pythonic, I know.
- I realize NTP is best used only for a time offset, however with limited options, I'm using NTP as an absolute time source (I could add the check for the NTP rollover in 2036 to enable another 136 years of operation).
- The GC-864-V2 device with up-to-date firmware does have NTP capability, but the GC-864 I need to use is stuck on a previous release of firmware.