current_time/1 yields the current system time as an opaque time stamp.
blake2 = "0.8.1"
openssl = { version = "0.10.29", features = ["vendored"] }
native-tls = "0.2.4"
+chrono = "0.4.11"
* [`arithmetic`](src/prolog/lib/arithmetic.pl)
Arithmetic predicates such as `lsb/2`, `msb/2` and
`number_to_rational/2`.
-* [`time`](src/prolog/lib/time.pl)
- `time/1` reports the CPU time of a goal. It is useful
- for measuring the performance of your code.
+* [`time`](src/prolog/lib/time.pl) Predicates for reasoning about
+ time, including `time/1` to measure the CPU time of a goal,
+ `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)
Provides *delimited continuations* via `reset/3` and `shift/1`.
* [`random`](src/prolog/lib/random.pl)
InstallNewBlock,
Maybe,
CpuNow,
+ CurrentTime,
QuotedToken,
ReadTermFromChars,
ResetBlock,
&SystemClauseType::LiftedHeapLength => clause_name!("$lh_length"),
&SystemClauseType::Maybe => clause_name!("maybe"),
&SystemClauseType::CpuNow => clause_name!("$cpu_now"),
+ &SystemClauseType::CurrentTime => clause_name!("$current_time"),
&SystemClauseType::ModuleAssertDynamicPredicateToFront => {
clause_name!("$module_asserta")
}
("$lh_length", 1) => Some(SystemClauseType::LiftedHeapLength),
("$maybe", 0) => Some(SystemClauseType::Maybe),
("$cpu_now", 1) => Some(SystemClauseType::CpuNow),
+ ("$current_time", 1) => Some(SystemClauseType::CurrentTime),
("$module_exists", 1) => Some(SystemClauseType::ModuleExists),
("$module_of", 2) => Some(SystemClauseType::ModuleOf),
("$module_retract_clause", 5) => Some(SystemClauseType::ModuleRetractClause),
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Part of Scryer Prolog.
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(iso_ext)).
:- 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).
; '$sleep'(T)
).
+
+% '$cpu_now' can be replaced by statistics/2 once that is implemented.
+
time(Goal) :-
'$cpu_now'(T0),
setup_call_cleanup(true,
use std::rc::Rc;
use std::num::NonZeroU32;
-use std::time::Duration;
+use std::time::{Duration, SystemTime};
use cpu_time::ProcessTime;
+use chrono::{offset::Local,DateTime};
use crate::crossterm::event::{read, Event, KeyCode, KeyEvent, KeyModifiers};
use crate::crossterm::terminal::{enable_raw_mode, disable_raw_mode};
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 => {
let priority = self[temp_v!(1)];
let specifier = self[temp_v!(2)];