prolog - SWI-Prolog 中的 "strptime"

标签 prolog swi-prolog

如何将原子 '2015-12-15T05 PST' 转换为时间戳或日期时间?

我已经尝试过parse_time/3

?- parse_time('2015-12-15T05 PST', '%Y-%m-%dT%H %Z', Stamp)
false.

format_time/3

?- format_time('2015-12-15T05 PST', '%Y-%m-%dT%H %Z', date(Y,M,D,H,M,S,O,TZ,DST)).
ERROR: format_time/3: Arguments are not sufficiently instantiated

最佳答案

根据文档,format_time/3 模式并不能真正帮助您,因为它期望传入所有内容:

format_time(+Out, +Format, +StampOrDateTime)

这意味着您提供每个参数。您希望看到带有 - 前缀的内容,这意味着它正在返回一些内容,这似乎意味着 parse_time/3,但文档中说:

Supported formats for Text are in the table below.

然后它会列出两个选项:rfc_1123iso_8601,这两个选项都不与您的格式真正匹配。这里似乎没有办法提供格式代码,我觉得这真的令人费解,因为这里有底层 Unix 库当然可以做到这一点。

但是,这个问题可以用每个人最喜欢的工具来解决:定语从句语法!这是我的解决方案:

:- use_module(library(dcg/basics)).

myformat(date(Y,M,D,H,_,_,_,TZ,_)) -->
    integer(Y), "-", integer(M), "-", integer(D),
    "T", integer(H), " ", timezone(TZ).

timezone('UTC') --> "UTC".
timezone('UTC') --> "GMT".
timezone(-18000) --> "PST".
timezone(Secs) -->
    [Sign], digit(H0), digit(H1), digit(M0), digit(M1),
    {
     (Sign = 0'+ ; Sign = 0'-),
     number_codes(Hour, [H0,H1]),
     number_codes(Minutes, [M0, M1]),
     (Sign = 0'+
     -> Secs is Hour * 3600 + Minutes * 60
     ;  Secs is -(Hour * 3600 + Minutes * 60))
    }.

my_time_parse(Atom, Date) :-
    atom_codes(Atom, Codes),
    phrase(myformat(Date), Codes).

我确信有学问的人会找到改进这段代码的方法,但它用你的示例数据对我起到了作用。不幸的是,您将需要枚举时区或找到更好的数据源(也许解析系统时区定义?),但如果您先验地知道只需要处理 PST,您可以尝试一下。这是一个例子:

?- my_time_parse('2015-12-15T05 PST', Date).
Date = date(2015, 12, 15, 5, _G3204, _G3205, _G3206, -18000, _G3208) ;
false.

希望这有帮助!

关于prolog - SWI-Prolog 中的 "strptime",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34325572/

相关文章:

Prolog:交换列表的两半

compiler-warnings - 对 SWI Prolog 编译器警告感到困惑

prolog - 更改工作目录 swi-Prolog

http - 在 SWI-Prolog 中读取 https 正文

prolog - current_predicate/1 不适用于 :- dynamic?

prolog - 如何在序言中定义谓词

recursion - 理解Prolog中的递归规则

recursion - 第 N 个素数列表 Prolog

logic - Prolog - 查找当前目录, 'tell' 谓词的相对目录

prolog - 由 swi-prolog 编译的可以接受参数的 .exe 示例