From 5ce43f94327ebf98b3eaff49fa6fcda8a88470fb Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 16 Feb 2022 07:31:09 -0800 Subject: time: fix missing day-of-week and day-of-year. The time code entirely neglects the tm_wday and tm_yday fields of struct tm; they are missing from the Lisp time structure, and not referenced anywhere. * time.c (wday_s, yday_s): New symbol variables. (tm_to_time_struct): Transfer tm_wday and tm_yday values to Lisp struct. (time_fields_to_tm): Take wday and yday parameters, convert these and store in the given struct tm. (time_struct_to_tm): Retrieve wday and yday slots, and pass these values to time_fields_to_tm. (make_time_impl): Pass nil for wday and yday arguments of time_fields_to_tm, which is OK since mktime doesn't use those. (time_init): Intern the wday and yday symbols. Add those slots to the time structure. * txr.1: Documented new slots. --- time.c | 27 ++++++++++++++++++++------- txr.1 | 13 +++++++++---- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/time.c b/time.c index 66c7b901..fecb9f40 100644 --- a/time.c +++ b/time.c @@ -45,7 +45,7 @@ #include "time.h" val time_s, time_local_s, time_utc_s, time_string_s, time_parse_s; -val year_s, month_s, day_s, hour_s, min_s, sec_s; +val year_s, month_s, day_s, hour_s, min_s, sec_s, wday_s, yday_s; val dst_s, gmtoff_s, zone_s; val time_sec(void) @@ -164,6 +164,8 @@ static void tm_to_time_struct(val time_struct, struct tm *ptm) slotset(time_struct, hour_s, num_fast(ptm->tm_hour)); slotset(time_struct, min_s, num_fast(ptm->tm_min)); slotset(time_struct, sec_s, num_fast(ptm->tm_sec)); + slotset(time_struct, wday_s, num_fast(ptm->tm_wday)); + slotset(time_struct, yday_s, num_fast(ptm->tm_yday)); slotset(time_struct, dst_s, tnil(ptm->tm_isdst)); #if HAVE_TM_GMTOFF slotset(time_struct, gmtoff_s, num_fast(ptm->TM_GMTOFF)); @@ -233,8 +235,9 @@ val time_struct_utc(val time) static void time_fields_to_tm(struct tm *ptm, val year, val month, val day, - val hour, val min, val sec, val dst, - val self) + val hour, val min, val sec, + val wday, val yday, + val dst, val self) { uses_or2; ptm->tm_year = c_num(or2(year, zero), self) - 1900; @@ -243,6 +246,8 @@ static void time_fields_to_tm(struct tm *ptm, ptm->tm_hour = c_num(or2(hour, zero), self); ptm->tm_min = c_num(or2(min, zero), self); ptm->tm_sec = c_num(or2(sec, zero), self); + ptm->tm_wday = c_num(or2(wday, zero), self); + ptm->tm_yday = c_num(or2(yday, zero), self); if (!dst) ptm->tm_isdst = 0; @@ -268,6 +273,8 @@ static void time_struct_to_tm(struct tm *ptm, val time_struct, val strict, val hour = slot(time_struct, hour_s); val min = slot(time_struct, min_s); val sec = slot(time_struct, sec_s); + val wday = slot(time_struct, wday_s); + val yday = slot(time_struct, yday_s); val dst = slot(time_struct, dst_s); if (!strict) { @@ -277,9 +284,12 @@ static void time_struct_to_tm(struct tm *ptm, val time_struct, val strict, hour = (hour ? hour : zero); min = (min ? min : zero); sec = (sec ? sec : zero); + wday = (wday ? wday : zero); + yday = (yday ? yday : zero); } - time_fields_to_tm(ptm, year, month, day, hour, min, sec, dst, self); + time_fields_to_tm(ptm, year, month, day, hour, min, sec, + wday, yday, dst, self); } static val make_time_impl(time_t (*pmktime)(struct tm *), @@ -291,7 +301,7 @@ static val make_time_impl(time_t (*pmktime)(struct tm *), time_t time; time_fields_to_tm(&local, year, month, day, - hour, minute, second, isdst, self); + hour, minute, second, nil, nil, isdst, self); time = pmktime(&local); return time == -1 ? nil : num_time(time); @@ -486,6 +496,8 @@ void time_init(void) hour_s = intern(lit("hour"), user_package); min_s = intern(lit("min"), user_package); sec_s = intern(lit("sec"), user_package); + wday_s = intern(lit("wday"), user_package); + yday_s = intern(lit("yday"), user_package); dst_s = intern(lit("dst"), user_package); gmtoff_s = intern(lit("gmtoff"), user_package); zone_s = intern(lit("zone"), user_package); @@ -494,8 +506,9 @@ void time_init(void) list(time_local_s, time_utc_s, time_string_s, time_parse_s, nao), list(year_s, month_s, day_s, - hour_s, min_s, sec_s, dst_s, - gmtoff_s, zone_s, nao), + hour_s, min_s, sec_s, + wday_s, yday_s, + dst_s, gmtoff_s, zone_s, nao), nil, nil, nil, nil); static_slot_set(time_st, time_local_s, func_f1(nil, time_meth)); diff --git a/txr.1 b/txr.1 index cd796423..dd4312f3 100644 --- a/txr.1 +++ b/txr.1 @@ -64898,8 +64898,9 @@ function. .coNP Structure @ time .synb .mets (defstruct time nil -.mets \ \ year month day hour min sec dst -.mets \ \ gmtoff zone) +.mets \ \ year month day hour min sec +.mets \ \ wday yday +.mets \ \ dst gmtoff zone) .syne .desc The @@ -64927,13 +64928,17 @@ uses a zero-based month. The slot is a \*(TL Boolean value. The slots .codn hour , .codn min , +.codn sec , +.code wday and -.code sec +.code yday correspond directly to .codn tm_hour , .codn tm_min , +.codn tm_sec , +.code tm_wday and -.codn tm_sec . +.codn tm_yday . The slot .code gmtoff -- cgit v1.2.3