1use super::Zone;
8use crate::prelude::*;
9use chrono::{Datelike, TimeZone};
10
11#[derive(Clone, Copy, Eq, From, Into, Ord, PartialEq, PartialOrd)]
12pub struct Date(chrono::NaiveDate);
13
14impl Date {
15 pub fn from_ymd(year: isize, month: usize, day: usize) -> Self {
17 Self(chrono::NaiveDate::from_ymd(year as i32, month as u32, day as u32))
18 }
19
20 pub fn and_hms(&self, hour: usize, minute: usize, second: usize, zone: Zone) -> Time {
23 let inner = match &zone {
24 Zone::Local => chrono::Local
25 .from_local_date(&self.0)
26 .and_hms_opt(hour as u32, minute as u32, second as u32)
27 .unwrap()
28 .with_timezone(&chrono::Utc),
29
30 Zone::Tz(tz) => tz
31 .from_local_date(&self.0)
32 .and_hms_opt(hour as u32, minute as u32, second as u32)
33 .unwrap()
34 .with_timezone(&chrono::Utc),
35 };
36
37 Time { inner, zone }
38 }
39
40 pub fn day(&self) -> usize {
42 self.0.day() as usize
43 }
44
45 pub fn format<'a>(&self, fmt: &'a str) -> impl Display + 'a {
47 self.0.format(fmt)
48 }
49
50 pub fn month(&self) -> usize {
52 self.0.month() as usize
53 }
54
55 pub fn next(&self) -> Self {
57 Self(self.0.succ())
58 }
59
60 pub fn prev(&self) -> Self {
62 Self(self.0.pred())
63 }
64
65 pub fn to_local_time(&self) -> Time {
67 self.to_time(super::LOCAL)
68 }
69
70 pub fn to_time(&self, zone: Zone) -> Time {
72 self.and_hms(0, 0, 0, zone)
73 }
74
75 pub fn to_utc_time(&self) -> Time {
77 self.to_time(super::UTC)
78 }
79
80 pub fn year(&self) -> isize {
82 self.0.year() as isize
83 }
84
85 pub fn ymd(&self) -> (isize, usize, usize) {
89 (self.year(), self.month(), self.day())
90 }
91}
92
93impl Debug for Date {
96 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
97 write!(f, "\"{}\"", self.format("%F"))
98 }
99}
100
101impl Display for Date {
102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 write!(f, "{}", self.format("%v"))
104 }
105}
106
107cfg_if! {
110 if #[cfg(feature = "postgres")] {
111 use postgres_types as pg;
112
113 impl<'a> pg::FromSql<'a> for Date {
114 fn from_sql(ty: &pg::Type, raw: &'a [u8]) -> Result<Self, Box<dyn Error + Sync + Send>>{
115 Ok(Self(pg::FromSql::from_sql(ty, raw)?))
116 }
117
118 fn accepts(ty: &pg::Type) -> bool {
119 <chrono::NaiveDate as pg::FromSql>::accepts(ty)
120 }
121 }
122
123 impl pg::ToSql for Date {
124 fn to_sql(&self, ty: &pg::Type, out: &mut bytes::BytesMut) -> Result<pg::IsNull, Box<dyn Error + Sync + Send>>
125 where
126 Self: Sized,
127 {
128 self.0.to_sql(ty, out)
129 }
130
131 fn accepts(ty: &pg::Type) -> bool
132 where
133 Self: Sized,
134 {
135 <chrono::NaiveDate as pg::ToSql>::accepts(ty)
136 }
137
138 fn to_sql_checked(&self, ty: &pg::Type, out: &mut bytes::BytesMut) -> Result<pg::IsNull, Box<dyn Error + Sync + Send>> {
139 self.0.to_sql_checked(ty, out)
140 }
141 }
142 }
143}