1use crate::common::*;
4use crate::error::{Error, Result};
5use crate::format::{Formatter, LazyFormat, NaiveDateTime};
6use crate::local::Local;
7use crate::{Date, DateTime, IntervalDT, IntervalYM, Round, Time, Trunc};
8use std::cmp::Ordering;
9use std::convert::TryFrom;
10use std::fmt::Display;
11
12#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
16#[repr(transparent)]
17pub struct Timestamp(i64);
18
19impl Timestamp {
20 pub const MIN: Self = Timestamp::new(Date::MIN, Time::ZERO);
22
23 pub const MAX: Self = Timestamp::new(Date::MAX, Time::MAX);
25
26 #[inline]
28 pub const fn new(date: Date, time: Time) -> Self {
29 let usecs = date.days() as i64 * USECONDS_PER_DAY + time.usecs();
30 Timestamp(usecs)
31 }
32
33 #[inline]
35 pub const fn extract(self) -> (Date, Time) {
36 let (date, time) = if self.0.is_negative() {
37 let temp_time = self.0 % USECONDS_PER_DAY;
38 if temp_time.is_negative() {
39 (self.0 / USECONDS_PER_DAY - 1, temp_time + USECONDS_PER_DAY)
40 } else {
41 (self.0 / USECONDS_PER_DAY, temp_time)
42 }
43 } else {
44 (self.0 / USECONDS_PER_DAY, self.0 % USECONDS_PER_DAY)
45 };
46
47 unsafe {
48 (
49 Date::from_days_unchecked(date as i32),
50 Time::from_usecs_unchecked(time),
51 )
52 }
53 }
54
55 #[inline]
56 pub(crate) fn date(self) -> Date {
57 let date = if self.0.is_negative() && self.0 % USECONDS_PER_DAY != 0 {
58 self.0 / USECONDS_PER_DAY - 1
59 } else {
60 self.0 / USECONDS_PER_DAY
61 };
62 unsafe { Date::from_days_unchecked(date as i32) }
63 }
64
65 #[inline]
66 pub(crate) fn time(self) -> Time {
67 let temp_time = self.0 % USECONDS_PER_DAY;
68 if temp_time.is_negative() {
69 unsafe { Time::from_usecs_unchecked(temp_time + USECONDS_PER_DAY) }
70 } else {
71 unsafe { Time::from_usecs_unchecked(temp_time) }
72 }
73 }
74
75 #[inline(always)]
77 pub const fn usecs(self) -> i64 {
78 self.0
79 }
80
81 #[inline(always)]
87 pub const unsafe fn from_usecs_unchecked(usecs: i64) -> Self {
88 Timestamp(usecs)
89 }
90
91 #[inline]
93 pub fn format<S: AsRef<str>>(self, fmt: S) -> Result<impl Display> {
94 let fmt = Formatter::try_new(fmt)?;
95 Ok(LazyFormat::new(fmt, self))
96 }
97
98 #[inline]
100 pub fn parse<S1: AsRef<str>, S2: AsRef<str>>(input: S1, fmt: S2) -> Result<Self> {
101 let fmt = Formatter::try_new(fmt)?;
102 fmt.parse(input)
103 }
104
105 #[inline]
107 pub const fn try_from_usecs(usecs: i64) -> Result<Self> {
108 if is_valid_timestamp(usecs) {
109 Ok(unsafe { Timestamp::from_usecs_unchecked(usecs) })
110 } else {
111 Err(Error::DateOutOfRange)
112 }
113 }
114
115 #[inline]
117 pub const fn add_interval_dt(self, interval: IntervalDT) -> Result<Timestamp> {
118 let result = self.usecs().checked_add(interval.usecs());
119 match result {
120 Some(ts) => Timestamp::try_from_usecs(ts),
121 None => Err(Error::DateOutOfRange),
122 }
123 }
124
125 #[inline]
127 pub fn add_interval_ym(self, interval: IntervalYM) -> Result<Timestamp> {
128 let (date, time) = self.extract();
129
130 Ok(Timestamp::new(
131 date.add_interval_ym_internal(interval)?,
132 time,
133 ))
134 }
135
136 #[inline]
138 pub const fn add_time(self, time: Time) -> Result<Timestamp> {
139 Timestamp::try_from_usecs(self.usecs() + time.usecs())
140 }
141
142 #[inline]
144 pub fn add_days(self, days: f64) -> Result<Timestamp> {
145 let microseconds = (days * USECONDS_PER_DAY as f64).round();
146 if microseconds.is_infinite() {
147 Err(Error::NumericOverflow)
148 } else if microseconds.is_nan() {
149 Err(Error::InvalidNumber)
150 } else {
151 let result = self.usecs().checked_add(microseconds as i64);
152 match result {
153 Some(d) => Timestamp::try_from_usecs(d),
154 None => Err(Error::DateOutOfRange),
155 }
156 }
157 }
158
159 #[inline]
161 pub const fn sub_date(self, date: Date) -> IntervalDT {
162 let temp_timestamp = date.and_zero_time();
163 self.sub_timestamp(temp_timestamp)
164 }
165
166 #[inline]
168 pub const fn sub_time(self, time: Time) -> Result<Timestamp> {
169 Timestamp::try_from_usecs(self.usecs() - time.usecs())
170 }
171
172 #[inline]
174 pub const fn sub_timestamp(self, timestamp: Timestamp) -> IntervalDT {
175 let microseconds = self.usecs() - timestamp.usecs();
176 unsafe { IntervalDT::from_usecs_unchecked(microseconds) }
177 }
178
179 #[inline]
181 pub const fn sub_interval_dt(self, interval: IntervalDT) -> Result<Timestamp> {
182 self.add_interval_dt(interval.negate())
183 }
184
185 #[inline]
187 pub fn sub_interval_ym(self, interval: IntervalYM) -> Result<Timestamp> {
188 self.add_interval_ym(interval.negate())
189 }
190
191 #[inline]
193 pub fn sub_days(self, days: f64) -> Result<Timestamp> {
194 self.add_days(-days)
195 }
196
197 #[inline]
199 pub fn now() -> Result<Timestamp> {
200 let now = Local::now();
201 Ok(Timestamp::new(
202 Date::try_from_ymd(now.year(), now.month(), now.day())?,
203 Time::try_from_hms(now.hour(), now.minute(), now.second(), now.usec())?,
204 ))
205 }
206
207 #[inline]
209 pub fn last_day_of_month(self) -> Timestamp {
210 let (sqldate, _) = self.extract();
211 let (year, month, day) = sqldate.extract();
212
213 let result_day = days_of_month(year, month);
214 let result = self.usecs() + (result_day - day) as i64 * USECONDS_PER_DAY;
215
216 unsafe { Timestamp::from_usecs_unchecked(result) }
217 }
218}
219
220impl Trunc for Timestamp {
221 #[inline]
222 fn trunc_century(self) -> Result<Self> {
223 Ok(self.date().trunc_century()?.and_zero_time())
224 }
225
226 #[inline]
227 fn trunc_year(self) -> Result<Self> {
228 Ok(self.date().trunc_year()?.and_zero_time())
229 }
230
231 #[inline]
232 fn trunc_iso_year(self) -> Result<Self> {
233 Ok(self.date().trunc_iso_year()?.and_zero_time())
234 }
235
236 #[inline]
237 fn trunc_quarter(self) -> Result<Self> {
238 Ok(self.date().trunc_quarter()?.and_zero_time())
239 }
240
241 #[inline]
242 fn trunc_month(self) -> Result<Self> {
243 Ok(self.date().trunc_month()?.and_zero_time())
244 }
245
246 #[inline]
247 fn trunc_week(self) -> Result<Self> {
248 Ok(self.date().trunc_week()?.and_zero_time())
249 }
250
251 #[inline]
252 fn trunc_iso_week(self) -> Result<Self> {
253 Ok(self.date().trunc_iso_week()?.and_zero_time())
254 }
255
256 #[inline]
257 fn trunc_month_start_week(self) -> Result<Self> {
258 Ok(self.date().trunc_month_start_week()?.and_zero_time())
259 }
260
261 #[inline]
262 fn trunc_day(self) -> Result<Self> {
263 Ok(self.date().and_zero_time())
264 }
265
266 #[inline]
267 fn trunc_sunday_start_week(self) -> Result<Self> {
268 Ok(self.date().trunc_sunday_start_week()?.and_zero_time())
269 }
270
271 #[inline]
272 fn trunc_hour(self) -> Result<Self> {
273 Ok(self
274 .date()
275 .and_time(unsafe { Time::from_hms_unchecked(self.hour().unwrap() as u32, 0, 0, 0) }))
276 }
277
278 #[inline]
279 fn trunc_minute(self) -> Result<Self> {
280 let (hour, minute, _, _) = self.time().extract();
281 Ok(self
282 .date()
283 .and_time(unsafe { Time::from_hms_unchecked(hour, minute, 0, 0) }))
284 }
285}
286
287impl Round for Timestamp {
288 #[inline]
289 fn round_century(self) -> Result<Self> {
290 Ok(self.date().round_century()?.and_zero_time())
291 }
292
293 #[inline]
294 fn round_year(self) -> Result<Self> {
295 Ok(self.date().round_year()?.and_zero_time())
296 }
297
298 #[inline]
299 fn round_iso_year(self) -> Result<Self> {
300 Ok(self.date().round_iso_year()?.and_zero_time())
301 }
302
303 #[inline]
304 fn round_quarter(self) -> Result<Self> {
305 Ok(self.date().round_quarter()?.and_zero_time())
306 }
307
308 #[inline]
309 fn round_month(self) -> Result<Self> {
310 Ok(self.date().round_month()?.and_zero_time())
311 }
312
313 #[inline]
314 fn round_week(self) -> Result<Self> {
315 let (mut date, time) = self.extract();
316 if time.hour().unwrap() >= 12 {
317 date = date.add_days(1)?;
318 }
319 let year = date.extract().0;
320
321 Ok(date.round_week_internal(year)?.and_zero_time())
322 }
323
324 #[inline]
325 fn round_iso_week(self) -> Result<Self> {
326 let (mut date, time) = self.extract();
327 if time.hour().unwrap() >= 12 {
328 date = date.add_days(1)?;
329 }
330 Ok(date.round_iso_week()?.and_zero_time())
331 }
332
333 #[inline]
334 fn round_month_start_week(self) -> Result<Self> {
335 let (mut date, time) = self.extract();
336 if time.hour().unwrap() >= 12 {
337 date = date.add_days(1)?;
338 }
339 let day = date.extract().2;
340
341 Ok(date
342 .round_month_start_week_internal(day as i32)?
343 .and_zero_time())
344 }
345
346 #[inline]
347 fn round_day(self) -> Result<Self> {
348 let mut date = self.date();
349 if self.hour().unwrap() >= 12 {
350 date = date.add_days(1)?;
351 }
352 Ok(date.and_zero_time())
353 }
354
355 #[inline]
356 fn round_sunday_start_week(self) -> Result<Self> {
357 let (mut date, time) = self.extract();
358 if time.hour().unwrap() >= 12 {
359 date = date.add_days(1)?;
360 }
361 Ok(date.round_sunday_start_week()?.and_zero_time())
362 }
363
364 #[inline]
365 fn round_hour(self) -> Result<Self> {
366 let mut date = self.date();
367 let (mut hour, minute, _, _) = self.time().extract();
368 if minute >= 30 {
369 if hour >= 23 {
370 date = date.add_days(1)?;
371 hour = 0;
372 } else {
373 hour += 1
374 }
375 }
376 Ok(date.and_time(unsafe { Time::from_hms_unchecked(hour, 0, 0, 0) }))
377 }
378
379 #[inline]
380 fn round_minute(self) -> Result<Self> {
381 let mut date = self.date();
382 let (mut hour, mut minute, sec, _) = self.time().extract();
383 if sec >= 30 {
384 if minute == 59 {
385 if hour == 23 {
386 date = date.add_days(1)?;
387 hour = 0;
388 } else {
389 hour += 1;
390 }
391 minute = 0;
392 } else {
393 minute += 1;
394 }
395 }
396
397 Ok(date.and_time(unsafe { Time::from_hms_unchecked(hour, minute, 0, 0) }))
398 }
399}
400
401impl From<Timestamp> for NaiveDateTime {
402 #[inline]
403 fn from(ts: Timestamp) -> Self {
404 let (date, time) = ts.extract();
405 let (year, month, day) = date.extract();
406 let (hour, minute, sec, usec) = time.extract();
407
408 NaiveDateTime {
409 year,
410 month,
411 day,
412 hour,
413 minute,
414 sec,
415 usec,
416 ampm: None,
417 negative: false,
418 }
419 }
420}
421
422impl TryFrom<NaiveDateTime> for Timestamp {
423 type Error = Error;
424
425 #[inline]
426 fn try_from(dt: NaiveDateTime) -> Result<Self> {
427 Date::validate_ymd(dt.year, dt.month, dt.day)?;
428 Time::validate_hms(dt.hour, dt.minute, dt.sec)?;
429
430 let days = date2julian(dt.year, dt.month, dt.day) - UNIX_EPOCH_JULIAN;
431 let total_usec = days as i64 * USECONDS_PER_DAY
432 + dt.hour as i64 * USECONDS_PER_HOUR
433 + dt.minute as i64 * USECONDS_PER_MINUTE
434 + dt.sec as i64 * USECONDS_PER_SECOND
435 + dt.usec as i64;
436
437 Timestamp::try_from_usecs(total_usec)
438 }
439}
440
441impl PartialEq<Date> for Timestamp {
442 #[inline]
443 fn eq(&self, other: &Date) -> bool {
444 *self == other.and_zero_time()
445 }
446}
447
448impl PartialOrd<Date> for Timestamp {
449 #[inline]
450 fn partial_cmp(&self, other: &Date) -> Option<Ordering> {
451 Some(self.usecs().cmp(&other.and_zero_time().usecs()))
452 }
453}
454
455impl From<Date> for Timestamp {
456 #[inline]
457 fn from(date: Date) -> Self {
458 date.and_zero_time()
459 }
460}
461
462impl TryFrom<Time> for Timestamp {
463 type Error = Error;
464
465 #[inline]
466 fn try_from(time: Time) -> Result<Self> {
467 let now = Local::now();
468 Ok(Timestamp::new(
469 Date::try_from_ymd(now.year(), now.month(), now.day())?,
470 time,
471 ))
472 }
473}
474
475impl DateTime for Timestamp {
476 #[inline]
477 fn year(&self) -> Option<i32> {
478 Timestamp::date(*self).year()
479 }
480
481 #[inline]
482 fn month(&self) -> Option<i32> {
483 Timestamp::date(*self).month()
484 }
485
486 #[inline]
487 fn day(&self) -> Option<i32> {
488 Timestamp::date(*self).day()
489 }
490
491 #[inline]
492 fn hour(&self) -> Option<i32> {
493 self.time().hour()
494 }
495
496 #[inline]
497 fn minute(&self) -> Option<i32> {
498 self.time().minute()
499 }
500
501 #[inline]
502 fn second(&self) -> Option<f64> {
503 self.time().second()
504 }
505
506 #[inline]
507 fn date(&self) -> Option<Date> {
508 Some(Timestamp::date(*self))
509 }
510}
511
512#[cfg(test)]
513mod tests {
514 use super::*;
515 use crate::common::DATE_MAX_YEAR;
516
517 fn generate_ts(
518 year: i32,
519 month: u32,
520 day: u32,
521 hour: u32,
522 min: u32,
523 sec: u32,
524 usec: u32,
525 ) -> Timestamp {
526 Timestamp::new(
527 Date::try_from_ymd(year, month, day).unwrap(),
528 Time::try_from_hms(hour, min, sec, usec).unwrap(),
529 )
530 }
531
532 fn generate_date(year: i32, month: u32, day: u32) -> Date {
533 Date::try_from_ymd(year, month, day).unwrap()
534 }
535
536 fn generate_time(hour: u32, min: u32, sec: u32, usec: u32) -> Time {
537 Time::try_from_hms(hour, min, sec, usec).unwrap()
538 }
539
540 #[test]
541 fn test_timestamp() {
542 {
543 let date = Date::try_from_ymd(1970, 1, 1).unwrap();
544 let time = Time::try_from_hms(0, 0, 0, 0).unwrap();
545 let ts = Timestamp::new(date, time);
546 assert_eq!(ts.usecs(), 0);
547
548 let (date, time) = ts.extract();
549 assert_eq!(date.extract(), (1970, 1, 1));
550 assert_eq!(time.extract(), (0, 0, 0, 0));
551
552 let ts = generate_ts(1, 1, 1, 0, 0, 0, 0);
553 let (date, time) = ts.extract();
554 assert_eq!(date.extract(), (1, 1, 1));
555 assert_eq!(time.extract(), (0, 0, 0, 0));
556
557 let ts = generate_ts(1, 1, 1, 23, 59, 59, 999999);
558 let (date, time) = ts.extract();
559 assert_eq!(date.extract(), (1, 1, 1));
560 assert_eq!(time.extract(), (23, 59, 59, 999999));
561
562 let ts = generate_ts(1, 12, 31, 0, 0, 0, 0);
563 let (date, time) = ts.extract();
564 assert_eq!(date.extract(), (1, 12, 31));
565 assert_eq!(time.extract(), (0, 0, 0, 0));
566
567 let ts = generate_ts(1, 12, 31, 23, 59, 59, 999999);
568 let (date, time) = ts.extract();
569 assert_eq!(date.extract(), (1, 12, 31));
570 assert_eq!(time.extract(), (23, 59, 59, 999999));
571
572 let ts = generate_ts(1969, 12, 30, 0, 0, 0, 0);
573 let (date, time) = ts.extract();
574 assert_eq!(date.extract(), (1969, 12, 30));
575 assert_eq!(time.extract(), (0, 0, 0, 0));
576
577 let ts = generate_ts(1969, 12, 30, 23, 59, 59, 999999);
578 let (date, time) = ts.extract();
579 assert_eq!(date.extract(), (1969, 12, 30));
580 assert_eq!(time.extract(), (23, 59, 59, 999999));
581
582 let ts = generate_ts(1969, 12, 31, 0, 0, 0, 0);
583 let (date, time) = ts.extract();
584 assert_eq!(date.extract(), (1969, 12, 31));
585 assert_eq!(time.extract(), (0, 0, 0, 0));
586
587 let ts = generate_ts(1969, 12, 31, 23, 59, 59, 999999);
588 let (date, time) = ts.extract();
589 assert_eq!(date.extract(), (1969, 12, 31));
590 assert_eq!(time.extract(), (23, 59, 59, 999999));
591
592 let ts = generate_ts(1970, 1, 1, 0, 0, 0, 0);
593 let (date, time) = ts.extract();
594 assert_eq!(date.extract(), (1970, 1, 1));
595 assert_eq!(time.extract(), (0, 0, 0, 0));
596
597 let ts = generate_ts(1970, 1, 1, 23, 59, 59, 999999);
598 let (date, time) = ts.extract();
599 assert_eq!(date.extract(), (1970, 1, 1));
600 assert_eq!(time.extract(), (23, 59, 59, 999999));
601
602 let ts = generate_ts(1970, 3, 4, 23, 12, 30, 123456);
603 let (date, time) = ts.extract();
604 assert_eq!(date.extract(), (1970, 3, 4));
605 assert_eq!(time.extract(), (23, 12, 30, 123456));
606
607 let ts = generate_ts(9999, 12, 31, 0, 0, 0, 0);
608 let (date, time) = ts.extract();
609 assert_eq!(date.extract(), (9999, 12, 31));
610 assert_eq!(time.extract(), (0, 0, 0, 0));
611
612 let ts = generate_ts(9999, 12, 31, 23, 59, 59, 999999);
613 let (date, time) = ts.extract();
614 assert_eq!(date.extract(), (9999, 12, 31));
615 assert_eq!(time.extract(), (23, 59, 59, 999999));
616
617 let ts = generate_ts(1969, 10, 31, 1, 1, 1, 1);
618 let (date, time) = ts.extract();
619 assert_eq!(date.extract(), (1969, 10, 31));
620 assert_eq!(time.extract(), (1, 1, 1, 1));
621
622 {
624 assert_eq!(
627 Timestamp::new(
628 Date::try_from_ymd(2022, 10, 24).unwrap(),
629 Time::try_from_hms(0, 0, 0, 0).unwrap(),
630 ),
631 Timestamp::parse("2022-10-23 23:59:59.9999999", "yyyy-mm-dd hh24:mi:ss.ff")
632 .unwrap()
633 );
634 assert_eq!(
636 Timestamp::new(
637 Date::try_from_ymd(2022, 11, 1).unwrap(),
638 Time::try_from_hms(0, 0, 0, 0).unwrap(),
639 ),
640 Timestamp::parse("2022-10-31 23:59:59.9999999", "yyyy-mm-dd hh24:mi:ss.ff")
641 .unwrap()
642 );
643 assert_eq!(
645 Timestamp::new(
646 Date::try_from_ymd(2023, 1, 1).unwrap(),
647 Time::try_from_hms(0, 0, 0, 0).unwrap(),
648 ),
649 Timestamp::parse("2022-12-31 23:59:59.9999999", "yyyy-mm-dd hh24:mi:ss.ff")
650 .unwrap()
651 );
652
653 assert_eq!(
655 Timestamp::new(
656 Date::try_from_ymd(2022, 6, 18).unwrap(),
657 Time::try_from_hms(3, 4, 5, 6).unwrap(),
658 ),
659 Timestamp::parse("2022-06-18 03:04:05.000006", "yyyy-mm-dd hh24:mi:ss.ff")
660 .unwrap()
661 );
662 assert_eq!(
663 Timestamp::MAX,
664 Timestamp::parse("9999-12-31 23:59:59.999999", "yyyy-mm-dd hh24:mi:ss.ff")
665 .unwrap()
666 );
667 assert_eq!(
668 Timestamp::MAX,
669 Timestamp::parse("9999-12-31 23:59:59.9999991", "yyyy-mm-dd hh24:mi:ss.ff")
670 .unwrap()
671 );
672 assert_eq!(
673 Timestamp::MAX,
674 Timestamp::parse("9999-12-31 23:59:59.999999119", "yyyy-mm-dd hh24:mi:ss.ff")
675 .unwrap()
676 );
677 assert_eq!(
678 Timestamp::MAX,
679 Timestamp::parse("9999-12-31 23:59:59.9999994", "yyyy-mm-dd hh24:mi:ss.ff")
680 .unwrap()
681 );
682
683 assert!(Timestamp::parse(
686 "10000-12-31 23:59:59.999999",
687 "yyyy-mm-dd hh24:mi:ss.ff"
688 )
689 .is_err());
690 assert!(Timestamp::parse(
691 "20000-12-31 23:59:59.999999",
692 "yyyy-mm-dd hh24:mi:ss.ff"
693 )
694 .is_err());
695 assert_eq!(
697 Err(Error::InvalidMonth),
698 Timestamp::parse("9999-13-31 24:60:59.999999", "yyyy-mm-dd hh24:mi:ss.ff")
699 );
700 assert_eq!(
701 Err(Error::InvalidMonth),
702 Timestamp::parse("9999-20-31 24:60:59.999999", "yyyy-mm-dd hh24:mi:ss.ff")
703 );
704 assert_eq!(
706 Err(Error::InvalidDay),
707 Timestamp::parse("9999-12-32 24:59:60.999999", "yyyy-mm-dd hh24:mi:ss.ff")
708 );
709 assert_eq!(
710 Err(Error::InvalidDay),
711 Timestamp::parse("9999-12-40 24:59:60.999999", "yyyy-mm-dd hh24:mi:ss.ff")
712 );
713 assert_eq!(
715 Err(Error::TimeOutOfRange),
716 Timestamp::parse("9999-12-31 24:59:59.999999", "yyyy-mm-dd hh24:mi:ss.ff")
717 );
718 assert_eq!(
719 Err(Error::TimeOutOfRange),
720 Timestamp::parse("9999-12-31 25:59:59.999999", "yyyy-mm-dd hh24:mi:ss.ff")
721 );
722 assert_eq!(
724 Err(Error::InvalidMinute),
725 Timestamp::parse("9999-12-31 23:60:59.999999", "yyyy-mm-dd hh24:mi:ss.ff")
726 );
727 assert_eq!(
729 Err(Error::InvalidSecond),
730 Timestamp::parse("9999-12-31 23:59:60.999999", "yyyy-mm-dd hh24:mi:ss.ff")
731 );
732 assert_eq!(
734 Err(Error::DateOutOfRange),
735 Timestamp::parse("9999-12-31 23:59:59.9999995", "yyyy-mm-dd hh24:mi:ss.ff")
736 );
737 assert_eq!(
738 Err(Error::DateOutOfRange),
739 Timestamp::parse("9999-12-31 23:59:59.99999999", "yyyy-mm-dd hh24:mi:ss.ff")
740 );
741 }
742
743 {
745 let time = Time::try_from_hms(23, 59, 59, 999999).unwrap();
747 let ts = Date::try_from_ymd(9999, 12, 31).unwrap().and_time(time);
748 let ts2 = Timestamp::parse(
749 "PM 9999\\12-31 11/59:59.999999",
750 "AM yyyy\\mm-dd hh/mi:ss.ff",
751 )
752 .unwrap();
753 assert_eq!(ts2, ts);
754
755 let ts2 =
756 Timestamp::parse("PM 11-9999-59.999999 12-59-31", "PM HH-YYYY-MI.FF MM-SS-DD")
757 .unwrap();
758 assert_eq!(ts2, ts);
759 assert!(Timestamp::parse(
760 "P.M. 11-9999-59.999999 12-59-31",
761 "PM HH-YYYY-MI.FF MM-SS-DD"
762 )
763 .is_err());
764
765 let ts2 =
766 Timestamp::parse("23-9999-59.999999 12 59 31", "HH24-YYYY-MI.FF MM SS DD")
767 .unwrap();
768 assert_eq!(ts, ts2);
769
770 let ts2 = Timestamp::parse(
771 "T23--59.999999 12 59 31.9999;",
772 "THH24--MI.FF MM SS DD.yyyy;",
773 )
774 .unwrap();
775 assert_eq!(ts, ts2);
776
777 let fmt = ts.format("TAM HH\\YYYY\\MI.FF MM-SS/DD").unwrap();
779 assert_eq!(format!("{}", fmt), "TPM 11\\9999\\59.999999 12-59/31");
780
781 let fmt = ts.format("HH\\YYYY\\MI MM-SS/DD.FF4;").unwrap();
782 assert_eq!(format!("{}", fmt), "11\\9999\\59 12-59/31.9999;");
783 }
784
785 {
787 assert!(Timestamp::parse(
789 "AM PM 9999\\12-31 11/59:59.999999",
790 "AM PM yyyy\\mm-dd hh/mi:ss.ff"
791 )
792 .is_err());
793
794 assert!(Timestamp::parse(
795 "pm PM 9999\\12-31 11/59:59.999999",
796 "AM PM yyyy\\mm-dd hh/mi:ss.ff"
797 )
798 .is_err());
799
800 assert!(Timestamp::parse(
801 "9999 9999\\12-31 11/59:59.999999",
802 "yyyy yyyy\\mm-dd hh/mi:ss.ff"
803 )
804 .is_err());
805
806 assert!(Timestamp::parse(
807 "9999\\12-31 11/59:59.999999 59",
808 "yyyy\\mm-dd hh/mi:ss.ff mi"
809 )
810 .is_err());
811
812 assert_eq!(
813 Timestamp::parse("23:60:00", "hh24:mi:ss").err().unwrap(),
814 Error::InvalidMinute
815 );
816
817 assert_eq!(
818 Timestamp::parse("23:00:60", "hh24:mi:ss").err().unwrap(),
819 Error::InvalidSecond
820 );
821
822 assert!(Timestamp::parse(
823 "2021-04-25 03:04:05.000006 thu 5",
824 "yyyy-mm-dd hh24:mi:ss.FF6 dy d",
825 )
826 .is_err());
827
828 }
830
831 {
833 let now = Local::now();
834 let year = now.year();
835 let month = now.month();
836
837 let timestamp = generate_ts(year, month, 1, 0, 0, 5, 0);
838 let ts = Timestamp::parse("5", "ss").unwrap();
839 assert_eq!(timestamp, ts);
840
841 let timestamp = generate_ts(year, month, 1, 0, 0, 0, 0);
842 let ts = Timestamp::parse("", "").unwrap();
843 assert_eq!(timestamp, ts);
844
845 let timestamp = generate_ts(year, 1, 1, 0, 0, 0, 0);
846 let ts = Timestamp::parse("jan", "mm").unwrap();
847 assert_eq!(timestamp, ts);
848
849 let ts = Timestamp::parse("January", "mm").unwrap();
850 assert_eq!(timestamp, ts);
851
852 let ts = Timestamp::parse("JANUARY", "mm").unwrap();
853 assert_eq!(timestamp, ts);
854
855 let ts = Timestamp::parse("jan", "MONTH").unwrap();
856 assert_eq!(timestamp, ts);
857
858 let ts = Timestamp::parse("January", "mon").unwrap();
859 assert_eq!(timestamp, ts);
860
861 let timestamp = generate_ts(year - year % 10, month, 1, 0, 0, 0, 0);
862 let ts = Timestamp::parse("0", "y").unwrap();
863 assert_eq!(timestamp, ts);
864
865 let timestamp = generate_ts(year - year % 10 + 2, month, 1, 0, 0, 0, 0);
866 let ts = Timestamp::parse("2", "y").unwrap();
867 assert_eq!(timestamp, ts);
868
869 let timestamp = generate_ts(year - year % 100, month, 1, 0, 0, 0, 0);
870 let ts = Timestamp::parse("0", "yy").unwrap();
871 assert_eq!(timestamp, ts);
872
873 let timestamp = generate_ts(year - year % 100 + 1, month, 1, 0, 0, 0, 0);
874 let ts = Timestamp::parse("1", "yy").unwrap();
875 assert_eq!(timestamp, ts);
876
877 let timestamp = generate_ts(year - year % 100 + 12, month, 1, 0, 0, 0, 0);
878 let ts = Timestamp::parse("12", "yy").unwrap();
879 assert_eq!(timestamp, ts);
880
881 let timestamp = generate_ts(123, month, 1, 0, 0, 0, 0);
882 let ts = Timestamp::parse("123", "yy").unwrap();
883 assert_eq!(timestamp, ts);
884
885 let timestamp = generate_ts(1234, month, 1, 0, 0, 0, 0);
886 let ts = Timestamp::parse("1234", "yy").unwrap();
887 assert_eq!(timestamp, ts);
888
889 let timestamp = generate_ts(year - year % 1000 + 1, month, 1, 0, 0, 0, 0);
890 let ts = Timestamp::parse("1", "yyy").unwrap();
891 assert_eq!(timestamp, ts);
892
893 let timestamp = generate_ts(year - year % 1000 + 12, month, 1, 0, 0, 0, 0);
894 let ts = Timestamp::parse("12", "yyy").unwrap();
895 assert_eq!(timestamp, ts);
896
897 let timestamp = generate_ts(year - year % 1000 + 12, month, 1, 0, 0, 0, 0);
898 let ts = Timestamp::parse("012", "yyy").unwrap();
899 assert_eq!(timestamp, ts);
900
901 let timestamp = generate_ts(year - year % 1000 + 123, month, 1, 0, 0, 0, 0);
902 let ts = Timestamp::parse("123", "yyy").unwrap();
903 assert_eq!(timestamp, ts);
904
905 let timestamp = generate_ts(2, month, 1, 0, 0, 0, 0);
906 let ts = Timestamp::parse("2", "yyyy").unwrap();
907 assert_eq!(timestamp, ts);
908
909 let timestamp = generate_ts(1234, month, 1, 0, 0, 0, 0);
910 let ts = Timestamp::parse("1234", "yyyy").unwrap();
911 assert_eq!(timestamp, ts);
912 }
913
914 {
916 let timestamp =
917 Timestamp::parse("+2020-+11-+12 +11:+12:+13", "YYYY-MM-DD HH24:mi:ss").unwrap();
918 assert_eq!(timestamp, generate_ts(2020, 11, 12, 11, 12, 13, 0));
919 }
920
921 {
923 let timestamp = Timestamp::parse("2020-11-12", "YYYY-MM-DD HH24:MI:SS").unwrap();
924 assert_eq!(timestamp, generate_ts(2020, 11, 12, 0, 0, 0, 0));
925
926 let timestamp = Timestamp::parse("2020-11-12", "YYYY-MM-DD HH24-MI-SS").unwrap();
927 assert_eq!(timestamp, generate_ts(2020, 11, 12, 0, 0, 0, 0));
928
929 let timestamp = Timestamp::parse("2020-11-12 11", "YYYY-MM-DD HH24:MI:SS").unwrap();
930 assert_eq!(timestamp, generate_ts(2020, 11, 12, 11, 0, 0, 0));
931
932 let timestamp =
933 Timestamp::parse("2020-11-12 11:23", "YYYY-MM-DD HH24:MI:SS").unwrap();
934 assert_eq!(timestamp, generate_ts(2020, 11, 12, 11, 23, 0, 0));
935
936 let timestamp =
937 Timestamp::parse("2020-11-12 11:23:25", "YYYY-MM-DD HH24:MI:SS.ff").unwrap();
938 assert_eq!(timestamp, generate_ts(2020, 11, 12, 11, 23, 25, 0));
939
940 let timestamp =
941 Timestamp::parse("2021-12-15", "YYYY-MM-DD HH:MI:SS.ff AM").unwrap();
942 assert_eq!(timestamp, generate_ts(2021, 12, 15, 0, 0, 0, 0));
943
944 assert!(Timestamp::parse("2021-12-15 0", "YYYY-MM-DD HH").is_err());
945 assert!(Timestamp::parse("2021-12-15 0", "YYYY-MM-DD HH12").is_err());
946 assert!(Timestamp::parse("2021-12-15 0", "YYYY-MM-DD HH:MI:SS.ff AM").is_err());
947
948 let timestamp =
949 Timestamp::parse("2021-12-15 11", "YYYY-MM-DD HH:MI:SS.ff AM").unwrap();
950 assert_eq!(timestamp, generate_ts(2021, 12, 15, 11, 0, 0, 0));
951
952 let timestamp =
953 Timestamp::parse("2021-12-15 11:23", "YYYY-MM-DD HH:MI:SS.ff AM").unwrap();
954 assert_eq!(timestamp, generate_ts(2021, 12, 15, 11, 23, 0, 0));
955
956 let timestamp =
957 Timestamp::parse("2021-12-15 11:23:25", "YYYY-MM-DD HH:MI:SS.ff AM").unwrap();
958 assert_eq!(timestamp, generate_ts(2021, 12, 15, 11, 23, 25, 0));
959
960 let timestamp =
961 Timestamp::parse("2020-11-12 11:23:25.123456", "YYYY-MM-DD HH:MI:SS.ff AM")
962 .unwrap();
963 assert_eq!(timestamp, generate_ts(2020, 11, 12, 11, 23, 25, 123456));
964
965 let timestamp =
966 Timestamp::parse("2020-11-12 11:23:25.123", "YYYY-MM-DD HH:MI:SS.ff A.M.")
967 .unwrap();
968 assert_eq!(timestamp, generate_ts(2020, 11, 12, 11, 23, 25, 123000));
969
970 let timestamp =
971 Timestamp::parse("2020-11-12 11:23:25.123", "YYYY-MM-DD HH:MI:SS.ff PM")
972 .unwrap();
973 assert_eq!(timestamp, generate_ts(2020, 11, 12, 11, 23, 25, 123000));
974
975 let timestamp =
976 Timestamp::parse("2020-11-12 11:23:25 ", "YYYY-MM-DD HH:MI:SS.ff PM")
977 .unwrap();
978 assert_eq!(timestamp, generate_ts(2020, 11, 12, 11, 23, 25, 0));
979 }
980
981 {
983 assert!(Timestamp::parse("2022-4", "YYYY-MM-DD HH24:MI:SS.FF").is_err());
984 }
985
986 {
988 let ts = generate_ts(1234, 8, 6, 7, 8, 9, 10);
989 assert_eq!(format!("{}", ts.format("YYYY").unwrap()), "1234");
990 assert_eq!(format!("{}", ts.format("DD").unwrap()), "06");
991 assert_eq!(format!("{}", ts.format("MON").unwrap()), "AUG");
992 assert_eq!(format!("{}", ts.format("Mon").unwrap()), "Aug");
993 assert_eq!(format!("{}", ts.format("mon").unwrap()), "aug");
994 assert_eq!(format!("{}", ts.format("MONTH").unwrap()), "AUGUST");
995 assert_eq!(format!("{}", ts.format("MONtH").unwrap()), "AUGUST");
996 assert_eq!(format!("{}", ts.format("Month").unwrap()), "August");
997 assert_eq!(format!("{}", ts.format("month").unwrap()), "august");
998 assert_eq!(format!("{}", ts.format("WW").unwrap()), "32");
999 assert_eq!(format!("{}", ts.format("W").unwrap()), "1");
1000 assert_eq!(format!("{}", ts.format("DAY").unwrap()), "SUNDAY");
1001 assert_eq!(format!("{}", ts.format("DAy").unwrap()), "SUNDAY");
1002 assert_eq!(format!("{}", ts.format("Day").unwrap()), "Sunday");
1003 assert_eq!(format!("{}", ts.format("DaY").unwrap()), "Sunday");
1004 assert_eq!(format!("{}", ts.format("day").unwrap()), "sunday");
1005 assert_eq!(format!("{}", ts.format("daY").unwrap()), "sunday");
1006 assert_eq!(format!("{}", ts.format("DY").unwrap()), "SUN");
1007 assert_eq!(format!("{}", ts.format("Dy").unwrap()), "Sun");
1008 assert_eq!(format!("{}", ts.format("dy").unwrap()), "sun");
1009 assert_eq!(format!("{}", ts.format("D").unwrap()), "1");
1010 assert_eq!(format!("{}", ts.format("DDD").unwrap()), "218");
1011 assert_eq!(format!("{}", ts.format("mi").unwrap()), "08");
1012 assert_eq!(format!("{}", ts.format("hh").unwrap()), "07");
1013 assert_eq!(format!("{}", ts.format("ss").unwrap()), "09");
1014 assert_eq!(format!("{}", ts.format("FF").unwrap()), "000010");
1015 assert_eq!(format!("{}", ts.format("y").unwrap()), "4");
1016 assert_eq!(format!("{}", ts.format("yy").unwrap()), "34");
1017 assert_eq!(format!("{}", ts.format("yyy").unwrap()), "234");
1018
1019 assert!(Timestamp::parse("1234", "yyy").is_err());
1020 assert!(Timestamp::parse("1234", "y").is_err());
1021 assert!(Timestamp::parse("123", "y").is_err());
1022 assert!(Timestamp::parse("12", "y").is_err());
1023
1024 assert!(Timestamp::parse("-12", "yyyy").is_err());
1025 assert!(Timestamp::parse("-12", "mm").is_err());
1026 assert!(Timestamp::parse("-12", "dd").is_err());
1027 assert!(Timestamp::parse("-12", "hh24").is_err());
1028 assert!(Timestamp::parse("-1", "hh12").is_err());
1029 assert!(Timestamp::parse("-123456", "ff").is_err());
1030 assert!(Timestamp::parse("-12", "yyyy").is_err());
1031 assert!(Timestamp::parse("-12", "mi").is_err());
1032 assert!(Timestamp::parse("-12", "ss").is_err());
1033
1034 let ts = generate_ts(1970, 1, 1, 7, 8, 9, 10);
1035 assert_eq!(format!("{}", ts.format("day").unwrap()), "thursday");
1036 assert_eq!(format!("{}", ts.format("d").unwrap()), "5");
1037 assert_eq!(format!("{}", ts.format("ddd").unwrap()), "001");
1038 assert_eq!(format!("{}", ts.format("ww").unwrap()), "01");
1039 assert_eq!(format!("{}", ts.format("w").unwrap()), "1");
1040
1041 let ts = generate_ts(1970, 1, 2, 7, 8, 9, 10);
1042 assert_eq!(format!("{}", ts.format("day").unwrap()), "friday");
1043
1044 let ts = generate_ts(1969, 12, 31, 7, 8, 9, 10);
1045 assert_eq!(format!("{}", ts.format("day").unwrap()), "wednesday");
1046 assert_eq!(format!("{}", ts.format("d").unwrap()), "4");
1047 assert_eq!(format!("{}", ts.format("ddd").unwrap()), "365");
1048 assert_eq!(format!("{}", ts.format("ww").unwrap()), "53");
1049 assert_eq!(format!("{}", ts.format("w").unwrap()), "5");
1050
1051 let ts = generate_ts(1969, 10, 1, 7, 8, 9, 10);
1052 assert_eq!(format!("{}", ts.format("day").unwrap()), "wednesday");
1053
1054 let ts = generate_ts(9999, 11, 14, 7, 8, 9, 10);
1055 assert_eq!(format!("{}", ts.format("day").unwrap()), "sunday");
1056 }
1057
1058 {
1060 let ts = generate_ts(2000, 1, 1, 0, 0, 0, 0);
1061 let fmt = format!("{}", ts.format("yyyy-MONTH-dd hh:mi:ss.ff1").unwrap());
1062 assert_eq!(fmt, "2000-JANUARY-01 12:00:00.0");
1063
1064 let fmt = format!("{}", ts.format("yyyy-Mon-dd hh:mi:ss.ff1").unwrap());
1065 assert_eq!(fmt, "2000-Jan-01 12:00:00.0");
1066
1067 let fmt = format!("{}", ts.format("Day yyyy-Mon-dd hh:mi:ss.ff1").unwrap());
1068 assert_eq!(fmt, "Saturday 2000-Jan-01 12:00:00.0");
1069
1070 let fmt = format!("{}", ts.format("yyyyMMdd hh24miss.ff1").unwrap());
1071 assert_eq!(fmt, "20000101 000000.0");
1072
1073 let ts = generate_ts(2001, 1, 2, 3, 4, 5, 6);
1074 assert_eq!(
1075 format!("{}", ts.format("YYYYMMDDHHMISSFF").unwrap()),
1076 "20010102030405000006"
1077 );
1078
1079 assert_eq!(
1080 ts,
1081 Timestamp::parse("20010102030405000006", "YYYYMMDDHHMISSFF").unwrap()
1082 );
1083
1084 assert_eq!(
1085 ts,
1086 Timestamp::parse("2001012 030405000006", "YYYYMMDD HHMISSFF").unwrap()
1087 );
1088 }
1089
1090 {
1092 let now = Local::now();
1093 let year = now.year();
1094 let month = now.month();
1095
1096 assert_eq!(
1097 Timestamp::parse(".12345", ".ff").unwrap(),
1098 generate_ts(year, month, 1, 0, 0, 0, 123450)
1099 );
1100 assert_eq!(
1101 Timestamp::parse(".123456789", ".ff").unwrap(),
1102 generate_ts(year, month, 1, 0, 0, 0, 123457)
1103 );
1104 assert_eq!(
1105 Timestamp::parse(".12345678", ".ff").unwrap(),
1106 generate_ts(year, month, 1, 0, 0, 0, 123457)
1107 );
1108 assert_eq!(
1109 Timestamp::parse(".1234567", ".ff7").unwrap(),
1110 generate_ts(year, month, 1, 0, 0, 0, 123457)
1111 );
1112 assert!(Timestamp::parse(".12345678", ".ff7").is_err());
1113 assert_eq!(
1114 Timestamp::parse(".123456", ".ff6").unwrap(),
1115 generate_ts(year, month, 1, 0, 0, 0, 123456)
1116 );
1117 assert!(Timestamp::parse(".123456789", ".ff2").is_err());
1118
1119 let timestamp = generate_ts(1, 2, 3, 4, 5, 6, 123456);
1120 assert_eq!(format!("{}", timestamp.format("ff6").unwrap()), "123456");
1121 assert_eq!(format!("{}", timestamp.format("ff").unwrap()), "123456");
1122 assert_eq!(format!("{}", timestamp.format("ff9").unwrap()), "123456000");
1123 assert_eq!(format!("{}", timestamp.format("ff5").unwrap()), "12345");
1124 }
1125
1126 {
1128 let ts = generate_ts(2021, 4, 22, 3, 4, 5, 6);
1129 let ts1 =
1130 Timestamp::parse("2021-04-22 03:04:05.000006", "yyyy-mm-dd hh24:mi:ss.ff")
1131 .unwrap();
1132 let ts2 =
1133 Timestamp::parse("2021-APRIL-22 03:04:05.000006", "yyyy-mm-dd hh24:mi:ss.ff")
1134 .unwrap();
1135 let ts3 =
1136 Timestamp::parse("2021-APR-22 03:04:05.000006", "yyyy-mm-dd hh24:mi:ss.ff")
1137 .unwrap();
1138 let ts4 =
1139 Timestamp::parse("2021-April-22 03:04:05.000006", "yyyy-mm-dd hh24:mi:ss.ff")
1140 .unwrap();
1141 let ts5 =
1142 Timestamp::parse("2021-Apr-22 03:04:05.000006", "yyyy-mm-dd hh24:mi:ss.ff")
1143 .unwrap();
1144 let ts6 =
1145 Timestamp::parse("2021-april-22 03:04:05.000006", "yyyy-mm-dd hh24:mi:ss.ff")
1146 .unwrap();
1147 let ts7 =
1148 Timestamp::parse("2021-apr-22 03:04:05.000006", "yyyy-mm-dd hh24:mi:ss.ff")
1149 .unwrap();
1150 assert_eq!(ts, ts1);
1151 assert_eq!(ts, ts2);
1152 assert_eq!(ts, ts3);
1153 assert_eq!(ts, ts4);
1154 assert_eq!(ts, ts5);
1155 assert_eq!(ts, ts6);
1156 assert_eq!(ts, ts7);
1157 }
1158
1159 {
1161 let ts = generate_ts(2021, 4, 22, 3, 4, 5, 6);
1162 let ts2 = Timestamp::parse(
1163 "2021-04-22 03:04:05.000006 thu",
1164 "yyyy-mm-dd hh24:mi:ss.FF6 dy",
1165 )
1166 .unwrap();
1167 let ts3 = Timestamp::parse(
1168 "2021-04-22 03:04:05.000006 5",
1169 "yyyy-mm-dd hh24:mi:ss.FF6 d",
1170 )
1171 .unwrap();
1172 let ts4 =
1173 Timestamp::parse("2021 112 3:4:5.000006", "yyyy ddd hh24:mi:ss.FF6").unwrap();
1174 let ts5 = Timestamp::parse(
1175 "2021-4-22 3:4:5.000006 112",
1176 "yyyy-mm-dd hh24:mi:ss.FF6 ddd",
1177 )
1178 .unwrap();
1179 assert_eq!(ts, ts2);
1180 assert_eq!(ts, ts3);
1181 assert_eq!(ts, ts4);
1182 assert_eq!(ts, ts5);
1183
1184 let ts2 = Timestamp::parse(
1185 "2021-04-22 03:04:05.000006 thu",
1186 "yyyy-mm-dd hh24:mi:ss.FF6 dy",
1187 )
1188 .unwrap();
1189 assert_eq!(ts, ts2);
1190
1191 let ts2 = Timestamp::parse(
1192 "2021-04-22 03:04:05.000006 thursday",
1193 "yyyy-mm-dd hh24:mi:ss.FF6 day",
1194 )
1195 .unwrap();
1196 assert_eq!(ts, ts2);
1197
1198 let ts2 = Timestamp::parse(
1199 "2021-04-22 03:04:05.000006 thu",
1200 "yyyy-mm-dd hh24:mi:ss.FF6 Dy",
1201 )
1202 .unwrap();
1203 assert_eq!(ts, ts2);
1204
1205 let ts2 = Timestamp::parse(
1206 "2021-04-22 03:04:05.000006 Thu",
1207 "yyyy-mm-dd hh24:mi:ss.FF6 dy",
1208 )
1209 .unwrap();
1210 assert_eq!(ts, ts2);
1211
1212 assert!(Timestamp::parse(
1213 "2021-04-23 03:04:05.000006 thu",
1214 "yyyy-mm-dd hh24:mi:ss.FF6 dy",
1215 )
1216 .is_err());
1217
1218 assert!(Timestamp::parse(
1219 "2021-04-23 03:04:05.000006 5",
1220 "yyyy-mm-dd hh24:mi:ss.FF6 d",
1221 )
1222 .is_err());
1223
1224 assert!(Timestamp::parse(
1225 "2021-04-22 03:04:05.000006 ",
1226 "yyyy-mm-dd hh24:mi:ss.FF6 d",
1227 )
1228 .is_err());
1229
1230 assert!(Timestamp::parse("2021-04-22 172", "yyyy-mm-dd ddd",).is_err());
1231 }
1232
1233 {
1235 let ts = generate_ts(2021, 4, 25, 3, 4, 5, 6);
1236 assert_eq!(
1237 format!(
1238 "{}",
1239 ts.format("DAY DaY DY D DDD W WW WW MM MM yyyy YYYY MI MI")
1240 .unwrap()
1241 ),
1242 "SUNDAY Sunday SUN 1 115 4 17 17 04 04 2021 2021 04 04"
1243 );
1244
1245 assert_eq!(
1246 format!(
1247 "{}",
1248 ts.format("DAYDaYDYDWWWWWDMMMMyyyyYYYYMIMIDDD").unwrap()
1249 ),
1250 "SUNDAYSundaySUN11717410404202120210404115"
1251 );
1252 }
1253
1254 {
1256 assert!(Timestamp::parse(
1258 "2021-04-22 03:04:05.000006",
1259 "yyyy-mmX-dd hh24:mi:ss.FF6",
1260 )
1261 .is_err());
1262
1263 assert!(
1264 Timestamp::parse("2021-04-22 03:04:05.000006", "yyyy-mm-dd mi:ss.FF7").is_err()
1265 );
1266
1267 assert!(
1268 Timestamp::parse("2021-04-22 03:04:05.000006", "yyy-mm-dd hh24:mi:ss.FF7")
1269 .is_err()
1270 );
1271
1272 assert!(
1273 Timestamp::parse("2021-04-32 03:04:05.000006", "yyyy-mm-dd mi:ss.FF7").is_err()
1274 );
1275
1276 assert!(
1277 Timestamp::parse("10000-04-31 03:04:05.000006", "yyyy-mm-dd mi:ss.FF6")
1278 .is_err()
1279 );
1280
1281 assert!(
1282 Timestamp::parse("10000-04-31 33:04:05.000006", "yyyy-mm-dd mi:ss.FF6")
1283 .is_err()
1284 );
1285
1286 assert!(Timestamp::parse(
1287 "2021-04-22 03:04:05.000006",
1288 "ABCD-mm-dd hh24:mi:ss.FF10",
1289 )
1290 .is_err());
1291
1292 assert!(Timestamp::parse(
1293 "2021-04-23 03:04:05.000006 thur",
1294 "yyyy-mm-dd hh24:mi:ss.FF6 dy",
1295 )
1296 .is_err());
1297
1298 assert!(
1299 Timestamp::parse("2021423 03:04:05.000006", "yyyymmdd hh24:mi:ss.FF6").is_err()
1300 );
1301
1302 assert!(
1303 Timestamp::parse("2021423 03:04:05.000006", "yyyymmdd hh24:mi:ss.FF3").is_err()
1304 );
1305
1306 let timestamp = generate_ts(1234, 5, 6, 7, 8, 9, 10);
1307 assert!(timestamp.format("testtest").is_err());
1308
1309 assert!(Timestamp::parse("2021423 03:04:05", "yyyymmdd am hh:mi:ss").is_err());
1310
1311 assert!(Timestamp::parse(
1312 "2021-04-23 03:04:05.000006 4",
1313 "yyyy-mm-dd hh24:mi:ss.FF6 w",
1314 )
1315 .is_err());
1316 }
1317
1318 }
1321 }
1322
1323 #[test]
1324 fn test_timestamp_date_time() {
1325 let ts = generate_ts(1, 1, 1, 0, 0, 0, 0);
1326 assert_eq!(ts.date(), generate_date(1, 1, 1));
1327 assert_eq!(ts.time(), generate_time(0, 0, 0, 0));
1328
1329 let ts = generate_ts(1, 1, 1, 23, 59, 59, 999999);
1330 assert_eq!(ts.date(), generate_date(1, 1, 1));
1331 assert_eq!(ts.time(), generate_time(23, 59, 59, 999999));
1332
1333 let ts = generate_ts(1969, 12, 30, 0, 0, 0, 0);
1334 assert_eq!(ts.date(), generate_date(1969, 12, 30));
1335 assert_eq!(ts.time(), generate_time(0, 0, 0, 0));
1336
1337 let ts = generate_ts(1969, 12, 30, 23, 59, 59, 999999);
1338 assert_eq!(ts.date(), generate_date(1969, 12, 30));
1339 assert_eq!(ts.time(), generate_time(23, 59, 59, 999999));
1340
1341 let ts = generate_ts(1969, 12, 31, 0, 0, 0, 0);
1342 assert_eq!(ts.date(), generate_date(1969, 12, 31));
1343 assert_eq!(ts.time(), generate_time(0, 0, 0, 0));
1344
1345 let ts = generate_ts(1969, 12, 31, 23, 59, 59, 999999);
1346 assert_eq!(ts.date(), generate_date(1969, 12, 31));
1347 assert_eq!(ts.time(), generate_time(23, 59, 59, 999999));
1348
1349 let ts = generate_ts(1970, 1, 1, 0, 0, 0, 0);
1350 assert_eq!(ts.date(), generate_date(1970, 1, 1));
1351 assert_eq!(ts.time(), generate_time(0, 0, 0, 0));
1352
1353 let ts = generate_ts(1970, 1, 1, 23, 59, 59, 999999);
1354 assert_eq!(ts.date(), generate_date(1970, 1, 1));
1355 assert_eq!(ts.time(), generate_time(23, 59, 59, 999999));
1356
1357 let ts = generate_ts(9999, 1, 1, 0, 0, 0, 0);
1358 assert_eq!(ts.date(), generate_date(9999, 1, 1));
1359 assert_eq!(ts.time(), generate_time(0, 0, 0, 0));
1360
1361 let ts = generate_ts(9999, 1, 1, 23, 59, 59, 999999);
1362 assert_eq!(ts.date(), generate_date(9999, 1, 1));
1363 assert_eq!(ts.time(), generate_time(23, 59, 59, 999999));
1364
1365 let ts = generate_ts(9999, 12, 31, 0, 0, 0, 0);
1366 assert_eq!(ts.date(), generate_date(9999, 12, 31));
1367 assert_eq!(ts.time(), generate_time(0, 0, 0, 0));
1368
1369 let ts = generate_ts(9999, 12, 31, 23, 59, 59, 999999);
1370 assert_eq!(ts.date(), generate_date(9999, 12, 31));
1371 assert_eq!(ts.time(), generate_time(23, 59, 59, 999999));
1372 }
1373
1374 #[test]
1375 fn test_timestamp_add_sub_interval_dt() {
1376 let ts = generate_ts(2001, 3, 31, 12, 5, 6, 7);
1378 let interval = IntervalDT::try_from_dhms(1, 2, 3, 4, 5).unwrap();
1379 let expect = generate_ts(2001, 4, 1, 14, 8, 10, 12);
1380 assert_eq!(ts.add_interval_dt(interval).unwrap(), expect);
1381
1382 let interval = -IntervalDT::try_from_dhms(1, 2, 3, 4, 5).unwrap();
1384 assert_eq!(ts.sub_interval_dt(interval).unwrap(), expect);
1385
1386 let ts = generate_ts(2001, 12, 31, 23, 59, 59, 999999);
1388 let interval = IntervalDT::try_from_dhms(0, 0, 0, 0, 1).unwrap();
1389 let expect = generate_ts(2002, 1, 1, 0, 0, 0, 0);
1390 assert_eq!(ts.add_interval_dt(interval).unwrap(), expect);
1391
1392 let interval = -IntervalDT::try_from_dhms(0, 0, 0, 0, 1).unwrap();
1394 assert_eq!(ts.sub_interval_dt(interval).unwrap(), expect);
1395
1396 let ts = generate_ts(2001, 3, 31, 12, 5, 6, 7);
1398 let interval = -IntervalDT::try_from_dhms(1, 2, 3, 4, 5).unwrap();
1399 let expect = generate_ts(2001, 3, 30, 10, 2, 2, 2);
1400 assert_eq!(ts.add_interval_dt(interval).unwrap(), expect);
1401
1402 let interval = IntervalDT::try_from_dhms(1, 2, 3, 4, 5).unwrap();
1404 assert_eq!(ts.sub_interval_dt(interval).unwrap(), expect);
1405
1406 let ts = generate_ts(1970, 1, 1, 0, 0, 0, 0);
1408 let interval = -IntervalDT::try_from_dhms(0, 0, 0, 0, 1).unwrap();
1409 let expect = generate_ts(1969, 12, 31, 23, 59, 59, 999999);
1410 assert_eq!(ts.add_interval_dt(interval).unwrap(), expect);
1411
1412 let interval = IntervalDT::try_from_dhms(0, 0, 0, 0, 1).unwrap();
1414 assert_eq!(ts.sub_interval_dt(interval).unwrap(), expect);
1415
1416 let ts = generate_ts(9999, 12, 31, 23, 59, 59, 999999);
1418 let interval = IntervalDT::try_from_dhms(5, 4, 3, 2, 1).unwrap();
1419 let expect = generate_ts(9999, 12, 26, 19, 56, 57, 999998);
1420 assert_eq!(ts.sub_interval_dt(interval).unwrap(), expect);
1421
1422 let interval = IntervalDT::try_from_dhms(0, 0, 0, 0, 1).unwrap();
1423 assert!(ts.add_interval_dt(interval).is_err());
1424
1425 let interval = IntervalDT::try_from_dhms(12345, 12, 3, 5, 6).unwrap();
1426 assert!(ts.add_interval_dt(interval).is_err());
1427
1428 let ts = generate_ts(1, 1, 1, 0, 0, 0, 0);
1429 let interval = IntervalDT::try_from_dhms(5, 4, 3, 2, 1).unwrap();
1430 let expect = generate_ts(1, 1, 6, 4, 3, 2, 1);
1431 assert_eq!(ts.add_interval_dt(interval).unwrap(), expect);
1432
1433 let interval = IntervalDT::try_from_dhms(0, 0, 0, 0, 1).unwrap();
1434 assert!(ts.sub_interval_dt(interval).is_err());
1435
1436 let interval = IntervalDT::try_from_dhms(12345, 12, 3, 5, 6).unwrap();
1437 assert!(ts.sub_interval_dt(interval).is_err());
1438 }
1439
1440 #[test]
1441 fn test_timestamp_add_sub_interval_ym() {
1442 let ts = generate_ts(2001, 3, 31, 12, 5, 6, 7);
1444 let interval = IntervalYM::try_from_ym(0, 2).unwrap();
1445 assert_eq!(
1446 ts.add_interval_ym(interval).unwrap(),
1447 generate_ts(2001, 5, 31, 12, 5, 6, 7)
1448 );
1449
1450 let interval = IntervalYM::try_from_ym(1, 2).unwrap();
1451 assert_eq!(
1452 ts.add_interval_ym(interval).unwrap(),
1453 generate_ts(2002, 5, 31, 12, 5, 6, 7)
1454 );
1455
1456 let ts = generate_ts(2001, 3, 31, 12, 5, 6, 7);
1458 let interval = IntervalYM::try_from_ym(0, 2).unwrap();
1459 assert_eq!(
1460 ts.sub_interval_ym(-interval).unwrap(),
1461 generate_ts(2001, 5, 31, 12, 5, 6, 7)
1462 );
1463
1464 let interval = IntervalYM::try_from_ym(1, 2).unwrap();
1465 assert_eq!(
1466 ts.sub_interval_ym(-interval).unwrap(),
1467 generate_ts(2002, 5, 31, 12, 5, 6, 7)
1468 );
1469
1470 let interval = IntervalYM::try_from_ym(0, 2).unwrap();
1472 assert_eq!(
1473 ts.sub_interval_ym(interval).unwrap(),
1474 generate_ts(2001, 1, 31, 12, 5, 6, 7)
1475 );
1476
1477 let interval = IntervalYM::try_from_ym(1, 2).unwrap();
1478 assert_eq!(
1479 ts.sub_interval_ym(interval).unwrap(),
1480 generate_ts(2000, 1, 31, 12, 5, 6, 7)
1481 );
1482
1483 let interval = IntervalYM::try_from_ym(0, 2).unwrap();
1485 assert_eq!(
1486 ts.add_interval_ym(-interval).unwrap(),
1487 generate_ts(2001, 1, 31, 12, 5, 6, 7)
1488 );
1489
1490 let interval = IntervalYM::try_from_ym(1, 2).unwrap();
1491 assert_eq!(
1492 ts.add_interval_ym(-interval).unwrap(),
1493 generate_ts(2000, 1, 31, 12, 5, 6, 7)
1494 );
1495
1496 let upper_ts = generate_ts(9999, 12, 31, 23, 59, 59, 999999);
1498 let lower_ts = generate_ts(1, 1, 1, 0, 0, 0, 0);
1499 let interval = IntervalYM::try_from_ym(0, 1).unwrap();
1500
1501 assert!(upper_ts.add_interval_ym(interval).is_err());
1502 assert!(lower_ts.sub_interval_ym(interval).is_err());
1503
1504 let interval = IntervalYM::try_from_ym(1, 1).unwrap();
1506 assert!(ts.add_interval_ym(interval).is_err());
1507
1508 let interval = IntervalYM::try_from_ym(0, 11).unwrap();
1509 assert!(ts.add_interval_ym(interval).is_err());
1510
1511 let interval = IntervalYM::try_from_ym(2, 11).unwrap();
1512 assert!(ts.add_interval_ym(interval).is_err());
1513
1514 let interval = IntervalYM::try_from_ym(1, 1).unwrap();
1515 assert!(ts.sub_interval_ym(-interval).is_err());
1516
1517 let interval = IntervalYM::try_from_ym(0, 11).unwrap();
1518 assert!(ts.sub_interval_ym(-interval).is_err());
1519
1520 let interval = IntervalYM::try_from_ym(2, 11).unwrap();
1521 assert!(ts.sub_interval_ym(-interval).is_err());
1522
1523 let interval = IntervalYM::try_from_ym(1, 1).unwrap();
1524 assert!(ts.sub_interval_ym(interval).is_err());
1525
1526 let interval = IntervalYM::try_from_ym(0, 11).unwrap();
1527 assert!(ts.sub_interval_ym(interval).is_err());
1528
1529 let interval = IntervalYM::try_from_ym(2, 1).unwrap();
1530 assert!(ts.sub_interval_ym(interval).is_err());
1531
1532 let interval = IntervalYM::try_from_ym(2, 1).unwrap();
1533 assert!(ts.sub_interval_ym(interval).is_err());
1534
1535 let interval = IntervalYM::try_from_ym(1, 1).unwrap();
1536 assert!(ts.add_interval_ym(-interval).is_err());
1537
1538 let interval = IntervalYM::try_from_ym(0, 11).unwrap();
1539 assert!(ts.add_interval_ym(-interval).is_err());
1540
1541 let interval = IntervalYM::try_from_ym(2, 1).unwrap();
1542 assert!(ts.add_interval_ym(-interval).is_err());
1543 }
1544
1545 #[test]
1546 fn test_timestamp_add_sub_time() {
1547 let ts = generate_ts(1234, 5, 6, 7, 8, 9, 10);
1549 let time = Time::try_from_hms(1, 2, 3, 4).unwrap();
1550 let expect = generate_ts(1234, 5, 6, 8, 10, 12, 14);
1551 assert_eq!(ts.add_time(time).unwrap(), expect);
1552
1553 let expect = generate_ts(1234, 5, 6, 6, 6, 6, 6);
1554 assert_eq!(ts.sub_time(time).unwrap(), expect);
1555
1556 let time = Time::try_from_hms(23, 59, 59, 999999).unwrap();
1557 let expect = generate_ts(1234, 5, 7, 7, 8, 9, 9);
1558 assert_eq!(ts.add_time(time).unwrap(), expect);
1559
1560 let expect = generate_ts(1234, 5, 5, 7, 8, 9, 11);
1561 assert_eq!(ts.sub_time(time).unwrap(), expect);
1562
1563 let ts = generate_ts(9999, 12, 31, 23, 59, 59, 999999);
1565 let time = Time::try_from_hms(5, 4, 3, 2).unwrap();
1566 assert!(ts.add_time(time).is_err());
1567
1568 let time = Time::try_from_hms(0, 0, 0, 1).unwrap();
1569 assert!(ts.add_time(time).is_err());
1570
1571 let ts = generate_ts(1, 1, 1, 0, 0, 0, 0);
1572 let time = Time::try_from_hms(5, 4, 3, 2).unwrap();
1573 assert!(ts.sub_time(time).is_err());
1574
1575 let time = Time::try_from_hms(0, 0, 0, 1).unwrap();
1576 assert!(ts.sub_time(time).is_err());
1577 }
1578
1579 #[test]
1580 fn test_timestamp_sub_timestamp() {
1581 let upper_ts = generate_ts(9999, 12, 31, 23, 59, 59, 999999);
1582 let lower_ts = generate_ts(1, 1, 1, 0, 0, 0, 0);
1583 let ts = generate_ts(5000, 6, 15, 12, 30, 30, 500000);
1584
1585 assert_eq!(
1586 upper_ts.sub_timestamp(lower_ts),
1587 IntervalDT::try_from_dhms(3652058, 23, 59, 59, 999999).unwrap()
1588 );
1589
1590 assert_eq!(
1591 upper_ts.sub_timestamp(ts),
1592 IntervalDT::try_from_dhms(1826046, 11, 29, 29, 499999).unwrap()
1593 );
1594
1595 assert_eq!(
1596 lower_ts.sub_timestamp(upper_ts),
1597 -IntervalDT::try_from_dhms(3652058, 23, 59, 59, 999999).unwrap()
1598 );
1599 }
1600
1601 #[test]
1602 fn test_timestamp_sub_date() {
1603 let upper_ts = generate_ts(9999, 12, 31, 23, 59, 59, 999999);
1604 let lower_ts = generate_ts(1, 1, 1, 0, 0, 0, 0);
1605 let lower_date = Date::try_from_ymd(1, 1, 1).unwrap();
1606 let upper_date = Date::try_from_ymd(9999, 12, 31).unwrap();
1607 let date = Date::try_from_ymd(5000, 6, 15).unwrap();
1608
1609 assert_eq!(
1610 upper_ts.sub_date(lower_date),
1611 IntervalDT::try_from_dhms(3652058, 23, 59, 59, 999999).unwrap()
1612 );
1613
1614 assert_eq!(
1615 upper_ts.sub_date(date),
1616 IntervalDT::try_from_dhms(1826046, 23, 59, 59, 999999).unwrap()
1617 );
1618
1619 assert_eq!(
1620 lower_ts.sub_date(upper_date),
1621 -IntervalDT::try_from_dhms(3652058, 0, 0, 0, 0).unwrap()
1622 );
1623 }
1624
1625 #[test]
1626 fn test_timestamp_add_sub_days() {
1627 let upper_ts = generate_ts(9999, 12, 31, 23, 59, 59, 999999);
1628 let lower_ts = generate_ts(1, 1, 1, 0, 0, 0, 0);
1629
1630 assert!(lower_ts.add_days(213435445784784.13).is_err());
1632 assert!(lower_ts.add_days(f64::NAN).is_err());
1633 assert!(lower_ts.add_days(f64::INFINITY).is_err());
1634 assert!(lower_ts.add_days(f64::NEG_INFINITY).is_err());
1635 assert!(lower_ts.add_days(f64::MAX).is_err());
1636 assert!(lower_ts.add_days(f64::MIN).is_err());
1637 assert!(upper_ts.add_days(0.0001).is_err());
1638
1639 assert!(lower_ts.sub_days(213435445784784.13).is_err());
1640 assert!(lower_ts.sub_days(f64::NAN).is_err());
1641 assert!(lower_ts.sub_days(f64::INFINITY).is_err());
1642 assert!(lower_ts.sub_days(f64::NEG_INFINITY).is_err());
1643 assert!(lower_ts.sub_days(f64::MAX).is_err());
1644 assert!(lower_ts.sub_days(f64::MIN).is_err());
1645 assert!(lower_ts.sub_days(0.0001).is_err());
1646
1647 assert_eq!(
1649 lower_ts.add_days(1.123456789).unwrap(),
1650 generate_ts(1, 1, 2, 2, 57, 46, 666570)
1651 );
1652 assert_eq!(
1653 upper_ts.sub_days(1.123456789).unwrap(),
1654 generate_ts(9999, 12, 30, 21, 2, 13, 333429)
1655 );
1656
1657 assert_eq!(upper_ts.sub_days(0.0).unwrap(), upper_ts);
1659 assert_eq!(upper_ts.add_days(0.0).unwrap(), upper_ts);
1660 assert_eq!(
1661 upper_ts.sub_days(1.0).unwrap(),
1662 generate_ts(9999, 12, 30, 23, 59, 59, 999999)
1663 );
1664 assert_eq!(
1665 lower_ts.add_days(1.0).unwrap(),
1666 generate_ts(1, 1, 2, 0, 0, 0, 0)
1667 );
1668
1669 let ts = generate_ts(5000, 6, 15, 12, 30, 30, 555555);
1670 assert_eq!(ts.sub_days(1.12).unwrap(), ts.add_days(-1.12).unwrap());
1671 assert_eq!(ts.sub_days(-1.12).unwrap(), ts.add_days(1.12).unwrap());
1672 }
1673
1674 #[test]
1675 fn test_timestamp_cmp_date() {
1676 let ts = generate_ts(1970, 1, 1, 1, 1, 1, 1);
1677 let date = generate_date(1970, 1, 1);
1678 assert!(ts > date);
1679 let ts = generate_ts(1970, 1, 1, 0, 0, 0, 0);
1680 assert!(ts == date);
1681 }
1682
1683 #[allow(clippy::float_cmp)]
1684 fn test_extract(year: i32, month: u32, day: u32, hour: u32, min: u32, sec: u32, usec: u32) {
1685 let ts = generate_ts(year, month, day, hour, min, sec, usec);
1686 assert_eq!(year, ts.year().unwrap());
1687 assert_eq!(month as i32, ts.month().unwrap());
1688 assert_eq!(day as i32, ts.day().unwrap());
1689 assert_eq!(hour as i32, ts.hour().unwrap());
1690 assert_eq!(min as i32, ts.minute().unwrap());
1691 assert_eq!(
1692 (sec as f64 + (usec as f64) / 1_000_000f64),
1693 ts.second().unwrap()
1694 );
1695 }
1696
1697 #[test]
1698 fn test_timestamp_extract() {
1699 test_extract(1960, 12, 31, 23, 59, 59, 999999);
1700 test_extract(1, 1, 1, 0, 0, 0, 0);
1701 test_extract(1, 1, 1, 1, 1, 1, 1);
1702 test_extract(1969, 12, 31, 1, 2, 3, 4);
1703 test_extract(1969, 12, 30, 23, 59, 59, 999999);
1704 test_extract(1969, 12, 30, 0, 0, 0, 0);
1705 test_extract(1970, 1, 1, 0, 0, 0, 0);
1706 test_extract(1970, 1, 1, 12, 30, 30, 30);
1707 test_extract(1999, 10, 21, 12, 30, 30, 30);
1708 test_extract(9999, 12, 31, 23, 59, 59, 999999);
1709 }
1710
1711 #[test]
1712 fn test_now() {
1713 let now = Local::now();
1714 let dt = Timestamp::now().unwrap();
1715 assert_eq!(now.year(), dt.year().unwrap());
1716 assert_eq!(now.month() as i32, dt.month().unwrap());
1717 assert_eq!(now.day() as i32, dt.day().unwrap());
1718 assert_eq!(now.hour() as i32, dt.hour().unwrap());
1719 }
1720
1721 #[test]
1722 fn test_round_error() {
1723 let ts = generate_ts(DATE_MAX_YEAR, 12, 31, 23, 59, 30, 0);
1724
1725 assert!(ts.round_century().is_err());
1727 assert!(ts.round_year().is_err());
1728 assert!(ts.round_iso_year().is_err());
1729 assert!(ts.round_quarter().is_err());
1730 assert!(ts.round_month().is_err());
1731 assert!(ts.round_week().is_err());
1732 assert!(ts.round_iso_week().is_err());
1733 assert!(ts.round_month_start_week().is_err());
1734 assert!(ts.round_day().is_err());
1735 assert!(ts.round_sunday_start_week().is_err());
1736 assert!(ts.round_hour().is_err());
1737 assert!(ts.round_minute().is_err());
1738 }
1739
1740 #[test]
1741 fn test_trunc() {
1742 let ts = generate_ts(1996, 10, 24, 0, 0, 0, 0);
1743
1744 assert_eq!(
1746 generate_ts(1901, 1, 1, 0, 0, 0, 0),
1747 ts.trunc_century().unwrap()
1748 );
1749 assert_eq!(
1750 generate_ts(1801, 1, 1, 0, 0, 0, 0),
1751 generate_ts(1900, 10, 24, 0, 0, 0, 0)
1752 .trunc_century()
1753 .unwrap()
1754 );
1755
1756 assert_eq!(
1758 generate_ts(1996, 1, 1, 0, 0, 0, 0),
1759 ts.trunc_year().unwrap()
1760 );
1761
1762 assert_eq!(
1764 generate_ts(1996, 1, 1, 0, 0, 0, 0),
1765 ts.trunc_iso_year().unwrap()
1766 );
1767 assert_eq!(
1768 generate_ts(2021, 1, 4, 0, 0, 0, 0),
1769 generate_ts(2021, 10, 24, 0, 0, 0, 0)
1770 .trunc_iso_year()
1771 .unwrap()
1772 );
1773
1774 assert_eq!(
1776 generate_ts(1996, 10, 1, 0, 0, 0, 0),
1777 ts.trunc_quarter().unwrap()
1778 );
1779
1780 assert_eq!(
1782 generate_ts(1996, 10, 1, 0, 0, 0, 0),
1783 ts.trunc_month().unwrap()
1784 );
1785
1786 assert_eq!(
1788 generate_ts(1996, 10, 21, 0, 0, 0, 0),
1789 ts.trunc_week().unwrap()
1790 );
1791
1792 assert_eq!(
1794 generate_ts(1996, 10, 21, 0, 0, 0, 0),
1795 ts.trunc_iso_week().unwrap()
1796 );
1797
1798 assert_eq!(
1800 generate_ts(1996, 10, 22, 0, 0, 0, 0),
1801 ts.trunc_month_start_week().unwrap()
1802 );
1803
1804 assert_eq!(
1806 generate_ts(1996, 10, 24, 0, 0, 0, 0),
1807 ts.trunc_day().unwrap()
1808 );
1809
1810 assert_eq!(
1812 generate_ts(1996, 10, 20, 0, 0, 0, 0),
1813 ts.trunc_sunday_start_week().unwrap()
1814 );
1815
1816 assert_eq!(
1818 generate_ts(2015, 4, 11, 13, 0, 0, 0),
1819 generate_ts(2015, 4, 11, 13, 59, 59, 0)
1820 .trunc_hour()
1821 .unwrap()
1822 );
1823
1824 assert_eq!(
1826 generate_ts(2015, 4, 11, 13, 59, 0, 0),
1827 generate_ts(2015, 4, 11, 13, 59, 59, 0)
1828 .trunc_minute()
1829 .unwrap()
1830 );
1831 }
1832
1833 #[test]
1834 fn test_round() {
1835 let ts = generate_ts(1996, 10, 24, 0, 0, 0, 0);
1836
1837 assert_eq!(
1838 generate_ts(2001, 1, 1, 0, 0, 0, 0),
1839 ts.round_century().unwrap()
1840 );
1841 assert_eq!(
1842 generate_ts(1901, 1, 1, 0, 0, 0, 0),
1843 generate_ts(2000, 1, 1, 0, 0, 0, 0).round_century().unwrap()
1844 );
1845 assert_eq!(
1846 generate_ts(1997, 1, 1, 0, 0, 0, 0),
1847 ts.round_year().unwrap()
1848 );
1849 assert_eq!(
1850 generate_ts(1996, 12, 30, 0, 0, 0, 0),
1851 ts.round_iso_year().unwrap()
1852 );
1853 assert_eq!(
1854 generate_ts(1996, 10, 1, 0, 0, 0, 0),
1855 ts.round_quarter().unwrap()
1856 );
1857 assert_eq!(
1858 generate_ts(2022, 1, 1, 0, 0, 0, 0),
1859 generate_ts(2021, 11, 16, 0, 0, 0, 0)
1860 .round_quarter()
1861 .unwrap()
1862 );
1863 assert_eq!(
1864 generate_ts(2021, 10, 1, 0, 0, 0, 0),
1865 generate_ts(2021, 9, 1, 0, 0, 0, 0).round_quarter().unwrap()
1866 );
1867 assert_eq!(
1868 generate_ts(2022, 1, 1, 0, 0, 0, 0),
1869 generate_ts(2021, 12, 1, 0, 0, 0, 0)
1870 .round_quarter()
1871 .unwrap()
1872 );
1873 assert_eq!(
1874 generate_ts(1996, 11, 1, 0, 0, 0, 0),
1875 ts.round_month().unwrap()
1876 );
1877
1878 assert_eq!(
1880 generate_ts(2021, 10, 15, 0, 0, 0, 0),
1881 generate_ts(2021, 10, 13, 0, 0, 0, 0).round_week().unwrap()
1882 );
1883 assert_eq!(
1884 generate_ts(2021, 1, 1, 0, 0, 0, 0),
1885 generate_ts(2021, 1, 1, 0, 0, 0, 0).round_week().unwrap()
1886 );
1887 assert_eq!(
1888 generate_ts(2021, 12, 31, 0, 0, 0, 0),
1889 generate_ts(2021, 12, 31, 0, 0, 0, 0).round_week().unwrap()
1890 );
1891 assert_eq!(
1894 generate_ts(2021, 1, 1, 0, 0, 0, 0),
1895 generate_ts(2021, 1, 4, 11, 59, 59, 59)
1896 .round_week()
1897 .unwrap()
1898 );
1899 assert_eq!(
1900 generate_ts(2021, 1, 8, 0, 0, 0, 0),
1901 generate_ts(2021, 1, 4, 12, 0, 0, 0).round_week().unwrap()
1902 );
1903 assert_eq!(
1905 generate_ts(2021, 1, 29, 0, 0, 0, 0),
1906 generate_ts(2021, 2, 1, 11, 59, 59, 59)
1907 .round_week()
1908 .unwrap()
1909 );
1910 assert_eq!(
1911 generate_ts(2021, 2, 5, 0, 0, 0, 0),
1912 generate_ts(2021, 2, 1, 12, 0, 0, 0).round_week().unwrap()
1913 );
1914 assert_eq!(
1916 generate_ts(2021, 12, 31, 0, 0, 0, 0),
1917 generate_ts(2021, 12, 31, 11, 59, 59, 59)
1918 .round_week()
1919 .unwrap()
1920 );
1921 assert_eq!(
1922 generate_ts(2022, 1, 1, 0, 0, 0, 0),
1923 generate_ts(2021, 12, 31, 12, 0, 0, 0).round_week().unwrap()
1924 );
1925
1926 assert_eq!(
1928 generate_ts(2021, 10, 18, 0, 0, 0, 0),
1929 generate_ts(2021, 10, 15, 0, 0, 0, 0)
1930 .round_iso_week()
1931 .unwrap()
1932 );
1933 assert_eq!(
1936 generate_ts(2021, 10, 11, 0, 0, 0, 0),
1937 generate_ts(2021, 10, 14, 11, 59, 59, 59)
1938 .round_iso_week()
1939 .unwrap()
1940 );
1941 assert_eq!(
1942 generate_ts(2021, 10, 18, 0, 0, 0, 0),
1943 generate_ts(2021, 10, 15, 12, 0, 0, 0)
1944 .round_iso_week()
1945 .unwrap()
1946 );
1947 assert_eq!(
1949 generate_ts(2021, 2, 22, 0, 0, 0, 0),
1950 generate_ts(2021, 2, 25, 11, 59, 59, 59)
1951 .round_iso_week()
1952 .unwrap()
1953 );
1954 assert_eq!(
1955 generate_ts(2021, 3, 1, 0, 0, 0, 0),
1956 generate_ts(2021, 2, 25, 12, 0, 0, 0)
1957 .round_iso_week()
1958 .unwrap()
1959 );
1960 assert_eq!(
1962 generate_ts(2021, 12, 27, 0, 0, 0, 0),
1963 generate_ts(2021, 12, 30, 11, 59, 59, 59)
1964 .round_iso_week()
1965 .unwrap()
1966 );
1967 assert_eq!(
1968 generate_ts(2022, 1, 3, 0, 0, 0, 0),
1969 generate_ts(2021, 12, 30, 12, 0, 0, 0)
1970 .round_iso_week()
1971 .unwrap()
1972 );
1973
1974 assert_eq!(
1976 generate_ts(2021, 11, 8, 0, 0, 0, 0),
1977 generate_ts(2021, 11, 5, 0, 0, 0, 0)
1978 .round_month_start_week()
1979 .unwrap()
1980 );
1981 assert_eq!(
1984 generate_ts(2021, 11, 1, 0, 0, 0, 0),
1985 generate_ts(2021, 11, 4, 11, 59, 59, 59)
1986 .round_month_start_week()
1987 .unwrap()
1988 );
1989 assert_eq!(
1990 generate_ts(2021, 11, 8, 0, 0, 0, 0),
1991 generate_ts(2021, 11, 4, 12, 0, 0, 0)
1992 .round_month_start_week()
1993 .unwrap()
1994 );
1995 assert_eq!(
1997 generate_ts(2021, 11, 29, 0, 0, 0, 0),
1998 generate_ts(2021, 11, 30, 11, 59, 59, 59)
1999 .round_month_start_week()
2000 .unwrap()
2001 );
2002 assert_eq!(
2003 generate_ts(2021, 12, 1, 0, 0, 0, 0),
2004 generate_ts(2021, 11, 30, 12, 0, 0, 0)
2005 .round_month_start_week()
2006 .unwrap()
2007 );
2008 assert_eq!(
2010 generate_ts(2021, 12, 29, 0, 0, 0, 0),
2011 generate_ts(2021, 12, 31, 11, 59, 59, 59)
2012 .round_month_start_week()
2013 .unwrap()
2014 );
2015 assert_eq!(
2016 generate_ts(2022, 1, 1, 0, 0, 0, 0),
2017 generate_ts(2021, 12, 31, 12, 0, 0, 0)
2018 .round_month_start_week()
2019 .unwrap()
2020 );
2021
2022 assert_eq!(
2023 generate_ts(1996, 10, 25, 0, 0, 0, 0),
2024 generate_ts(1996, 10, 24, 12, 0, 0, 0).round_day().unwrap()
2025 );
2026
2027 assert_eq!(
2029 generate_ts(1996, 10, 27, 0, 0, 0, 0),
2030 ts.round_sunday_start_week().unwrap()
2031 );
2032 assert_eq!(
2035 generate_ts(2021, 10, 10, 0, 0, 0, 0),
2036 generate_ts(2021, 10, 13, 11, 59, 59, 59)
2037 .round_sunday_start_week()
2038 .unwrap()
2039 );
2040 assert_eq!(
2041 generate_ts(2021, 10, 17, 0, 0, 0, 0),
2042 generate_ts(2021, 10, 13, 12, 0, 0, 0)
2043 .round_sunday_start_week()
2044 .unwrap()
2045 );
2046 assert_eq!(
2048 generate_ts(2021, 3, 28, 0, 0, 0, 0),
2049 generate_ts(2021, 3, 31, 11, 59, 59, 59)
2050 .round_sunday_start_week()
2051 .unwrap()
2052 );
2053 assert_eq!(
2054 generate_ts(2021, 4, 4, 0, 0, 0, 0),
2055 generate_ts(2021, 3, 31, 12, 0, 0, 0)
2056 .round_sunday_start_week()
2057 .unwrap()
2058 );
2059 assert_eq!(
2061 generate_ts(2021, 12, 26, 0, 0, 0, 0),
2062 generate_ts(2021, 12, 29, 11, 59, 59, 59)
2063 .round_sunday_start_week()
2064 .unwrap()
2065 );
2066 assert_eq!(
2067 generate_ts(2022, 1, 2, 0, 0, 0, 0),
2068 generate_ts(2021, 12, 29, 12, 0, 0, 0)
2069 .round_sunday_start_week()
2070 .unwrap()
2071 );
2072
2073 assert_eq!(
2074 generate_ts(2015, 3, 3, 12, 0, 0, 0),
2075 generate_ts(2015, 3, 3, 11, 30, 59, 0).round_hour().unwrap()
2076 );
2077 assert_eq!(
2078 generate_ts(2015, 3, 4, 0, 0, 0, 0),
2079 generate_ts(2015, 3, 3, 23, 30, 0, 0).round_hour().unwrap()
2080 );
2081 assert_eq!(
2082 generate_ts(2015, 3, 3, 11, 30, 0, 0),
2083 generate_ts(2015, 3, 3, 11, 29, 30, 0)
2084 .round_minute()
2085 .unwrap()
2086 );
2087 assert_eq!(
2088 generate_ts(2015, 3, 4, 0, 0, 0, 0),
2089 generate_ts(2015, 3, 3, 23, 59, 30, 0)
2090 .round_minute()
2091 .unwrap()
2092 );
2093 }
2094
2095 #[test]
2096 fn test_last_day_of_month() {
2097 assert_eq!(
2098 generate_ts(2021, 9, 23, 14, 15, 16, 17).last_day_of_month(),
2099 generate_ts(2021, 9, 30, 14, 15, 16, 17)
2100 );
2101 assert_eq!(
2102 generate_ts(1970, 1, 1, 0, 0, 0, 0).last_day_of_month(),
2103 generate_ts(1970, 1, 31, 0, 0, 0, 0)
2104 );
2105 assert_eq!(
2106 generate_ts(1704, 2, 1, 23, 59, 59, 999999).last_day_of_month(),
2107 generate_ts(1704, 2, 29, 23, 59, 59, 999999)
2108 );
2109 assert_eq!(
2110 generate_ts(1705, 2, 10, 20, 40, 50, 56789).last_day_of_month(),
2111 generate_ts(1705, 2, 28, 20, 40, 50, 56789)
2112 );
2113 assert_eq!(
2114 generate_ts(1, 1, 1, 0, 0, 0, 0).last_day_of_month(),
2115 generate_ts(1, 1, 31, 0, 0, 0, 0)
2116 );
2117 assert_eq!(
2118 generate_ts(9999, 12, 31, 23, 59, 59, 999999).last_day_of_month(),
2119 generate_ts(9999, 12, 31, 23, 59, 59, 999999)
2120 );
2121 }
2122
2123 #[test]
2124 fn test_iso_format() {
2125 const FMT: &str = "YYYY-MM-DDTHH24:MI:SS.FF";
2126 fn assert_iso_fmt(input: &str, output: &str) {
2127 let ts = Timestamp::parse(input, FMT).unwrap();
2128 assert_eq!(format!("{}", ts.format(FMT).unwrap()), output);
2129 }
2130
2131 fn assert_invalid_iso_str(input: &str) {
2132 assert!(Timestamp::parse(input, FMT).is_err());
2133 }
2134
2135 assert_invalid_iso_str("2023-05-26 23:59");
2136 assert_invalid_iso_str("2023-05-26T");
2137 assert_invalid_iso_str("2023-05-26T ");
2138 assert_invalid_iso_str("2023-05-26 T");
2139
2140 assert_iso_fmt("2023-05-26", "2023-05-26T00:00:00");
2141 assert_iso_fmt("2023-05-26 ", "2023-05-26T00:00:00");
2142 assert_iso_fmt("2023-05-2600:00:01", "2023-05-26T00:00:01");
2143 assert_iso_fmt("2023-05-26 00:00:01", "2023-05-26T00:00:01");
2144 assert_iso_fmt("2023-05-26 T00:00:01", "2023-05-26T00:00:01");
2145 assert_iso_fmt("2023-05-26T 00:00:01", "2023-05-26T00:00:01");
2146 assert_iso_fmt("2023-05-26 T 00:00:01", "2023-05-26T00:00:01");
2147 assert_iso_fmt("2023-05-26 ", "2023-05-26T00:00:00");
2148 assert_iso_fmt("2023-05-26 00:00:01", "2023-05-26T00:00:01");
2149 assert_iso_fmt("2023-05-26 00:00:01", "2023-05-26T00:00:01");
2150 assert_iso_fmt("2023-05-26T00:00:00", "2023-05-26T00:00:00");
2151 assert_iso_fmt("2023-05-26T00:00:00.000", "2023-05-26T00:00:00");
2152 assert_iso_fmt("2023-05-26T00:00:00.123000", "2023-05-26T00:00:00.123000");
2153 assert_iso_fmt("2023-05-26T00:00:00.123456", "2023-05-26T00:00:00.123456");
2154 assert_iso_fmt(
2155 "2023-05-26T00:00:00.123456789",
2156 "2023-05-26T00:00:00.123457",
2157 );
2158 assert_iso_fmt("2023-05-26T00:00:00Z", "2023-05-26T00:00:00");
2159 assert_iso_fmt("2023-05-26T00:00:00.123Z", "2023-05-26T00:00:00.123000");
2160
2161 assert_invalid_iso_str("2023-05");
2162 assert_invalid_iso_str("2023-05-26T00");
2163 assert_invalid_iso_str("2023-05-26T00:00");
2164 assert_invalid_iso_str("2023-05-26T00:00:");
2165 assert_invalid_iso_str("2023-05-26T00:00.123");
2166 assert_invalid_iso_str("2023-05Z");
2167 assert_invalid_iso_str("2023-05-26T00Z");
2168 assert_invalid_iso_str("2023-05-26T00:00Z");
2169 assert_invalid_iso_str("2023-05-26T00:00:Z");
2170 assert_invalid_iso_str("2023-05-26T00:00.123Z");
2171 }
2172}