如何从 Apple 的 sqlite3 数据库中确定 "remind me date"

How to determine the "remind me date" from Apple's sqlite3 database

我有一个自定义重复提醒(每 2 周重复一次),名为“每隔一个星期一回收一次”。我写了一个脚本来捕获更改事件并记录所选提醒的下一个截止日期。

(注意,我选择使用 Apple 的 sqlite3 数据库来执行此操作,因为我的数据库非常大,它需要超过 30 秒才能通过 applescript 运行 并且需要一小部分使用 sqlite3).

当我查询数据库以获取所有未完成的提醒和自特定日期以来修改的所有提醒时,我 运行 进入一个用例,如果我不小心“未完成”(并重新完成)一个非常旧的实例重复发生并且意外完成和“未完成”当前实例,我似乎无法弄清楚计算下一个截止日期的逻辑(在 applescript 和提醒应用程序中称为“提醒我日期”)。

这是我的查询和输出,查看所有未完成的提醒和过去 14 天内修改的任何提醒。 (注意,如果我取出所有 WHERE 子句,则此输出包含所有输出的最后几行)。

% sqlite3 "file:/Users/robleach/Library/Reminders/Container_v1/Stores/Data-A6A78E21-BA53-4867-B651-08569C902142.sqlite?mode=ro" -cmd ".mode tabs" "SELECT (978307200 + TASK.ZLASTMODIFIEDDATE) as lmdEpochSecs, TASK.ZPRIORITY AS priority, replace(replace(replace(TASK.ZTITLE1, X'0A', '\n'), X'0D', '\r'), X'09', '\t') AS title, LIST.ZNAME1 AS list, replace(replace(replace(TASK.ZNOTES, X'0A', '\n'), X'0D', '\r'), X'09', '\t') AS notes, TASK.ZCOMPLETED as completed, strftime('%Y-%m-%dT%H:%M:%S',(978307200 + TASK.ZCOMPLETIONDATE),'unixepoch') as completionDate, strftime('%Y-%m-%dT%H:%M:%S',(978307200 + TASK.ZCREATIONDATE),'unixepoch') as creationDate, TASK.ZDISPLAYDATEISALLDAY as isAllday, strftime('%Y-%m-%dT%H:%M:%S',(978307200 + TASK.ZDISPLAYDATEDATE),'unixepoch') as displayDate, strftime('%Y-%m-%dT%H:%M:%S',(978307200 + TASK.ZLASTMODIFIEDDATE),'unixepoch') as modificationDate, TASK.ZFLAGGED as flagged, TASK.ZCKIDENTIFIER as reminderID, strftime('%Y-%m-%dT%H:%M:%S',(978307200 + TASK.ZACKNOWLEDGEDDATE),'unixepoch') as ackDate, strftime('%Y-%m-%dT%H:%M:%S',(978307200 + TASK.ZENDDATE),'unixepoch') as endDate, strftime('%Y-%m-%dT%H:%M:%S',(978307200 + TASK.ZDUEDATE),'unixepoch') as dueDate, strftime('%Y-%m-%dT%H:%M:%S',(978307200 + TASK.ZSTARTDATE),'unixepoch') as startDate FROM ZREMCDOBJECT TASK LEFT JOIN ZREMCDOBJECT LIST on TASK.ZLIST = LIST.Z_PK WHERE LIST.Z_ENT = 21 AND LIST.ZMARKEDFORDELETION = 0 AND TASK.ZMARKEDFORDELETION = 0 AND (TASK.ZCOMPLETED = 0 or modificationDate > '2021-08-03T09:25:08') ORDER BY CASE WHEN TASK.ZDISPLAYDATEDATE IS NULL THEN 1 ELSE 0 END, TASK.ZDISPLAYDATEDATE, TASK.ZPRIORITY;" | grep "Recycling is " | sort -n | perl -e 'while(<>){chomp;@x=split(/\t/);$x[0]=localtime($x[0]);print(join("\t",@x),"\n")}'
lmd priority    title   list    notes   completed   completionDate  creationDate    isAllday    displayDate modificationDate    flagged reminderID  acknowledgedDate    endDate dueDate startDate
Sun Aug  8 21:57:44 2021    0   Recycling is every other Monday ToDo Home Recurring     1   2021-08-09T01:57:44 2017-09-18T16:59:00 0   2021-08-08T22:00:00 2021-08-09T01:57:44 0   AA6C3A21-45F8-4A21-8A29-E20F00C6EFE3            2021-08-08T22:00:00 2021-08-09T04:00:00
Sun Aug  8 21:58:33 2021    0   Recycling is every other Monday ToDo Home Recurring     1   2021-08-09T01:58:33 2017-09-18T16:59:00 0   2021-08-22T22:00:00 2021-08-09T01:58:33 0   E324BFD0-4EC8-41D3-8EF2-0BEA96EC05F0            2021-08-22T22:00:00 2021-08-23T04:00:00
Sun Aug  8 21:58:33 2021    0   Recycling is every other Monday ToDo Home Recurring     0       2017-09-18T16:59:00 0   2021-09-05T22:00:00 2021-08-09T01:58:33 097F85B66-E979-5226-9E87-794C0901AEB2           2021-09-05T22:00:00 2021-09-06T04:00:00
Sun Aug 15 09:19:03 2021    0   Recycling is every other Monday ToDo Home Recurring     1   2021-08-15T13:19:03 2017-09-18T16:59:00 0   2017-07-17T00:00:00 2021-08-15T13:19:03 0   EAA3CD20-D4A7-59F6-B3BF-DD7A32175810            2017-07-17T00:00:00 2017-07-17T04:00:00
Sun Aug 15 12:53:31 2021    0   Recycling is every other Monday ToDo Home Recurring     1   2021-08-15T16:53:31 2017-09-18T16:59:00 0   2121-07-15T22:00:00 2021-08-15T16:53:31 0   0CBB413B-7BD2-4D4E-80EF-612BF08E2DAD            2021-08-08T22:00:00 2021-08-09T04:00:00

为了方便,我手动添加了headers。输出按lmd(last modified date)排序,最近修改的在最下面。

提醒应用程序中唯一不完整的提醒实例的实际提醒 me/due 日期是 2021-08-22。该日期确实出现在返回的行中(第二行)。但是我的脚本正在生成 2121-07-15,这是具有最新 lmd 的行的截止日期。

我的脚本通常将上次修改的条目的截止日期(或显示日期 - 总是看起来相同)记录为下一个截止日期,这通常是正确的,但在这种情况下,它是错误的。而且我似乎无法辨别苹果如何确定提醒我日期的逻辑。包含正确截止日期的行的完成状态为“已完成”,因此如果我选择该行,完成状态将是错误的。唯一状态不完整的行的截止日期比正确的截止日期晚 2 周。

我想为提醒生成的输出是:

Sun Aug 15 12:53:31 2021    0   Recycling is every other Monday ToDo Home Recurring     0       2017-09-18T16:59:00 0   2021-08-22T22:00:00 2021-08-09T01:58:33 0   E324BFD0-4EC8-41D3-8EF2-0BEA96EC05F0            2021-08-22T22:00:00 2021-08-23T04:00:00

但是,我真正感兴趣的唯一数据是完成状态(为 0)和截止日期(/提醒我日期)反映了提醒应用程序显示的内容 (2021-08-22)。

那么如何从该输出中编译正确的组合当前条目?没看懂。

UPDATE:我今天早上再次查看输出以尝试找出逻辑,所以我再次 运行 命令并看到一个新条目没有意义。提醒的最新(新)版本的新截止日期为 2021 年 9 月 5 日。我检查了我的 phone,因为我不记得完成了最新的提醒,并且 phone 仍然显示截止日期为 8/22/2021。这让我开始思考,所以我检查了我正在 运行 查询 sqlite3 的计算机上的提醒应用程序,果然,提醒我的日期显示为 2021 年 9 月 5 日。它不同意我在同一个 iCloud 帐户上的 phone!所以我认为这似乎可能是 iCloud 同步错误。我希望我在它说截止日期是 7 月 15 日时检查过它,但我敢打赌它就是这么说的。我的猜测是我不小心更改了 2 个重复实例的完成状态导致显示同步错误。所以我在 Mac mini 上禁用了提醒同步并重新启用它。提醒从头开始同步。一旦我证实了我的怀疑,我会回来报告。我敢打赌,一旦同步完成,他们就会同意。

结果是最新的提醒我日期(/截止日期) 是否出现在 sqlite 数据库中最近修改的提醒条目中。

问题似乎是 iCloud 提醒同步问题(/bug)。

我一直在我的 iPhone 上的提醒应用程序中查询提醒我的日期,它显示的日期是 2021 年 8 月 22 日,但是当我在我的计算机上打开提醒应用程序时我是 运行 sqlite 命令,remind-me-date 与我 iPhone 的重复提醒副本不一致。

两台设备都使用同一个 iCloud 帐户。我通过关闭提醒同步并重新打开来解决了差异。同步需要一段时间,但完成后,提醒我的日期与我 iPhone 上的一致,并且 sqlite 命令在该提醒的最新版本中显示相同的截止日期。

我认为导致同步问题的提醒修改是:

  1. 之前已完成的旧提醒意外“未完成”,然后是“重新完成”
  2. 最新版本的提醒意外“完成”后跟“未完成”

...虽然我不确定这些发生的顺序。

我怀疑 iCloud 提醒同步可能错误地将这些多个编辑压缩到一个事件中,但是...

提醒的错误副本 did 似乎在今天早上的某个时候自行更新了(我知道这一点是因为我已经 fswatch 设置为查看数据库文件和当它检测到我正在跟踪自动化的提醒发生变化时给我发短信),导致第二个不正确的截止日期(9/5/2021)仍然与我的 phone 的截止日期 8/22 不一致/2021.