首页 > 解决方案 > 对于日期时间转换的极端情况,正确的错误是什么?

问题描述

TL;DR:     谓词datime/2(由 SICStus Prolog 和 SWI-Prolog 提供)将UNIX 时间与包含年、月、日、小时、分钟和秒的记录相关联。

对于某些极端情况,我得到了奇怪的答案,这让我想知道: 在这些情况下,符合 ISO 标准的 Prolog 系统应该引发哪些错误?


首先,这里是datime/2文档——SICStus Prolog 手册的一部分:

now(-When)     将当前日期和时间统一为 UNIX 时间戳When

datime(-Datime)Datime与当前日期时间     统一datime/6为表格的记录datime(Year,Month,Day,Hour,Min,Sec)。所有字段都是整数。

datime(+When,-Datime) datime(-When,+Datime)     将通过 获得的时间戳转换为now/1记录datime/6可以双向使用。

所以这里有一些虚假的 SICStus Prolog 4.6.0 输出:

| ?- use_module(library(system)).
yes
| ?- datime(X,Y).
no                           % expected: result | error
| ?- datime(-67768200000000000,X).
no                           % expected: result | error
| ?- datime(X,datime(19700000000000,1,1,1,0,0)).
X = -32029950380687608 ? ;   % expected: X >= 0
no

SWI-Prolog 8.2.0 给出了一些奇怪的“答案”:

?- use_module(library(dialect/sicstus/system)).
true.

?- datime(X,datime(1970,1,1,1,0,0)).
ERROR: Arguments are not sufficiently instantiated
% expected: X = 0

?- datime(10000000000000000000000000,X).
X = datime(1901, 1461302465, 32753, 9, 35, 13).

?- datime(1000000000000000000000000000,X).
X = datime(1901, 1461302465, 32753, 9, 35, 13).

?- datime(100000000000000000000000000000,X).
X = datime(1901, 1461302465, 32753, 9, 35, 13).
% expected: different answers for different queries

那么: 在这些情况下,符合 ISO 标准的 Prolog 系统应该引发哪些错误?

标签: prologiso-prolog

解决方案


如果 Unix 时间戳值不合理地超出“预期”范围,您希望确定适当的错误。我不清楚负数是否有意义。但至少,它们似乎在 0..1972 年产生了合理的日期。第二个参数可能是一个正确的域,或者只是因为不可统一的术语而失败。

从 7.12.2 中现有的错误分类,我们有以下候选:

b) 类型错误。指定一个特殊类型似乎有点牵强。毕竟,即使是非负数也不值得一个单独的类型,而是它们是一个域not_less_than_zero

c) 域错误。这似乎是一个不错的候选人。所以域可能是 unix_timestamp——如果它是一个定义良好的数据类型;或datime

f) 表示错误。虽然类型和域错误意味着语义失败(“这样的时间不存在”),但表示错误却没有。它只是指出当前的处理器不能代表那个日期,但没有给出关于这可能意味着什么的结论。

所以我倾向于支持 f,仅仅是因为时间的概念似乎没有限制,甚至没有年份(或时间戳)7^7^7。我知道那是真正的乐观...

两种实现似乎都有一些实例化错误的问题,SWI 产生了太多的错误,而 SICStus 不够——这个库在 SICStus 和 Quintus 血统中相对较新。

作为实例化错误的一般规则,请考虑5.5.12中新选项的要求。因此,如果第二个参数的实例是有效日期,则必须存在实例化错误。但是,如果没有有效的实例但组件仍然是变量,也可能会产生实例化错误。想想datime(T, datime(noyear,_,_,_,_,_)).你可能会为任何非基础术语产生实例化错误。


推荐阅读