3636#include "portmodules.h"
3737#include "rtc.h"
3838
39- #define DAYS_PER_400Y (365*400 + 97)
40- #define DAYS_PER_100Y (365*100 + 24)
41- #define DAYS_PER_4Y (365*4 + 1)
42-
43- typedef struct {
44- uint16_t tm_year ; // i.e. 2014
45- uint8_t tm_mon ; // 1..12
46- uint8_t tm_mday ; // 1..31
47- uint8_t tm_hour ; // 0..23
48- uint8_t tm_min ; // 0..59
49- uint8_t tm_sec ; // 0..59
50- uint8_t tm_wday ; // 0..6 0 = Monday
51- uint16_t tm_yday ; // 1..366
52- } mod_struct_time ;
53-
5439/// \module time - time related functions
5540///
5641/// The `time` module provides functions for getting the current time and date,
@@ -63,7 +48,7 @@ STATIC bool is_leap_year(mp_uint_t year) {
6348}
6449
6550// Month is one based
66- STATIC mp_uint_t days_in_month (mp_uint_t year , mp_uint_t month ) {
51+ STATIC mp_uint_t mod_time_days_in_month (mp_uint_t year , mp_uint_t month ) {
6752 mp_uint_t mdays = days_since_jan1 [month ] - days_since_jan1 [month - 1 ];
6853 if (month == 2 && is_leap_year (year )) {
6954 mdays ++ ;
@@ -73,7 +58,7 @@ STATIC mp_uint_t days_in_month(mp_uint_t year, mp_uint_t month) {
7358
7459// compute the day of the year, between 1 and 366
7560// month should be between 1 and 12, date should start at 1
76- mp_uint_t mod_time_year_day (mp_uint_t year , mp_uint_t month , mp_uint_t date ) {
61+ STATIC mp_uint_t mod_time_year_day (mp_uint_t year , mp_uint_t month , mp_uint_t date ) {
7762 mp_uint_t yday = days_since_jan1 [month - 1 ] + date ;
7863 if (month >= 3 && is_leap_year (year )) {
7964 yday += 1 ;
@@ -102,11 +87,24 @@ mp_uint_t mod_time_seconds_since_2000(mp_uint_t year, mp_uint_t month, mp_uint_t
10287
10388#define LEAPOCH ((31 + 29) * 86400)
10489
105- void mod_time_seconds_since_2000_to_struct_time (mp_uint_t t , mod_struct_time * tm ) {
106- memset (tm , 0 , sizeof (* tm ));
90+ #define DAYS_PER_400Y (365*400 + 97)
91+ #define DAYS_PER_100Y (365*100 + 24)
92+ #define DAYS_PER_4Y (365*4 + 1)
93+
94+ typedef struct {
95+ uint16_t tm_year ; // i.e. 2014
96+ uint8_t tm_mon ; // 1..12
97+ uint8_t tm_mday ; // 1..31
98+ uint8_t tm_hour ; // 0..23
99+ uint8_t tm_min ; // 0..59
100+ uint8_t tm_sec ; // 0..59
101+ uint8_t tm_wday ; // 0..6 0 = Monday
102+ uint16_t tm_yday ; // 1..366
103+ } mod_struct_time ;
107104
105+ STATIC void mod_time_seconds_since_2000_to_struct_time (mp_uint_t t , mod_struct_time * tm ) {
108106 // The following algorithm was adapted from musl's __secs_to_tm and adapted
109- // for differences in MicroPython 's timebase.
107+ // for differences in Micro Python 's timebase.
110108
111109 mp_int_t seconds = t - LEAPOCH ;
112110
@@ -146,17 +144,21 @@ void mod_time_seconds_since_2000_to_struct_time(mp_uint_t t, mod_struct_time *tm
146144 }
147145 days -= (years * 365 );
148146
147+ /* We will compute tm_yday at the very end
149148 mp_int_t leap = !years && (q_cycles || !c_cycles);
150149
151150 tm->tm_yday = days + 31 + 28 + leap;
152151 if (tm->tm_yday >= 365 + leap) {
153152 tm->tm_yday -= 365 + leap;
154153 }
155154
155+ tm->tm_yday++; // Make one based
156+ */
157+
156158 tm -> tm_year = 2000 + years + 4 * q_cycles + 100 * c_cycles + 400 * qc_cycles ;
157159
158160 // Note: days_in_month[0] corresponds to March
159- static const int8_t days_in_month [] = {31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 , 31 , 29 };
161+ STATIC const int8_t days_in_month [] = {31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 , 31 , 29 };
160162
161163 mp_int_t month ;
162164 for (month = 0 ; days_in_month [month ] <= days ; month ++ ) {
@@ -170,9 +172,9 @@ void mod_time_seconds_since_2000_to_struct_time(mp_uint_t t, mod_struct_time *tm
170172 }
171173 tm -> tm_mday = days + 1 ; // Make one based
172174 tm -> tm_mon ++ ; // Make one based
173- tm -> tm_yday ++ ; // Make one based
174- }
175175
176+ tm -> tm_yday = mod_time_year_day (tm -> tm_year , tm -> tm_mon , tm -> tm_mday );
177+ }
176178
177179/// \function localtime([secs])
178180/// Convert a time expressed in seconds since Jan 1, 2000 into an 8-tuple which
@@ -205,22 +207,22 @@ STATIC mp_obj_t time_localtime(uint n_args, const mp_obj_t *args) {
205207 mp_obj_new_int (mod_time_year_day (2000 + date .Year , date .Month , date .Date )),
206208 };
207209 return mp_obj_new_tuple (8 , tuple );
210+ } else {
211+ mp_int_t seconds = mp_obj_get_int (args [0 ]);
212+ mod_struct_time tm ;
213+ mod_time_seconds_since_2000_to_struct_time (seconds , & tm );
214+ mp_obj_t tuple [8 ] = {
215+ tuple [0 ] = mp_obj_new_int (tm .tm_year ),
216+ tuple [1 ] = mp_obj_new_int (tm .tm_mon ),
217+ tuple [2 ] = mp_obj_new_int (tm .tm_mday ),
218+ tuple [3 ] = mp_obj_new_int (tm .tm_hour ),
219+ tuple [4 ] = mp_obj_new_int (tm .tm_min ),
220+ tuple [5 ] = mp_obj_new_int (tm .tm_sec ),
221+ tuple [6 ] = mp_obj_new_int (tm .tm_wday ),
222+ tuple [7 ] = mp_obj_new_int (tm .tm_yday ),
223+ };
224+ return mp_obj_new_tuple (8 , tuple );
208225 }
209-
210- mp_int_t seconds = mp_obj_get_int (args [0 ]);
211- mod_struct_time tm ;
212- mod_time_seconds_since_2000_to_struct_time (seconds , & tm );
213- mp_obj_t tuple [8 ] = {
214- mp_obj_new_int (tm .tm_year ),
215- mp_obj_new_int (tm .tm_mon ),
216- mp_obj_new_int (tm .tm_mday ),
217- mp_obj_new_int (tm .tm_hour ),
218- mp_obj_new_int (tm .tm_min ),
219- mp_obj_new_int (tm .tm_sec ),
220- mp_obj_new_int (tm .tm_wday ),
221- mp_obj_new_int (tm .tm_yday ),
222- };
223- return mp_obj_new_tuple (8 , tuple );
224226}
225227MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (time_localtime_obj , 0 , 1 , time_localtime );
226228
@@ -248,12 +250,12 @@ STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
248250 mp_int_t minutes = mp_obj_get_int (elem [4 ]);
249251 mp_int_t seconds = mp_obj_get_int (elem [5 ]);
250252
251- // Normalize the tuple. This allows things like:
253+ // Normalise the tuple. This allows things like:
252254 //
253255 // tm_tomorrow = list(time.localtime())
254256 // tm_tomorrow[2] += 1 # Adds 1 to mday
255257 // tomorrow = time.mktime(tm_tommorrow)
256- //
258+ //
257259 // And not have to worry about all the weird overflows.
258260 //
259261 // You can subtract dates/times this way as well.
@@ -289,10 +291,10 @@ STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
289291 month = 12 ;
290292 year -- ;
291293 }
292- mday += days_in_month (year , month );
294+ mday += mod_time_days_in_month (year , month );
293295 }
294- while (mday > days_in_month (year , month )) {
295- mday -= days_in_month (year , month );
296+ while (mday > mod_time_days_in_month (year , month )) {
297+ mday -= mod_time_days_in_month (year , month );
296298 if (++ month == 13 ) {
297299 month = 1 ;
298300 year ++ ;
0 commit comments