From fe002557cfefe331ad029c44d990534dc18fff5e Mon Sep 17 00:00:00 2001 From: Dianne Skoll Date: Wed, 3 Sep 2025 11:02:01 -0400 Subject: [PATCH] New approach to handling time zone specs in REM command. --- src/dorem.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/funcs.c | 3 +-- src/globals.h | 2 +- src/init.c | 13 +++++++-- src/main.c | 5 ++++ src/protos.h | 1 + src/types.h | 1 + 7 files changed, 94 insertions(+), 5 deletions(-) diff --git a/src/dorem.c b/src/dorem.c index 5e674e4a..2774a8c4 100644 --- a/src/dorem.c +++ b/src/dorem.c @@ -18,6 +18,7 @@ #include #include +#include #include "types.h" #include "globals.h" @@ -32,6 +33,79 @@ static int ParseUntil (ParsePtr s, Trigger *t, int type); static int ShouldTriggerBasedOnWarn (Trigger const *t, int dse, int *err); static int ComputeTrigDuration(TimeTrig const *t); +static int CalledEnterTimezone = 0; + +static void ExitTimezone(char const *tz) +{ + if (!CalledEnterTimezone) { + fprintf(stderr, "ExitTimezone called without EnterTimezone!!!\n"); + abort(); + } + CalledEnterTimezone = 0; + if (!tz || !*tz) { + /* Nothing to do */ + return; + } + DSEToday = LocalDSEToday; + SysTime = LocalSysTime; + FromDSE(DSEToday, &CurYear, &CurMon, &CurDay); + + if (DebugFlag & DB_SWITCH_ZONE) { + fprintf(stderr, "TZ exit %s: %04d-%02d-%02d %02d:%02d\n", tz, + CurYear, CurMon+1, CurDay, SysTime / 60, SysTime % 60); + } +} + + +static void EnterTimezone(char const *tz) +{ + struct tm tm; + int y, m, d; + time_t t; + + if (CalledEnterTimezone) { + fprintf(stderr, "EnterTimezone called twice in a row!!!\n"); + abort(); + } + + CalledEnterTimezone = 1; + + if (!tz || !*tz) { + /* Stay in local timezone */ + return; + } + + FromDSE(LocalDSEToday, &y, &m, &d); + tm.tm_sec = 0; + tm.tm_min = LocalSysTime % 60; + tm.tm_hour = LocalSysTime / 60; + tm.tm_mday = d; + tm.tm_mon = m; + tm.tm_year = y - 1900; + tm.tm_wday = 0; /* Ignored by mktime */ + tm.tm_yday = 0; /* Ignored by mktime */ + tm.tm_isdst = -1; /* Information not available */ + + t = mktime(&tm); /* Convert local time to seconds */ + + /* Set target timezone */ + (void) tz_set_tz(tz); + + /* Update our variables */ + (void) localtime_r(&t, &tm); + + CurDay = tm.tm_mday; + CurMon = tm.tm_mon; + CurYear = tm.tm_year + 1900; + DSEToday = DSE(CurYear, CurMon, CurDay); + SysTime = tm.tm_min + (tm.tm_hour * 60); + + if (DebugFlag & DB_SWITCH_ZONE) { + fprintf(stderr, "TZ enter %s: %04d-%02d-%02d %02d:%02d\n", tz, + CurYear, CurMon+1, CurDay, SysTime / 60, SysTime % 60); + } +} + void remove_trailing_newlines(DynamicBuffer *buf) { char *s = (char *) DBufValue(buf) + DBufLen(buf) - 1; diff --git a/src/funcs.c b/src/funcs.c index 999cc1ef..ed0d8dee 100644 --- a/src/funcs.c +++ b/src/funcs.c @@ -206,7 +206,6 @@ static int FWkdaynum (func_info *); static int FYear (func_info *); static int SunStuff (int rise, double cosz, int dse); -static int tz_set_tz (char const *tz); /* Caches for extracting months, days, years from dates - may improve performance slightly. */ @@ -3879,7 +3878,7 @@ static void unsetenv(char const *varname) /* Conversion between different timezones. */ /* */ /***************************************************************/ -static int tz_set_tz(char const *tz) +int tz_set_tz(char const *tz) { int r; if (tz == NULL) { diff --git a/src/globals.h b/src/globals.h index a5e9e58c..33188203 100644 --- a/src/globals.h +++ b/src/globals.h @@ -48,7 +48,6 @@ EXTERN FILE *ErrFp; EXTERN int DSEToday; EXTERN int RealToday; EXTERN int LocalDSEToday; -EXTERN int LocalRealToday; EXTERN int CurDay; EXTERN int CurMon; EXTERN int CurYear; @@ -104,6 +103,7 @@ EXTERN INIT( int LocalSysTime, -1); EXTERN INIT( int ParseUntriggered, 0); EXTERN char const *InitialFile; +EXTERN char const *LocalTimeZone; EXTERN int FileAccessDate; EXTERN INIT( int WeekdayOmits, 0); diff --git a/src/init.c b/src/init.c index 2ee8bf51..94fbe859 100644 --- a/src/init.c +++ b/src/init.c @@ -179,6 +179,16 @@ void InitRemind(int argc, char const *argv[]) dse = NO_DATE; + /* Initialize local time zone */ + LocalTimeZone = getenv("TZ"); + if (LocalTimeZone) { + LocalTimeZone = StrDup(LocalTimeZone); + if (!LocalTimeZone) { + fprintf(stderr, "Out of memory!\n"); + exit(1); + } + } + /* Initialize variable hash table */ InitVars(); @@ -221,7 +231,6 @@ void InitRemind(int argc, char const *argv[]) fprintf(ErrFp, "\n"); exit(EXIT_FAILURE); } - LocalRealToday = RealToday; DSEToday = RealToday; LocalDSEToday = DSEToday; FromDSE(DSEToday, &CurYear, &CurMon, &CurDay); @@ -648,6 +657,7 @@ void InitRemind(int argc, char const *argv[]) case 'q': case 'Q': DebugFlag |= DB_TRANSLATE; break; case 'n': case 'N': DebugFlag |= DB_NONCONST; break; case 'u': case 'U': DebugFlag |= DB_UNUSED_VARS; break; + case 'z': case 'Z': DebugFlag |= DB_SWITCH_ZONE; break; default: fprintf(ErrFp, GetErr(M_BAD_DB_FLAG), *(arg-1)); fprintf(ErrFp, "\n"); @@ -1148,7 +1158,6 @@ ProcessLongOption(char const *arg) /* Update RealToday because of TestMode */ RealToday = SystemDate(&CurYear, &CurMon, &CurDay); - LocalRealToday = RealToday; DSEToday = RealToday; LocalDSEToday = DSEToday; FromDSE(DSEToday, &CurYear, &CurMon, &CurDay); diff --git a/src/main.c b/src/main.c index c8c73905..77249c55 100644 --- a/src/main.c +++ b/src/main.c @@ -1439,6 +1439,11 @@ static int DoDebug(ParsePtr p) if (val) DebugFlag |= DB_UNUSED_VARS; else DebugFlag &= ~DB_UNUSED_VARS; break; + case 'z': + case 'Z': + if (val) DebugFlag |= DB_SWITCH_ZONE; + else DebugFlag &= ~DB_SWITCH_ZONE; + break; default: Wprint(GetErr(M_BAD_DB_FLAG), ch); break; diff --git a/src/protos.h b/src/protos.h index 6eb9fa7f..05caffc3 100644 --- a/src/protos.h +++ b/src/protos.h @@ -296,3 +296,4 @@ void remove_trailing_newlines(DynamicBuffer *buf); void set_cloexec(int fd); int system_to_stderr(char const *cmd); int system1(char const *cmd); +int tz_set_tz (char const *tz); diff --git a/src/types.h b/src/types.h index 3c20270f..8f418b77 100644 --- a/src/types.h +++ b/src/types.h @@ -226,6 +226,7 @@ typedef Parser *ParsePtr; /* Pointer to parser structure */ #define DB_TRANSLATE 0x100 #define DB_NONCONST 0x200 #define DB_UNUSED_VARS 0x400 +#define DB_SWITCH_ZONE 0x800 /* Enumeration of the tokens */ enum TokTypes