summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2023-02-13 18:32:42 -0800
committerKaz Kylheku <kaz@kylheku.com>2023-02-13 18:32:42 -0800
commit489e4213a4223a831e2886c324d56e6019188163 (patch)
tree13a6338009b510b77272dd9d2b65b6100a231172
parent8d54fdb9967429c46c8dc84d1c07d994b5c79856 (diff)
downloadtxr-489e4213a4223a831e2886c324d56e6019188163.tar.gz
txr-489e4213a4223a831e2886c324d56e6019188163.tar.bz2
txr-489e4213a4223a831e2886c324d56e6019188163.zip
Support gmtoff and zone in time formatting.
The glibc strftime function can refer to the character string zone, and numeric zone via %Z and %z. So let us populate these from the Lisp structure. * time.c (time_fields_to_tm): Take gmtoff and zone arguments. Store these values in the struct tm, suitably converted, instead of zeros and nulls. In the case of zone, we dynamically allocate a utf-8 string, which will have to be freed. (time_fields_cleanup): New static function. Called to clean up any allocations performed by time_fields_to_tm. (time_struct_to_tm): Drop the strict parameter. This is useless because the underlying function time_fields_to_tm checks for nils and substitutes zeros. This silliness was introduced in a commit made in 2016. Extract the gmtoff and zone, passing these to time_fields_to_tm. (make_time_impl): Pass nil for gmtoff and zone, call time_fields_cleanup. (time_string_meth, time_parse_meth): No need to pass strict parameter to time_struct_to_tm. Need to call time_fields_cleanup.
-rw-r--r--time.c42
1 files changed, 22 insertions, 20 deletions
diff --git a/time.c b/time.c
index dd2945b5..18a000d7 100644
--- a/time.c
+++ b/time.c
@@ -237,7 +237,8 @@ static void time_fields_to_tm(struct tm *ptm,
val year, val month, val day,
val hour, val min, val sec,
val wday, val yday,
- val dst, val self)
+ val dst, val gmtoff, val zone,
+ val self)
{
uses_or2;
ptm->tm_year = c_num(or2(year, zero), self) - 1900;
@@ -257,15 +258,21 @@ static void time_fields_to_tm(struct tm *ptm,
ptm->tm_isdst = 1;
#if HAVE_TM_GMTOFF
- ptm->TM_GMTOFF = 0;
+ ptm->TM_GMTOFF = c_num(or2(gmtoff, zero), self);
#endif
#if HAVE_TM_ZONE
- ptm->TM_ZONE = 0;
+ ptm->TM_ZONE = if3(zone, utf8_dup_to(c_str(zone, self)), 0);
#endif
}
-static void time_struct_to_tm(struct tm *ptm, val time_struct, val strict,
- val self)
+static void time_fields_cleanup(struct tm *ptm)
+{
+#if HAVE_TM_ZONE
+ free(strip_qual(char *, ptm->TM_ZONE));
+#endif
+}
+
+static void time_struct_to_tm(struct tm *ptm, val time_struct, val self)
{
val year = slot(time_struct, year_s);
val month = slot(time_struct, month_s);
@@ -276,20 +283,11 @@ static void time_struct_to_tm(struct tm *ptm, val time_struct, val strict,
val wday = slot(time_struct, wday_s);
val yday = slot(time_struct, yday_s);
val dst = slot(time_struct, dst_s);
-
- if (!strict) {
- year = (year ? year : zero);
- month = (month ? month : zero);
- day = (day ? day : zero);
- hour = (hour ? hour : zero);
- min = (min ? min : zero);
- sec = (sec ? sec : zero);
- wday = (wday ? wday : zero);
- yday = (yday ? yday : zero);
- }
+ val gmtoff = slot(time_struct, gmtoff_s);
+ val zone = slot(time_struct, zone_s);
time_fields_to_tm(ptm, year, month, day, hour, min, sec,
- wday, yday, dst, self);
+ wday, yday, dst, gmtoff, zone, self);
}
static val make_time_impl(time_t (*pmktime)(struct tm *),
@@ -301,8 +299,9 @@ static val make_time_impl(time_t (*pmktime)(struct tm *),
time_t time;
time_fields_to_tm(&local, year, month, day,
- hour, minute, second, nil, nil, isdst, self);
+ hour, minute, second, nil, nil, isdst, nil, nil, self);
time = pmktime(&local);
+ time_fields_cleanup(&local);
return time == -1 ? nil : num_time(time);
}
@@ -426,12 +425,13 @@ static val time_string_meth(val time_struct, val format)
char buffer[512] = "";
char *fmt = utf8_dup_to(c_str(format, self));
- time_struct_to_tm(&tms, time_struct, t, self);
+ time_struct_to_tm(&tms, time_struct, self);
if (strftime(buffer, sizeof buffer, fmt, &tms) == 0)
buffer[0] = 0;
free(fmt);
+ time_fields_cleanup(&tms);
return string_own(utf8_dup_from(buffer));
}
@@ -444,7 +444,7 @@ static val time_parse_meth(val time_struct, val format, val string)
struct tm tms = all_zero_init;
val ret = nil;
- time_struct_to_tm(&tms, time_struct, nil, self);
+ time_struct_to_tm(&tms, time_struct, self);
{
const wchar_t *w_str = c_str(string, self);
@@ -462,6 +462,8 @@ static val time_parse_meth(val time_struct, val format, val string)
free(str);
}
+ time_fields_cleanup(&tms);
+
return ret;
}