"strptime" 在 SWI-Prolog 中
"strptime" in SWI-Prolog
如何将原子 '2015-12-15T05 PST'
转换为时间戳或日期时间?
我试过了parse_time/3
?- parse_time('2015-12-15T05 PST', '%Y-%m-%dT%H %Z', Stamp)
false.
?- 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_1123
和 iso_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.
希望对您有所帮助!
这个问题来晚了:所需的格式是 close to iso_8601,这将采用格式 "2015-12-15T05-08"
。要将时区 " PST"
替换为 "-08"
,我们可以使用 append
。对于代码:
:- set_prolog_flag(double_quotes, chars).
timezone(" PST", "-08").
timezone(" PDT", "-07").
%% etc
convert_time(Date, Stamp) :-
timezone(Zone, Delta),
append(Front, Zone, Date),
append(Front, Delta, Date2),
string_chars(Date3, Date2),
parse_time(Date3, iso_8601, Stamp).
test :-
convert_time("2015-12-15T05 PST", Stamp),
writeln('Stamp'=Stamp),
fail.
有输出
?- test.
Stamp=1450184400.0
false.
如何将原子 '2015-12-15T05 PST'
转换为时间戳或日期时间?
我试过了parse_time/3
?- parse_time('2015-12-15T05 PST', '%Y-%m-%dT%H %Z', Stamp)
false.
?- 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_1123
和 iso_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.
希望对您有所帮助!
这个问题来晚了:所需的格式是 close to iso_8601,这将采用格式 "2015-12-15T05-08"
。要将时区 " PST"
替换为 "-08"
,我们可以使用 append
。对于代码:
:- set_prolog_flag(double_quotes, chars).
timezone(" PST", "-08").
timezone(" PDT", "-07").
%% etc
convert_time(Date, Stamp) :-
timezone(Zone, Delta),
append(Front, Zone, Date),
append(Front, Delta, Date2),
string_chars(Date3, Date2),
parse_time(Date3, iso_8601, Stamp).
test :-
convert_time("2015-12-15T05 PST", Stamp),
writeln('Stamp'=Stamp),
fail.
有输出
?- test.
Stamp=1450184400.0
false.