greg/calendar/
macros.rs

1/// Create a [`DateTime`](super::DateTime) from `YYYY-MM-DD hh:mm:ss`
2///
3/// If the `hh:mm:ss` time component is omitted, it defaults to `00:00:00`.
4///
5/// Unfortunately, using this macro with properly formatted dates like `2022-09-22` triggers the clippy lint `zero_prefixed_literal` for every leading zero (e.g. in `09`).
6///```
7/// use greg::ymd_hms;
8/// use greg::calendar::{DateTime, Date, Time};
9/// let dt1: DateTime = ymd_hms!(2022-09-22);
10/// let DateTime(date, time) = dt1;
11/// assert_eq!(date, Date::ymd(2022, 9, 22));
12/// assert_eq!(time, Time::MIDNIGHT);
13///
14/// let DateTime(date2, time2) = ymd_hms!(2022-09-22 03:00:00);
15/// assert_eq!(date, date2);
16/// assert_eq!(time2, Time::hms_checked(3, 0, 0));
17///```
18#[macro_export]
19macro_rules! ymd_hms {
20	($y:literal-$mo:literal-$d:literal $h:literal:$m:literal:$s:literal) => {
21		$crate::calendar::DateTime (
22			$crate::calendar::Date::ymd_checked($y, $mo, $d),
23			$crate::calendar::Time::hms_checked($h, $m, $s)
24		)
25	};
26	($y:literal-$mo:literal-$d:literal) => {
27		$crate::calendar::DateTime (
28			$crate::calendar::Date::ymd_checked($y, $mo, $d),
29			$crate::calendar::Time::MIDNIGHT
30		)
31	};
32}
33/// Create a [`Point`](crate::Point) from `YYYY-MM-DD hh:mm:ss` in UTC
34///
35/// If the `hh:mm:ss` time component is omitted, it defaults to `00:00:00`.
36///
37/// Unfortunately, using this macro with properly formatted dates like `2022-09-22` triggers the clippy lint `zero_prefixed_literal` for every leading zero (e.g. in `09`).
38///```
39/// use greg::{utc, Point, Span};
40/// let p1: Point = utc!(2022-09-22);
41/// let p2: Point = utc!(2022-09-22 03:00:00);
42/// let three_hours = Span::HOUR * 3;
43/// assert_eq!(p1 + three_hours, p2);
44///```
45#[macro_export]
46macro_rules! utc {
47	($y:literal-$mo:literal-$d:literal $h:literal:$m:literal:$s:literal) => {
48		$crate::calendar::Utc::resolve(
49			$crate::ymd_hms!($y-$mo-$d $h:$m:$s)
50		)
51	};
52	($y:literal-$mo:literal-$d:literal) => {
53		$crate::calendar::Utc::resolve(
54			$crate::ymd_hms!($y-$mo-$d)
55		)
56	};
57}
58
59#[test]
60fn ymd_hms() {
61	use super::{DateTime, Date, Time};
62	let DateTime(date, time) = ymd_hms!(2020-01-01 00:00:00);
63	assert_eq!(date, Date::ymd(2020, 1, 1));
64	assert_eq!(time, Time::MIDNIGHT);
65	let DateTime(date, time) = ymd_hms!(2020-01-01);
66	assert_eq!(date, Date::ymd(2020, 1, 1));
67	assert_eq!(time, Time::MIDNIGHT);
68}
69
70#[test]
71fn utc() {
72	assert_eq!(0, utc!(1970-01-01).timestamp);
73	assert_eq!(0, utc!(1970-01-01 00:00:00).timestamp);
74
75	assert_eq!(1514764800, utc!(2018-01-01).timestamp);
76	assert_eq!(1514764800, utc!(2018-01-01 00:00:00).timestamp);
77
78	assert_eq!(1641168000, utc!(2022-01-03).timestamp);
79	assert_eq!(1641168000, utc!(2022-01-03 00:00:00).timestamp);
80
81	assert_eq!(1582934400, utc!(2020-02-29).timestamp);
82	assert_eq!(1582934400, utc!(2020-02-29 00:00:00).timestamp);
83
84	assert_eq!(1583020800, utc!(2020-03-01).timestamp);
85	assert_eq!(1583020800, utc!(2020-03-01 00:00:00).timestamp);
86}