mirror of
https://salsa.debian.org/dskoll/remind.git
synced 2026-04-17 14:59:20 +02:00
Update JSON output.
This commit is contained in:
@@ -693,6 +693,7 @@ Its syntax is:
|
||||
[\fBSCANFROM\fR \fIscan_date\fR | \fBFROM\fR \fIstart_date\fR]
|
||||
[\fBDURATION\fR \fIduration\fR]
|
||||
[\fBTAG\fR \fItag\fR]
|
||||
[\fBTZ\fR \fItimezone\fR]
|
||||
[\fBINFO\fR "\fIinfo_string\fR"]
|
||||
\fBMSG\fR | \fBMSF\fR | \fBRUN\fR | \fBCAL\fR | \fBSATISFY\fR |
|
||||
\fBSPECIAL\fR \fIspecial\fR | \fBPS\fR | \fBPSFILE\fR
|
||||
@@ -2042,6 +2043,55 @@ In Purge Mode, \fBRemind\fR will not purge TODOs unless they have been marked
|
||||
as complete. In the case of a recurring TODO, \fBRemind\fR will not purge
|
||||
it until the last occurrence is marked as complete.
|
||||
.PP
|
||||
.SH TIMEZONE SUPPORT
|
||||
.PP
|
||||
The \fBREM\fR command supports an optional \fBTZ\fR keyword, which should
|
||||
be followed by the \fIcase-sensitive\fR time zone name in which the
|
||||
command is to be interpreted. Note that if you use the \fBTZ\fR keyword,
|
||||
then you \fImust also\fR use an \fBAT\fR clause. Here are some examples:
|
||||
.PP
|
||||
.nf
|
||||
REM Wednesday AT 14:00 TZ America/Toronto MSG 2PM Eastern (%2).
|
||||
REM Wednesday AT 23:59 TZ America/Los_Angeles SATISFY [$Td == 13] MSG Foo %b %2.
|
||||
.fi
|
||||
.PP
|
||||
Within a \fBSATISFY\fR clause, all trigger functions are interpreted in
|
||||
the time zone specified in the \fBREM\fR command. Outside the \fBREM\fR
|
||||
command, however, trigger functions are adjusted to the local time
|
||||
zone. If the local time zone is UTC and we feed \fBRemind\fR the
|
||||
following file on 2025-09-04 UTC:
|
||||
.PP
|
||||
.nf
|
||||
SET $AddBlankLines 0
|
||||
BANNER %
|
||||
REM Wednesday AT 14:00 TZ America/Toronto MSG 2PM Eastern (%2).
|
||||
set a $T
|
||||
set b $Tt
|
||||
REM MSG a = [a], b = [b]
|
||||
REM Wednesday AT 23:59 TZ America/Los_Angeles SATISFY [$Td == 13] MSG Foo %b %2.
|
||||
set c $T
|
||||
set d $Tt
|
||||
REM MSG c = [c], d = [d]
|
||||
.fi
|
||||
.PP
|
||||
Then the output is as follows:
|
||||
.PP
|
||||
.nf
|
||||
a = 2025-09-10, b = 18:00
|
||||
c = 2026-05-14, d = 06:59
|
||||
.fi
|
||||
.PP
|
||||
That is because the trigger date of the first (Wednesday, 2025-09-10
|
||||
at 14:00 Eastern time) is 2025-09-10 at 18:00 UTC. In the second case,
|
||||
Wednesday, 13 May 2026 is the SATISFied trigger date, which is
|
||||
adjusted to Thursday, 14 May 2026 at 06:59 UTC because of the
|
||||
time zone adjustment.
|
||||
.PP
|
||||
If you use an invalid time zone name after the \fBTZ\fR keyword,
|
||||
results are undefined. Unfortunately, \fBRemind\fR cannot diagnose
|
||||
this error becase the C library \fBtzset()\fR function has no
|
||||
error return.
|
||||
.PP
|
||||
.SH THE OMIT COMMAND
|
||||
.PP
|
||||
In addition to being a keyword in the \fBREM\fR command,
|
||||
|
||||
@@ -2316,6 +2316,9 @@ static int DoCalRem(ParsePtr p, int col)
|
||||
e->nonconst_expr = nonconst_expr;
|
||||
e->if_depth = get_if_pointer() - get_base_if_pointer();
|
||||
e->trig = trig;
|
||||
if (e->trig.tz) {
|
||||
e->trig.tz = StrDup(e->trig.tz);
|
||||
}
|
||||
e->tt = tim;
|
||||
#ifdef REM_USE_WCHAR
|
||||
e->wc_pos = NULL;
|
||||
@@ -2412,6 +2415,9 @@ static void WriteSimpleEntryProtocol1(CalEntry const *e)
|
||||
void WriteJSONTimeTrigger(TimeTrig const *tt)
|
||||
{
|
||||
PrintJSONKeyPairTime("time", tt->ttime);
|
||||
if (tt->ttime != tt->ttime_orig) {
|
||||
PrintJSONKeyPairTime("time_in_tz", tt->ttime_orig);
|
||||
}
|
||||
PrintJSONKeyPairTime("nexttime", tt->nexttime);
|
||||
PrintJSONKeyPairInt("tdelta", tt->delta);
|
||||
PrintJSONKeyPairInt("trep", tt->rep);
|
||||
@@ -2543,6 +2549,10 @@ void WriteJSONTrigger(Trigger const *t, int include_tags)
|
||||
PrintJSONKeyPairDate("from", t->from);
|
||||
PrintJSONKeyPairInt("priority", t->priority);
|
||||
PrintJSONKeyPairDateTime("eventstart", t->eventstart);
|
||||
if (t->eventstart_orig != NO_TIME &&
|
||||
t->eventstart_orig != t->eventstart) {
|
||||
PrintJSONKeyPairDateTime("eventstart_in_tz", t->eventstart_orig);
|
||||
}
|
||||
if (t->eventduration != NO_TIME) {
|
||||
PrintJSONKeyPairInt("eventduration", t->eventduration);
|
||||
}
|
||||
@@ -2564,6 +2574,7 @@ void WriteJSONTrigger(Trigger const *t, int include_tags)
|
||||
}
|
||||
PrintJSONKeyPairString("tags", DBufValue(&(t->tags)));
|
||||
}
|
||||
PrintJSONKeyPairString("tz", t->tz);
|
||||
}
|
||||
|
||||
static void WriteSimpleEntryProtocol2(CalEntry *e)
|
||||
|
||||
@@ -35,7 +35,7 @@ static int ComputeTrigDuration(TimeTrig const *t);
|
||||
|
||||
static int CalledEnterTimezone = 0;
|
||||
|
||||
int AdjustTriggerForTimeZone(Trigger const *trig, int dse, TimeTrig *tim)
|
||||
int AdjustTriggerForTimeZone(Trigger *trig, int dse, TimeTrig *tim)
|
||||
{
|
||||
int y, m, d, hour, minute;
|
||||
int r;
|
||||
@@ -57,6 +57,8 @@ int AdjustTriggerForTimeZone(Trigger const *trig, int dse, TimeTrig *tim)
|
||||
dse = DSE(tm.tm_year+1900, tm.tm_mon, tm.tm_mday);
|
||||
tim->ttime = tm.tm_hour * 60 + tm.tm_min;
|
||||
SaveAllTriggerInfo(trig, tim, dse, tim->ttime, 1);
|
||||
/* Adjust eventstart also */
|
||||
trig->eventstart = dse * MINUTES_PER_DAY + tim->ttime;
|
||||
if (DebugFlag & DB_PRTTRIG) {
|
||||
fprintf(ErrFp, "%s(%s): Trig(tz_adj %s) = %s, %d %s, %d AT %02d:%02d",
|
||||
GetCurrentFilename(), line_range(LineNoStart, LineNo), trig->tz,
|
||||
@@ -612,6 +614,9 @@ int DoRem(ParsePtr p)
|
||||
}
|
||||
if (tim.ttime != NO_TIME) {
|
||||
PrintJSONKeyPairInt("time", tim.ttime);
|
||||
if (tim.ttime_orig != tim.ttime) {
|
||||
PrintJSONKeyPairInt("time_in_tz", tim.ttime_orig);
|
||||
}
|
||||
}
|
||||
if (p->nonconst_expr) {
|
||||
PrintJSONKeyPairInt("nonconst_expr", 1);
|
||||
@@ -797,6 +802,7 @@ int ParseRem(ParsePtr s, Trigger *trig, TimeTrig *tim)
|
||||
trig->omitfunc[0] = 0;
|
||||
trig->duration_days = 0;
|
||||
trig->eventstart = NO_TIME;
|
||||
trig->eventstart_orig = NO_TIME;
|
||||
trig->eventduration = NO_TIME;
|
||||
trig->maybe_uncomputable = 0;
|
||||
DBufInit(&(trig->tags));
|
||||
@@ -1971,6 +1977,7 @@ int DoSatRemind(Trigger *trig, TimeTrig *tt, ParsePtr p)
|
||||
} else if (dse == start) {
|
||||
if (tt->ttime != NO_TIME) {
|
||||
trig->eventstart = MINUTES_PER_DAY * r + tt->ttime;
|
||||
trig->eventstart_orig = trig->eventstart;
|
||||
if (tt->duration != NO_TIME) {
|
||||
trig->eventduration = tt->duration;
|
||||
}
|
||||
|
||||
@@ -298,6 +298,6 @@ int system_to_stderr(char const *cmd);
|
||||
int system1(char const *cmd);
|
||||
int tz_set_tz (char const *tz);
|
||||
int tz_convert(int year, int month, int day, int hour, int minute, char const *src_tz, char const *tgt_tz, struct tm *tm);
|
||||
int AdjustTriggerForTimeZone(Trigger const *trig, int dse, TimeTrig *tim);
|
||||
int AdjustTriggerForTimeZone(Trigger *trig, int dse, TimeTrig *tim);
|
||||
void EnterTimezone(char const *tz);
|
||||
void ExitTimezone(char const *tz);
|
||||
|
||||
@@ -453,6 +453,7 @@ AdjustTriggerForDuration(int today, int r, Trigger *trig, TimeTrig *tim, int sav
|
||||
/* If we have an AT, save the original event start */
|
||||
if (tim->ttime != NO_TIME) {
|
||||
trig->eventstart = MINUTES_PER_DAY * r + tim->ttime;
|
||||
trig->eventstart_orig = trig->eventstart;
|
||||
if (tim->duration != NO_TIME) {
|
||||
trig->eventduration = tim->duration;
|
||||
}
|
||||
@@ -515,6 +516,7 @@ int ComputeTrigger(int today, Trigger *trig, TimeTrig *tim,
|
||||
if (r == today) {
|
||||
if (tim->ttime != NO_TIME) {
|
||||
trig->eventstart = MINUTES_PER_DAY * r + tim->ttime;
|
||||
trig->eventstart_orig = trig->eventstart;
|
||||
if (tim->duration != NO_TIME) {
|
||||
trig->eventduration = tim->duration;
|
||||
}
|
||||
|
||||
@@ -141,6 +141,7 @@ typedef struct {
|
||||
int priority;
|
||||
int duration_days; /* Duration converted to days to search */
|
||||
int eventstart; /* Original event start (datetime) */
|
||||
int eventstart_orig; /* Original event start in TZ (datetime) */
|
||||
int eventduration; /* Original event duration (minutes) */
|
||||
int maybe_uncomputable; /* Suppress "can't compute trigger" warnings */
|
||||
int addomit; /* Add trigger date to global OMITs */
|
||||
|
||||
Reference in New Issue
Block a user