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