Merge pull request #582 from triska/format_time
ADDED: format_time//2 for describing strings involving dates and times
This commit is contained in:
@@ -43,3 +43,4 @@ sha3 = "0.8.2"
|
|||||||
blake2 = "0.8.1"
|
blake2 = "0.8.1"
|
||||||
openssl = { version = "0.10.29", features = ["vendored"] }
|
openssl = { version = "0.10.29", features = ["vendored"] }
|
||||||
native-tls = "0.2.4"
|
native-tls = "0.2.4"
|
||||||
|
chrono = "0.4.11"
|
||||||
|
|||||||
@@ -400,9 +400,11 @@ The modules that ship with Scryer Prolog are also called
|
|||||||
* [`arithmetic`](src/prolog/lib/arithmetic.pl)
|
* [`arithmetic`](src/prolog/lib/arithmetic.pl)
|
||||||
Arithmetic predicates such as `lsb/2`, `msb/2` and
|
Arithmetic predicates such as `lsb/2`, `msb/2` and
|
||||||
`number_to_rational/2`.
|
`number_to_rational/2`.
|
||||||
* [`time`](src/prolog/lib/time.pl)
|
* [`time`](src/prolog/lib/time.pl) Predicates for reasoning about
|
||||||
`time/1` reports the CPU time of a goal. It is useful
|
time, including `time/1` to measure the CPU time of a goal,
|
||||||
for measuring the performance of your code.
|
`current_time/1` to obtain the current system time, the nonterminal
|
||||||
|
`format_time//2` to describe strings with dates and times, and
|
||||||
|
`sleep/1` to slow down a computation.
|
||||||
* [`cont`](src/prolog/lib/cont.pl)
|
* [`cont`](src/prolog/lib/cont.pl)
|
||||||
Provides *delimited continuations* via `reset/3` and `shift/1`.
|
Provides *delimited continuations* via `reset/3` and `shift/1`.
|
||||||
* [`random`](src/prolog/lib/random.pl)
|
* [`random`](src/prolog/lib/random.pl)
|
||||||
|
|||||||
@@ -261,6 +261,7 @@ pub enum SystemClauseType {
|
|||||||
InstallNewBlock,
|
InstallNewBlock,
|
||||||
Maybe,
|
Maybe,
|
||||||
CpuNow,
|
CpuNow,
|
||||||
|
CurrentTime,
|
||||||
QuotedToken,
|
QuotedToken,
|
||||||
ReadTermFromChars,
|
ReadTermFromChars,
|
||||||
ResetBlock,
|
ResetBlock,
|
||||||
@@ -398,6 +399,7 @@ impl SystemClauseType {
|
|||||||
&SystemClauseType::LiftedHeapLength => clause_name!("$lh_length"),
|
&SystemClauseType::LiftedHeapLength => clause_name!("$lh_length"),
|
||||||
&SystemClauseType::Maybe => clause_name!("maybe"),
|
&SystemClauseType::Maybe => clause_name!("maybe"),
|
||||||
&SystemClauseType::CpuNow => clause_name!("$cpu_now"),
|
&SystemClauseType::CpuNow => clause_name!("$cpu_now"),
|
||||||
|
&SystemClauseType::CurrentTime => clause_name!("$current_time"),
|
||||||
&SystemClauseType::ModuleAssertDynamicPredicateToFront => {
|
&SystemClauseType::ModuleAssertDynamicPredicateToFront => {
|
||||||
clause_name!("$module_asserta")
|
clause_name!("$module_asserta")
|
||||||
}
|
}
|
||||||
@@ -589,6 +591,7 @@ impl SystemClauseType {
|
|||||||
("$lh_length", 1) => Some(SystemClauseType::LiftedHeapLength),
|
("$lh_length", 1) => Some(SystemClauseType::LiftedHeapLength),
|
||||||
("$maybe", 0) => Some(SystemClauseType::Maybe),
|
("$maybe", 0) => Some(SystemClauseType::Maybe),
|
||||||
("$cpu_now", 1) => Some(SystemClauseType::CpuNow),
|
("$cpu_now", 1) => Some(SystemClauseType::CpuNow),
|
||||||
|
("$current_time", 1) => Some(SystemClauseType::CurrentTime),
|
||||||
("$module_exists", 1) => Some(SystemClauseType::ModuleExists),
|
("$module_exists", 1) => Some(SystemClauseType::ModuleExists),
|
||||||
("$module_of", 2) => Some(SystemClauseType::ModuleOf),
|
("$module_of", 2) => Some(SystemClauseType::ModuleOf),
|
||||||
("$module_retract_clause", 5) => Some(SystemClauseType::ModuleRetractClause),
|
("$module_retract_clause", 5) => Some(SystemClauseType::ModuleRetractClause),
|
||||||
|
|||||||
@@ -1,19 +1,73 @@
|
|||||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
Written April 2020 by Markus Triska (triska@metalevel.at)
|
Written 2020 by Markus Triska (triska@metalevel.at)
|
||||||
Part of Scryer Prolog.
|
Part of Scryer Prolog.
|
||||||
|
|
||||||
This library provides predicates for reasoning about time.
|
This library provides predicates for reasoning about time.
|
||||||
Reasoning about time stamps would be a useful addition, for example
|
|
||||||
by obtaining the current time, comparing and formatting it.
|
|
||||||
|
|
||||||
'$cpu_now' can be replaced by statistics/2 once that is implemented.
|
current_time(T) yields the current system time in an opaque form,
|
||||||
|
called a time stamp. Use format_time//2 to describe strings that
|
||||||
|
contain attributes of the time stamp.
|
||||||
|
|
||||||
|
The nonterminal format_time//2 describes a list of characters that
|
||||||
|
are formatted according to a format string. Usage:
|
||||||
|
|
||||||
|
phrase(format_time(FormatString, TimeStamp), Cs)
|
||||||
|
|
||||||
|
TimeStamp represents a moment in time in an opaque form, as for
|
||||||
|
example obtained by current_time/1.
|
||||||
|
|
||||||
|
FormatString is a list of characters that are interpreted literally,
|
||||||
|
except for the following specifiers (and possibly more in the future):
|
||||||
|
|
||||||
|
%Y year of the time stamp. Example: 2020.
|
||||||
|
%m month number (01-12), zero-padded to 2 digits
|
||||||
|
%d day number (01-31), zero-padded to 2 digits
|
||||||
|
%H hour number (00-24), zero-padded to 2 digits
|
||||||
|
%M minute number (00-59), zero-padded to 2 digits
|
||||||
|
%S second number (00-60), zero-padded to 2 digits
|
||||||
|
%b abbreviated month name, always 3 letters
|
||||||
|
%a abbreviated weekday name, always 3 letters
|
||||||
|
%A full weekday name
|
||||||
|
%j day of the year (001-366), zero-padded to 3 digits
|
||||||
|
%% the literal %
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
?- current_time(T), phrase(format_time("%d.%m.%Y (%H:%M:%S)", T), Cs).
|
||||||
|
T = [...], Cs = "11.06.2020 (00:24:32)"
|
||||||
|
; false.
|
||||||
|
|
||||||
|
sleep(S) sleeps for S seconds (a floating point number).
|
||||||
|
|
||||||
|
time(Goal) reports the execution time of Goal.
|
||||||
|
|
||||||
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||||
|
|
||||||
:- module(time, [max_sleep_time/1, sleep/1, time/1]).
|
:- module(time, [max_sleep_time/1, sleep/1, time/1, current_time/1, format_time//2]).
|
||||||
|
|
||||||
:- use_module(library(format)).
|
:- use_module(library(format)).
|
||||||
:- use_module(library(iso_ext)).
|
:- use_module(library(iso_ext)).
|
||||||
:- use_module(library(error)).
|
:- use_module(library(error)).
|
||||||
|
:- use_module(library(dcgs)).
|
||||||
|
:- use_module(library(lists)).
|
||||||
|
:- use_module(library(charsio), [read_term_from_chars/2]).
|
||||||
|
|
||||||
|
current_time(T) :-
|
||||||
|
'$current_time'(T0),
|
||||||
|
read_term_from_chars(T0, T).
|
||||||
|
|
||||||
|
format_time([], _) --> [].
|
||||||
|
format_time(['%','%'|Fs], T) --> !, "%", format_time(Fs, T).
|
||||||
|
format_time(['%',Spec|Fs], T) --> !,
|
||||||
|
( { member(Spec=Value, T) } ->
|
||||||
|
list(Value)
|
||||||
|
; { domain_error(time_specifier, Spec, format_time//2) }
|
||||||
|
),
|
||||||
|
format_time(Fs, T).
|
||||||
|
format_time([F|Fs], T) --> [F], format_time(Fs, T).
|
||||||
|
|
||||||
|
list([]) --> [].
|
||||||
|
list([L|Ls]) --> [L], list(Ls).
|
||||||
|
|
||||||
max_sleep_time(0xfffffffffffffbff).
|
max_sleep_time(0xfffffffffffffbff).
|
||||||
|
|
||||||
@@ -26,6 +80,9 @@ sleep(T) :-
|
|||||||
; '$sleep'(T)
|
; '$sleep'(T)
|
||||||
).
|
).
|
||||||
|
|
||||||
|
|
||||||
|
% '$cpu_now' can be replaced by statistics/2 once that is implemented.
|
||||||
|
|
||||||
time(Goal) :-
|
time(Goal) :-
|
||||||
'$cpu_now'(T0),
|
'$cpu_now'(T0),
|
||||||
setup_call_cleanup(true,
|
setup_call_cleanup(true,
|
||||||
|
|||||||
@@ -33,8 +33,9 @@ use std::ops::Sub;
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::num::NonZeroU32;
|
use std::num::NonZeroU32;
|
||||||
|
|
||||||
use std::time::Duration;
|
use std::time::{Duration, SystemTime};
|
||||||
use cpu_time::ProcessTime;
|
use cpu_time::ProcessTime;
|
||||||
|
use chrono::{offset::Local,DateTime};
|
||||||
|
|
||||||
use crate::crossterm::event::{read, Event, KeyCode, KeyEvent, KeyModifiers};
|
use crate::crossterm::event::{read, Event, KeyCode, KeyEvent, KeyModifiers};
|
||||||
use crate::crossterm::terminal::{enable_raw_mode, disable_raw_mode};
|
use crate::crossterm::terminal::{enable_raw_mode, disable_raw_mode};
|
||||||
@@ -3137,6 +3138,21 @@ impl MachineState {
|
|||||||
|
|
||||||
self.unify(a1, addr);
|
self.unify(a1, addr);
|
||||||
}
|
}
|
||||||
|
&SystemClauseType::CurrentTime => {
|
||||||
|
let system_time = SystemTime::now();
|
||||||
|
let datetime: DateTime<Local> = system_time.into();
|
||||||
|
|
||||||
|
let mut fstr = "[".to_string();
|
||||||
|
let specifiers = vec!["d","m","Y","y","H","M","S","b","B","a","A","w","u","U","W","j","D","x","v"];
|
||||||
|
for spec in specifiers {
|
||||||
|
fstr.push_str(&format!("'{}'=\"%{}\", ", spec, spec).to_string());
|
||||||
|
}
|
||||||
|
fstr.push_str("finis].");
|
||||||
|
let str = { let s = datetime.format(&fstr).to_string();
|
||||||
|
self.heap.put_complete_string(&s)
|
||||||
|
};
|
||||||
|
self.unify(self[temp_v!(1)], str);
|
||||||
|
}
|
||||||
&SystemClauseType::OpDeclaration => {
|
&SystemClauseType::OpDeclaration => {
|
||||||
let priority = self[temp_v!(1)];
|
let priority = self[temp_v!(1)];
|
||||||
let specifier = self[temp_v!(2)];
|
let specifier = self[temp_v!(2)];
|
||||||
|
|||||||
Reference in New Issue
Block a user