日期时间转换的极端情况的正确错误是什么?
What is the right error for corner cases of datetime conversion?
TL;DR: 谓词 datime/2
(由 SICStus Prolog 和 SWI-Prolog 提供)将 UNIX time 与包含年、月、日、时、分、秒。
对于一些极端情况,我得到了奇怪的答案,这让我想知道:
在这些情况下,符合 ISO 标准的 Prolog 系统应该引发哪些错误?
首先,这是 datime/2
documentation—part of the SICStus Prolog Manual:
<strong>now(-When)</strong>
Unifies the current date and time as a UNIX timestamp with When
.
<strong>datime(-Datime)</strong>
Unifies Datime
with the current date and time as a datime/6
record of the form datime(Year,Month,Day,Hour,Min,Sec)
. All fields are integers.
<strong>datime(+When,-Datime)</strong>
<strong>datime(-When,+Datime)</strong>
Convert a time stamp, as obtained by now/1
, to a datime/6
record. Can be used in both directions.
所以这是一些虚假的 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 系统应该引发哪些错误?
您想确定 Unix 时间戳值不合理地偏离“预期”范围的情况的适当错误。我不清楚负数是否有意义。但至少,它们似乎在 0..1972 年产生了合理的日期。第二个参数可能是一个适当的域,或者对于不可统一的术语来说只是失败。
从 7.12.2 中现有的 error classification 我们有以下候选人:
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,_,_,_,_,_)).
您可以为任何非基础术语产生实例化错误。
TL;DR: 谓词 datime/2
(由 SICStus Prolog 和 SWI-Prolog 提供)将 UNIX time 与包含年、月、日、时、分、秒。
对于一些极端情况,我得到了奇怪的答案,这让我想知道: 在这些情况下,符合 ISO 标准的 Prolog 系统应该引发哪些错误?
首先,这是 datime/2
documentation—part of the SICStus Prolog Manual:
<strong>now(-When)</strong>
Unifies the current date and time as a UNIX timestamp withWhen
.
<strong>datime(-Datime)</strong>
UnifiesDatime
with the current date and time as adatime/6
record of the formdatime(Year,Month,Day,Hour,Min,Sec)
. All fields are integers.
<strong>datime(+When,-Datime)</strong>
<strong>datime(-When,+Datime)</strong>
Convert a time stamp, as obtained bynow/1
, to adatime/6
record. Can be used in both directions.
所以这是一些虚假的 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 系统应该引发哪些错误?
您想确定 Unix 时间戳值不合理地偏离“预期”范围的情况的适当错误。我不清楚负数是否有意义。但至少,它们似乎在 0..1972 年产生了合理的日期。第二个参数可能是一个适当的域,或者对于不可统一的术语来说只是失败。
从 7.12.2 中现有的 error classification 我们有以下候选人:
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,_,_,_,_,_)).
您可以为任何非基础术语产生实例化错误。