Struct hyper_scripter::script_time::ScriptTime
source · pub struct ScriptTime<T = ()> { /* private fields */ }Expand description
可能帶著資料的時間。 如果有資料,代表「這些資料是新的產生,應儲存起來但還未存」 如果沒資料,就視為上次儲存的一個快照,只記得時間就好,因為我們通常不會需要上一次存下的資料
Implementations§
source§impl<T> ScriptTime<T>
impl<T> ScriptTime<T>
sourcepub fn now(data: T) -> Self
pub fn now(data: T) -> Self
Examples found in repository?
292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
pub fn read(&mut self) {
self.read_time = ScriptTime::now(());
}
pub fn write(&mut self) {
let now = ScriptTime::now(());
self.read_time = now.clone();
self.write_time = now;
}
pub fn miss(&mut self) {
self.miss_time = Some(ScriptTime::now(()));
}
pub fn exec(
&mut self,
content: String,
args: &[String],
env_record: String,
dir: Option<PathBuf>,
) {
log::trace!("{:?} 執行內容為 {}", self, content);
let args_ser = serde_json::to_string(args).unwrap();
self.exec_time = Some(ScriptTime::now((content, args_ser, env_record, dir)));
// NOTE: no readtime, otherwise it will be hard to tell what event was caused by what operation.
self.exec_count += 1;
}
pub fn exec_done(&mut self, code: i32, main_event_id: i64) {
log::trace!("{:?} 執行結果為 {}", self, code);
self.exec_done_time = Some(ScriptTime::now((code, main_event_id)));
}
pub fn neglect(&mut self) {
self.neglect_time = Some(ScriptTime::now(()))
}
pub fn builder(
id: i64,
name: ScriptName,
ty: ScriptType,
tags: impl Iterator<Item = Tag>,
) -> ScriptBuilder {
ScriptBuilder {
id,
name,
ty,
tags: tags.collect(),
read_time: None,
miss_time: None,
created_time: None,
exec_time: None,
write_time: None,
exec_done_time: None,
neglect_time: None,
humble_time: None,
exec_count: 0,
}
}
}
pub trait IntoScriptName {
fn into_script_name(self) -> Result<ScriptName>;
fn into_script_name_unchecked(self) -> Result<ScriptName>
where
Self: Sized,
{
self.into_script_name()
}
}
impl IntoScriptName for u32 {
fn into_script_name(self) -> Result<ScriptName> {
Ok(ScriptName::Anonymous(self))
}
}
impl IntoScriptName for ConcreteScriptName {
fn into_script_name(self) -> Result<ScriptName> {
Ok(ScriptName::Named(self))
}
}
#[inline]
fn string_into_script_name(s: String, check: bool) -> Result<ScriptName> {
log::debug!("解析腳本名:{} {}", s, check);
if let Some(id) = ScriptName::valid(&s, false, false, check)? {
id.into_script_name()
} else {
Ok(ScriptName::Named(ConcreteScriptName::new_unchecked(s))) // NOTE: already checked by `ScriptName::valid`
}
}
impl IntoScriptName for String {
fn into_script_name(self) -> Result<ScriptName> {
string_into_script_name(self, true)
}
fn into_script_name_unchecked(self) -> Result<ScriptName> {
string_into_script_name(self, false)
}
}
impl IntoScriptName for ScriptName {
fn into_script_name(self) -> Result<ScriptName> {
Ok(self)
}
}
#[derive(Debug)]
pub struct ScriptBuilder {
pub name: ScriptName,
read_time: Option<NaiveDateTime>,
miss_time: Option<NaiveDateTime>,
created_time: Option<NaiveDateTime>,
write_time: Option<NaiveDateTime>,
exec_time: Option<NaiveDateTime>,
neglect_time: Option<NaiveDateTime>,
humble_time: Option<NaiveDateTime>,
exec_done_time: Option<NaiveDateTime>,
exec_count: u64,
id: i64,
tags: HashSet<Tag>,
ty: ScriptType,
}
impl ScriptBuilder {
pub fn exec_count(&mut self, count: u64) -> &mut Self {
self.exec_count = count;
self
}
pub fn exec_time(&mut self, time: NaiveDateTime) -> &mut Self {
self.exec_time = Some(time);
self
}
pub fn exec_done_time(&mut self, time: NaiveDateTime) -> &mut Self {
self.exec_done_time = Some(time);
self
}
pub fn read_time(&mut self, time: NaiveDateTime) -> &mut Self {
self.read_time = Some(time);
self
}
pub fn miss_time(&mut self, time: NaiveDateTime) -> &mut Self {
self.miss_time = Some(time);
self
}
pub fn write_time(&mut self, time: NaiveDateTime) -> &mut Self {
self.write_time = Some(time);
self
}
pub fn neglect_time(&mut self, time: NaiveDateTime) -> &mut Self {
self.neglect_time = Some(time);
self
}
pub fn humble_time(&mut self, time: NaiveDateTime) -> &mut Self {
self.humble_time = Some(time);
self
}
pub fn created_time(&mut self, time: NaiveDateTime) -> &mut Self {
self.created_time = Some(time);
self
}
pub fn build(self) -> ScriptInfo {
let created_time = ScriptTime::new_or(self.created_time, ScriptTime::now(()));
ScriptInfo {
write_time: ScriptTime::new_or(self.write_time, created_time),
read_time: ScriptTime::new_or(self.read_time, created_time),
miss_time: self.miss_time.map(ScriptTime::new),
exec_time: self.exec_time.map(ScriptTime::new),
exec_done_time: self.exec_done_time.map(ScriptTime::new),
neglect_time: self.neglect_time.map(ScriptTime::new),
humble_time: self.humble_time,
exec_count: self.exec_count,
timeless_info: TimelessScriptInfo {
changed: false,
id: self.id,
name: self.name,
ty: self.ty,
tags: self.tags,
created_time,
},
}
}sourcepub fn new_or(time: Option<NaiveDateTime>, default: Self) -> Self
pub fn new_or(time: Option<NaiveDateTime>, default: Self) -> Self
Examples found in repository?
444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
pub fn build(self) -> ScriptInfo {
let created_time = ScriptTime::new_or(self.created_time, ScriptTime::now(()));
ScriptInfo {
write_time: ScriptTime::new_or(self.write_time, created_time),
read_time: ScriptTime::new_or(self.read_time, created_time),
miss_time: self.miss_time.map(ScriptTime::new),
exec_time: self.exec_time.map(ScriptTime::new),
exec_done_time: self.exec_done_time.map(ScriptTime::new),
neglect_time: self.neglect_time.map(ScriptTime::new),
humble_time: self.humble_time,
exec_count: self.exec_count,
timeless_info: TimelessScriptInfo {
changed: false,
id: self.id,
name: self.name,
ty: self.ty,
tags: self.tags,
created_time,
},
}
}pub fn new(time: NaiveDateTime) -> Self
sourcepub fn data(&self) -> Option<&T>
pub fn data(&self) -> Option<&T>
Examples found in repository?
206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
pub async fn run_n_times(
repeat: u64,
dummy: bool,
entry: &mut RepoEntry<'_>,
mut args: Vec<String>,
res: &mut Vec<Error>,
use_previous: bool,
error_no_previous: bool,
dir: Option<PathBuf>,
) -> Result {
log::info!("執行 {:?}", entry.name);
super::hijack_ctrlc_once();
let mut env_vec = vec![];
if use_previous {
let dir = super::option_map_res(dir, |d| path::normalize_path(d))?;
let historian = &entry.get_env().historian;
match historian.previous_args(entry.id, dir.as_deref()).await? {
None if error_no_previous => {
return Err(Error::NoPreviousArgs);
}
None => log::warn!("無前一次參數,當作空的"),
Some((arg_str, envs_str)) => {
log::debug!("撈到前一次呼叫的參數 {}", arg_str);
let mut prev_arg_vec: Vec<String> =
serde_json::from_str(&arg_str).context(format!("反序列失敗 {}", arg_str))?;
env_vec =
serde_json::from_str(&envs_str).context(format!("反序列失敗 {}", envs_str))?;
prev_arg_vec.extend(args.into_iter());
args = prev_arg_vec;
}
}
}
let here = path::normalize_path(".").ok();
let script_path = path::open_script(&entry.name, &entry.ty, Some(true))?;
let content = super::read_file(&script_path)?;
let mut hs_env_desc = vec![];
for (need_save, line) in extract_env_from_content_help_aware(&content) {
hs_env_desc.push(line.to_owned());
if need_save {
EnvPair::process_line(line, &mut env_vec);
}
}
EnvPair::sort(&mut env_vec);
let env_record = serde_json::to_string(&env_vec)?;
let run_id = entry
.update(|info| info.exec(content, &args, env_record, here))
.await?;
if dummy {
log::info!("--dummy 不用真的執行,提早退出");
return Ok(());
}
// Start packing hs tmpl val
let hs_home = path::get_home();
let hs_tags: Vec<_> = entry.tags.iter().map(|t| t.as_ref()).collect();
let hs_cmd = std::env::args().next().unwrap_or_default();
let hs_exe = std::env::current_exe()?;
let hs_exe = hs_exe.to_string_lossy();
let content = &entry.exec_time.as_ref().unwrap().data().unwrap().0;
let hs_tmpl_val = json!({
"path": script_path,
"home": hs_home,
"run_id": run_id,
"tags": hs_tags,
"cmd": hs_cmd,
"exe": hs_exe,
"env_desc": hs_env_desc,
"name": &entry.name.key(),
"content": content,
});
// End packing hs tmpl val
for _ in 0..repeat {
let run_res = run(&script_path, &*entry, &args, &hs_tmpl_val, &env_vec);
let ret_code: i32;
match run_res {
Err(Error::ScriptError(code)) => {
ret_code = code;
res.push(run_res.unwrap_err());
}
Err(e) => return Err(e),
Ok(_) => ret_code = 0,
}
entry
.update(|info| info.exec_done(ret_code, run_id))
.await?;
}
Ok(())
}More examples
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
async fn handle_change(&self, info: &ScriptInfo) -> Result<i64> {
log::debug!("開始修改資料庫 {:?}", info);
if info.changed {
assert!(self.modifies_script);
let name = info.name.key();
let name = name.as_ref();
let tags = join_tags(info.tags.iter());
let ty = info.ty.as_ref();
sqlx::query!(
"UPDATE script_infos SET name = ?, tags = ?, ty = ? where id = ?",
name,
tags,
ty,
info.id,
)
.execute(&self.info_pool)
.await?;
}
if matches!(self.trace_opt, TraceOption::NoTrace) {
return Ok(0);
}
let mut last_event_id = 0;
macro_rules! record_event {
($time:expr, $data:expr) => {
self.historian.record(&Event {
script_id: info.id,
humble: matches!(self.trace_opt, TraceOption::Humble),
time: $time,
data: $data,
})
};
}
if let Some(time) = info.exec_done_time.as_ref() {
if let Some(&(code, main_event_id)) = time.data() {
log::debug!("{:?} 的執行完畢事件", info.name);
last_event_id = record_event!(
**time,
EventData::ExecDone {
code,
main_event_id,
}
)
.await?;
if last_event_id != 0 {
self.update_last_time(info).await?;
} else {
log::info!("{:?} 的執行完畢事件被忽略了", info.name);
}
return Ok(last_event_id); // XXX: 超級醜的作法,為了避免重復記錄其它的事件
}
}
self.update_last_time(info).await?;
if info.read_time.has_changed() {
log::debug!("{:?} 的讀取事件", info.name);
last_event_id = record_event!(*info.read_time, EventData::Read).await?;
}
if info.write_time.has_changed() {
log::debug!("{:?} 的寫入事件", info.name);
last_event_id = record_event!(*info.write_time, EventData::Write).await?;
}
if let Some(time) = info.miss_time.as_ref() {
if time.has_changed() {
log::debug!("{:?} 的錯過事件", info.name);
last_event_id = record_event!(**time, EventData::Miss).await?;
}
}
if let Some(time) = info.exec_time.as_ref() {
if let Some((content, args, envs, dir)) = time.data() {
log::debug!("{:?} 的執行事件", info.name);
last_event_id = record_event!(
**time,
EventData::Exec {
content,
args,
envs,
dir: dir.as_deref(),
}
)
.await?;
}
}
Ok(last_event_id)
}sourcepub fn has_changed(&self) -> bool
pub fn has_changed(&self) -> bool
Examples found in repository?
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
async fn handle_change(&self, info: &ScriptInfo) -> Result<i64> {
log::debug!("開始修改資料庫 {:?}", info);
if info.changed {
assert!(self.modifies_script);
let name = info.name.key();
let name = name.as_ref();
let tags = join_tags(info.tags.iter());
let ty = info.ty.as_ref();
sqlx::query!(
"UPDATE script_infos SET name = ?, tags = ?, ty = ? where id = ?",
name,
tags,
ty,
info.id,
)
.execute(&self.info_pool)
.await?;
}
if matches!(self.trace_opt, TraceOption::NoTrace) {
return Ok(0);
}
let mut last_event_id = 0;
macro_rules! record_event {
($time:expr, $data:expr) => {
self.historian.record(&Event {
script_id: info.id,
humble: matches!(self.trace_opt, TraceOption::Humble),
time: $time,
data: $data,
})
};
}
if let Some(time) = info.exec_done_time.as_ref() {
if let Some(&(code, main_event_id)) = time.data() {
log::debug!("{:?} 的執行完畢事件", info.name);
last_event_id = record_event!(
**time,
EventData::ExecDone {
code,
main_event_id,
}
)
.await?;
if last_event_id != 0 {
self.update_last_time(info).await?;
} else {
log::info!("{:?} 的執行完畢事件被忽略了", info.name);
}
return Ok(last_event_id); // XXX: 超級醜的作法,為了避免重復記錄其它的事件
}
}
self.update_last_time(info).await?;
if info.read_time.has_changed() {
log::debug!("{:?} 的讀取事件", info.name);
last_event_id = record_event!(*info.read_time, EventData::Read).await?;
}
if info.write_time.has_changed() {
log::debug!("{:?} 的寫入事件", info.name);
last_event_id = record_event!(*info.write_time, EventData::Write).await?;
}
if let Some(time) = info.miss_time.as_ref() {
if time.has_changed() {
log::debug!("{:?} 的錯過事件", info.name);
last_event_id = record_event!(**time, EventData::Miss).await?;
}
}
if let Some(time) = info.exec_time.as_ref() {
if let Some((content, args, envs, dir)) = time.data() {
log::debug!("{:?} 的執行事件", info.name);
last_event_id = record_event!(
**time,
EventData::Exec {
content,
args,
envs,
dir: dir.as_deref(),
}
)
.await?;
}
}
Ok(last_event_id)
}Methods from Deref<Target = NaiveDateTime>§
sourcepub fn date(&self) -> NaiveDate
pub fn date(&self) -> NaiveDate
Retrieves a date component.
Example
use chrono::NaiveDate;
let dt = NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_opt(9, 10, 11).unwrap();
assert_eq!(dt.date(), NaiveDate::from_ymd_opt(2016, 7, 8).unwrap());sourcepub fn time(&self) -> NaiveTime
pub fn time(&self) -> NaiveTime
Retrieves a time component.
Example
use chrono::{NaiveDate, NaiveTime};
let dt = NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_opt(9, 10, 11).unwrap();
assert_eq!(dt.time(), NaiveTime::from_hms_opt(9, 10, 11).unwrap());sourcepub fn timestamp(&self) -> i64
pub fn timestamp(&self) -> i64
Returns the number of non-leap seconds since the midnight on January 1, 1970.
Note that this does not account for the timezone! The true “UNIX timestamp” would count seconds since the midnight UTC on the epoch.
Example
use chrono::NaiveDate;
let dt = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap().and_hms_milli_opt(0, 0, 1, 980).unwrap();
assert_eq!(dt.timestamp(), 1);
let dt = NaiveDate::from_ymd_opt(2001, 9, 9).unwrap().and_hms_opt(1, 46, 40).unwrap();
assert_eq!(dt.timestamp(), 1_000_000_000);
let dt = NaiveDate::from_ymd_opt(1969, 12, 31).unwrap().and_hms_opt(23, 59, 59).unwrap();
assert_eq!(dt.timestamp(), -1);
let dt = NaiveDate::from_ymd_opt(-1, 1, 1).unwrap().and_hms_opt(0, 0, 0).unwrap();
assert_eq!(dt.timestamp(), -62198755200);sourcepub fn timestamp_millis(&self) -> i64
pub fn timestamp_millis(&self) -> i64
Returns the number of non-leap milliseconds since midnight on January 1, 1970.
Note that this does not account for the timezone! The true “UNIX timestamp” would count seconds since the midnight UTC on the epoch.
Note also that this does reduce the number of years that can be represented from ~584 Billion to ~584 Million. (If this is a problem, please file an issue to let me know what domain needs millisecond precision over billions of years, I’m curious.)
Example
use chrono::NaiveDate;
let dt = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap().and_hms_milli_opt(0, 0, 1, 444).unwrap();
assert_eq!(dt.timestamp_millis(), 1_444);
let dt = NaiveDate::from_ymd_opt(2001, 9, 9).unwrap().and_hms_milli_opt(1, 46, 40, 555).unwrap();
assert_eq!(dt.timestamp_millis(), 1_000_000_000_555);
let dt = NaiveDate::from_ymd_opt(1969, 12, 31).unwrap().and_hms_milli_opt(23, 59, 59, 100).unwrap();
assert_eq!(dt.timestamp_millis(), -900);sourcepub fn timestamp_micros(&self) -> i64
pub fn timestamp_micros(&self) -> i64
Returns the number of non-leap microseconds since midnight on January 1, 1970.
Note that this does not account for the timezone! The true “UNIX timestamp” would count seconds since the midnight UTC on the epoch.
Note also that this does reduce the number of years that can be represented from ~584 Billion to ~584 Thousand. (If this is a problem, please file an issue to let me know what domain needs microsecond precision over millennia, I’m curious.)
Example
use chrono::NaiveDate;
let dt = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap().and_hms_micro_opt(0, 0, 1, 444).unwrap();
assert_eq!(dt.timestamp_micros(), 1_000_444);
let dt = NaiveDate::from_ymd_opt(2001, 9, 9).unwrap().and_hms_micro_opt(1, 46, 40, 555).unwrap();
assert_eq!(dt.timestamp_micros(), 1_000_000_000_000_555);sourcepub fn timestamp_nanos(&self) -> i64
pub fn timestamp_nanos(&self) -> i64
Returns the number of non-leap nanoseconds since midnight on January 1, 1970.
Note that this does not account for the timezone! The true “UNIX timestamp” would count seconds since the midnight UTC on the epoch.
Panics
Note also that this does reduce the number of years that can be represented from ~584 Billion to ~584 years. The dates that can be represented as nanoseconds are between 1677-09-21T00:12:44.0 and 2262-04-11T23:47:16.854775804.
(If this is a problem, please file an issue to let me know what domain needs nanosecond precision over millennia, I’m curious.)
Example
use chrono::{NaiveDate, NaiveDateTime};
let dt = NaiveDate::from_ymd_opt(1970, 1, 1).unwrap().and_hms_nano_opt(0, 0, 1, 444).unwrap();
assert_eq!(dt.timestamp_nanos(), 1_000_000_444);
let dt = NaiveDate::from_ymd_opt(2001, 9, 9).unwrap().and_hms_nano_opt(1, 46, 40, 555).unwrap();
const A_BILLION: i64 = 1_000_000_000;
let nanos = dt.timestamp_nanos();
assert_eq!(nanos, 1_000_000_000_000_000_555);
assert_eq!(
dt,
NaiveDateTime::from_timestamp(nanos / A_BILLION, (nanos % A_BILLION) as u32)
);sourcepub fn timestamp_subsec_millis(&self) -> u32
pub fn timestamp_subsec_millis(&self) -> u32
Returns the number of milliseconds since the last whole non-leap second.
The return value ranges from 0 to 999, or for leap seconds, to 1,999.
Example
use chrono::NaiveDate;
let dt = NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_nano_opt(9, 10, 11, 123_456_789).unwrap();
assert_eq!(dt.timestamp_subsec_millis(), 123);
let dt = NaiveDate::from_ymd_opt(2015, 7, 1).unwrap().and_hms_nano_opt(8, 59, 59, 1_234_567_890).unwrap();
assert_eq!(dt.timestamp_subsec_millis(), 1_234);sourcepub fn timestamp_subsec_micros(&self) -> u32
pub fn timestamp_subsec_micros(&self) -> u32
Returns the number of microseconds since the last whole non-leap second.
The return value ranges from 0 to 999,999, or for leap seconds, to 1,999,999.
Example
use chrono::NaiveDate;
let dt = NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_nano_opt(9, 10, 11, 123_456_789).unwrap();
assert_eq!(dt.timestamp_subsec_micros(), 123_456);
let dt = NaiveDate::from_ymd_opt(2015, 7, 1).unwrap().and_hms_nano_opt(8, 59, 59, 1_234_567_890).unwrap();
assert_eq!(dt.timestamp_subsec_micros(), 1_234_567);sourcepub fn timestamp_subsec_nanos(&self) -> u32
pub fn timestamp_subsec_nanos(&self) -> u32
Returns the number of nanoseconds since the last whole non-leap second.
The return value ranges from 0 to 999,999,999, or for leap seconds, to 1,999,999,999.
Example
use chrono::NaiveDate;
let dt = NaiveDate::from_ymd_opt(2016, 7, 8).unwrap().and_hms_nano_opt(9, 10, 11, 123_456_789).unwrap();
assert_eq!(dt.timestamp_subsec_nanos(), 123_456_789);
let dt = NaiveDate::from_ymd_opt(2015, 7, 1).unwrap().and_hms_nano_opt(8, 59, 59, 1_234_567_890).unwrap();
assert_eq!(dt.timestamp_subsec_nanos(), 1_234_567_890);sourcepub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat<I>where
I: Iterator<Item = B> + Clone,
B: Borrow<Item<'a>>,
pub fn format_with_items<'a, I, B>(&self, items: I) -> DelayedFormat<I>where
I: Iterator<Item = B> + Clone,
B: Borrow<Item<'a>>,
Formats the combined date and time with the specified formatting items.
Otherwise it is the same as the ordinary format method.
The Iterator of items should be Cloneable,
since the resulting DelayedFormat value may be formatted multiple times.
Example
use chrono::NaiveDate;
use chrono::format::strftime::StrftimeItems;
let fmt = StrftimeItems::new("%Y-%m-%d %H:%M:%S");
let dt = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap().and_hms_opt(23, 56, 4).unwrap();
assert_eq!(dt.format_with_items(fmt.clone()).to_string(), "2015-09-05 23:56:04");
assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2015-09-05 23:56:04");The resulting DelayedFormat can be formatted directly via the Display trait.
assert_eq!(format!("{}", dt.format_with_items(fmt)), "2015-09-05 23:56:04");sourcepub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>>
pub fn format<'a>(&self, fmt: &'a str) -> DelayedFormat<StrftimeItems<'a>>
Formats the combined date and time with the specified format string.
See the format::strftime module
on the supported escape sequences.
This returns a DelayedFormat,
which gets converted to a string only when actual formatting happens.
You may use the to_string method to get a String,
or just feed it into print! and other formatting macros.
(In this way it avoids the redundant memory allocation.)
A wrong format string does not issue an error immediately.
Rather, converting or formatting the DelayedFormat fails.
You are recommended to immediately use DelayedFormat for this reason.
Example
use chrono::NaiveDate;
let dt = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap().and_hms_opt(23, 56, 4).unwrap();
assert_eq!(dt.format("%Y-%m-%d %H:%M:%S").to_string(), "2015-09-05 23:56:04");
assert_eq!(dt.format("around %l %p on %b %-d").to_string(), "around 11 PM on Sep 5");The resulting DelayedFormat can be formatted directly via the Display trait.
assert_eq!(format!("{}", dt.format("%Y-%m-%d %H:%M:%S")), "2015-09-05 23:56:04");
assert_eq!(format!("{}", dt.format("around %l %p on %b %-d")), "around 11 PM on Sep 5");sourcepub fn and_local_timezone<Tz>(&self, tz: Tz) -> LocalResult<DateTime<Tz>>where
Tz: TimeZone,
pub fn and_local_timezone<Tz>(&self, tz: Tz) -> LocalResult<DateTime<Tz>>where
Tz: TimeZone,
Converts the NaiveDateTime into the timezone-aware DateTime<Tz>
with the provided timezone, if possible.
This can fail in cases where the local time represented by the NaiveDateTime
is not a valid local timestamp in the target timezone due to an offset transition
for example if the target timezone had a change from +00:00 to +01:00
occuring at 2015-09-05 22:59:59, then a local time of 2015-09-05 23:56:04
could never occur. Similarly, if the offset transitioned in the opposite direction
then there would be two local times of 2015-09-05 23:56:04, one at +00:00 and one
at +01:00.
Example
use chrono::{NaiveDate, Utc};
let dt = NaiveDate::from_ymd_opt(2015, 9, 5).unwrap().and_hms_opt(23, 56, 4).unwrap().and_local_timezone(Utc).unwrap();
assert_eq!(dt.timezone(), Utc);pub const MIN: NaiveDateTime = Self{ date: NaiveDate::MIN, time: NaiveTime::MIN,}
pub const MAX: NaiveDateTime = Self{ date: NaiveDate::MAX, time: NaiveTime::MAX,}
Trait Implementations§
source§impl<T: Clone> Clone for ScriptTime<T>
impl<T: Clone> Clone for ScriptTime<T>
source§fn clone(&self) -> ScriptTime<T>
fn clone(&self) -> ScriptTime<T>
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moresource§impl<T: Debug> Debug for ScriptTime<T>
impl<T: Debug> Debug for ScriptTime<T>
source§impl<T> Deref for ScriptTime<T>
impl<T> Deref for ScriptTime<T>
source§impl<T> Ord for ScriptTime<T>
impl<T> Ord for ScriptTime<T>
source§impl<T> PartialEq<ScriptTime<T>> for ScriptTime<T>
impl<T> PartialEq<ScriptTime<T>> for ScriptTime<T>
source§impl<T> PartialOrd<ScriptTime<T>> for ScriptTime<T>
impl<T> PartialOrd<ScriptTime<T>> for ScriptTime<T>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self and other) and is used by the <=
operator. Read moreimpl<T: Copy> Copy for ScriptTime<T>
impl<T> Eq for ScriptTime<T>
Auto Trait Implementations§
impl<T> RefUnwindSafe for ScriptTime<T>where
T: RefUnwindSafe,
impl<T> Send for ScriptTime<T>where
T: Send,
impl<T> Sync for ScriptTime<T>where
T: Sync,
impl<T> Unpin for ScriptTime<T>where
T: Unpin,
impl<T> UnwindSafe for ScriptTime<T>where
T: UnwindSafe,
Blanket Implementations§
source§impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
impl<Q, K> Equivalent<K> for Qwhere
Q: Eq + ?Sized,
K: Borrow<Q> + ?Sized,
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.