diff --git a/man/remind.1.in b/man/remind.1.in index 969d2e0e..00022f5f 100644 --- a/man/remind.1.in +++ b/man/remind.1.in @@ -3373,6 +3373,12 @@ Creates a \fBTIME\fR with the hour and minute components specified by Returns a \fBTIME\fR object representing the time portion of \fIdatetime\fR. .TP +.B timezone([dq_datetime]) +Returns a string representing the time zone name of the given \fBDATETIME\fR. +If no argument is supplied, \fBRemind\fR uses the value of \fBcurrent()\fR. If +a \fBDATE\fR rather than \fBDATETIME\fR is supplied, \fBRemind\fR uses a +time part of 00:00. +.TP .B today() Returns \fBRemind\fR's notion of "today." This may be the actual system date, or a date supplied on the command line, or the date of the diff --git a/src/funcs.c b/src/funcs.c index d642a512..281606b2 100644 --- a/src/funcs.c +++ b/src/funcs.c @@ -129,6 +129,7 @@ static int FSunrise (func_info *); static int FSunset (func_info *); static int FTime (func_info *); static int FTimepart (func_info *); +static int FTimezone (func_info *); static int FToday (func_info *); static int FTrig (func_info *); static int FTrigback (func_info *); @@ -287,6 +288,7 @@ BuiltinFunc Func[] = { { "sunset", 0, 1, 0, FSunset }, { "time", 2, 2, 1, FTime }, { "timepart", 1, 1, 1, FTimepart }, + { "timezone", 0, 1, 1, FTimezone }, { "today", 0, 0, 0, FToday }, { "trig", 0, NO_MAX, 0, FTrig }, { "trigback", 0, 0, 0, FTrigback }, @@ -2229,6 +2231,46 @@ static int FTimeStuff(int wantmins, func_info *info) return OK; } +static int FTimezone(func_info *info) +{ + int yr, mon, day, hr, min, jul, now; + struct tm local, *withzone; + time_t t; + char buf[64]; + + if (Nargs == 0) { + jul = JulianToday; + now = (SystemTime(0) / 60); + } else { + if (!HASDATE(ARG(0))) return E_BAD_TYPE; + jul = DATEPART(ARG(0)); + if (HASTIME(ARG(0))) { + now = TIMEPART(ARG(0)); + } else { + now = 0; + } + } + FromJulian(jul, &yr, &mon, &day); + hr = now / 60; + min = now % 60; + + memset(&local, 0, sizeof(local)); + local.tm_sec = 0; + local.tm_min = min; + local.tm_hour = hr; + local.tm_mday = day; + local.tm_mon = mon; + local.tm_year = yr-1900; + local.tm_isdst = -1; + + t = mktime(&local); + withzone = localtime(&t); + buf[0] = 0; + tzset(); + strftime(buf, sizeof(buf), "%Z", withzone); + return RetStrVal(buf, info); +} + static int FLocalToUTC(func_info *info) { int yr, mon, day, hr, min, jul; @@ -2241,6 +2283,7 @@ static int FLocalToUTC(func_info *info) hr = TIMEPART(ARG(0))/60; min = TIMEPART(ARG(0))%60; + memset(&local, 0, sizeof(local)); local.tm_sec = 0; local.tm_min = min; local.tm_hour = hr; @@ -2277,6 +2320,7 @@ static int FUTCToLocal(func_info *info) setenv("TZ", "UTC", 1); tzset(); + memset(&utc, 0, sizeof(utc)); utc.tm_sec = 0; utc.tm_min = min; utc.tm_hour = hr; diff --git a/tests/test-rem b/tests/test-rem index d0f49c2e..d9d643ec 100644 --- a/tests/test-rem +++ b/tests/test-rem @@ -370,6 +370,7 @@ EOF ../src/remind -cu '-i$SuppressLRM=1' ../tests/utf-8.rem 1 Nov 2019 >> ../tests/test.out TZ=America/Toronto ../src/remind -dxe ../tests/tz.rem >> ../tests/test.out 2>&1 +TZ=Europe/Berlin ../src/remind -dxe ../tests/tz.rem >> ../tests/test.out 2>&1 # Remove references to SysInclude, which is build-specific grep -F -v '$SysInclude' < ../tests/test.out > ../tests/test.out.1 && mv -f ../tests/test.out.1 ../tests/test.out diff --git a/tests/test.cmp b/tests/test.cmp index a99fb2e7..2343e9cc 100644 --- a/tests/test.cmp +++ b/tests/test.cmp @@ -8460,4 +8460,67 @@ utctolocal(2022-11-06@07:01) => 2022-11-06@02:01 set b utctolocal('2022-12-01@17:00') utctolocal(2022-12-01@17:00) => 2022-12-01@12:00 +set c timezone('2022-07-01') +timezone(2022-07-01) => "EDT" +set c timezone('2022-12-01') +timezone(2022-12-01) => "EST" + +No reminders. +# Test conversion between local time and UTC + +set a localtoutc('2022-01-01@12:00') +localtoutc(2022-01-01@12:00) => 2022-01-01@11:00 +set a localtoutc('2022-03-13@02:59') +localtoutc(2022-03-13@02:59) => 2022-03-13@01:59 +set a localtoutc('2022-03-13@03:00') +localtoutc(2022-03-13@03:00) => 2022-03-13@02:00 +set a localtoutc('2022-03-13@03:01') +localtoutc(2022-03-13@03:01) => 2022-03-13@02:01 +set a localtoutc('2022-06-01@12:00') +localtoutc(2022-06-01@12:00) => 2022-06-01@10:00 +set a localtoutc('2022-11-06@01:59') +localtoutc(2022-11-06@01:59) => 2022-11-06@00:59 +set a localtoutc('2022-11-06@02:00') +localtoutc(2022-11-06@02:00) => 2022-11-06@01:00 +set a localtoutc('2022-11-06@02:01') +localtoutc(2022-11-06@02:01) => 2022-11-06@01:01 +set a localtoutc('2022-12-01@12:00') +localtoutc(2022-12-01@12:00) => 2022-12-01@11:00 + +set b utctolocal('2022-01-01@17:00') +utctolocal(2022-01-01@17:00) => 2022-01-01@18:00 +set b utctolocal('2022-03-13@06:00') +utctolocal(2022-03-13@06:00) => 2022-03-13@07:00 +set b utctolocal('2022-03-13@06:01') +utctolocal(2022-03-13@06:01) => 2022-03-13@07:01 +set b utctolocal('2022-03-13@06:59') +utctolocal(2022-03-13@06:59) => 2022-03-13@07:59 +set b utctolocal('2022-03-13@07:00') +utctolocal(2022-03-13@07:00) => 2022-03-13@08:00 +set b utctolocal('2022-03-13@07:01') +utctolocal(2022-03-13@07:01) => 2022-03-13@08:01 +set b utctolocal('2022-03-13@07:59') +utctolocal(2022-03-13@07:59) => 2022-03-13@08:59 +set b utctolocal('2022-06-01@16:00') +utctolocal(2022-06-01@16:00) => 2022-06-01@18:00 +set b utctolocal('2022-11-06@05:59') +utctolocal(2022-11-06@05:59) => 2022-11-06@06:59 +set b utctolocal('2022-11-06@06:00') +utctolocal(2022-11-06@06:00) => 2022-11-06@07:00 +set b utctolocal('2022-11-06@06:01') +utctolocal(2022-11-06@06:01) => 2022-11-06@07:01 +set b utctolocal('2022-11-06@06:59') +utctolocal(2022-11-06@06:59) => 2022-11-06@07:59 +set b utctolocal('2022-11-06@07:00') +utctolocal(2022-11-06@07:00) => 2022-11-06@08:00 +set b utctolocal('2022-11-06@07:01') +utctolocal(2022-11-06@07:01) => 2022-11-06@08:01 +set b utctolocal('2022-12-01@17:00') +utctolocal(2022-12-01@17:00) => 2022-12-01@18:00 + +set c timezone('2022-07-01') +timezone(2022-07-01) => "CEST" +set c timezone('2022-12-01') +timezone(2022-12-01) => "CET" + No reminders. diff --git a/tests/tz.rem b/tests/tz.rem index b89bd89f..cfce165b 100644 --- a/tests/tz.rem +++ b/tests/tz.rem @@ -25,3 +25,6 @@ set b utctolocal('2022-11-06@06:59') set b utctolocal('2022-11-06@07:00') set b utctolocal('2022-11-06@07:01') set b utctolocal('2022-12-01@17:00') + +set c timezone('2022-07-01') +set c timezone('2022-12-01')