1extern crate time;
5
6use self::time::{
7 Date as NaiveDate, OffsetDateTime, PrimitiveDateTime, Time as NaiveTime, UtcOffset,
8 error::ComponentRange, macros::format_description,
9};
10#[allow(deprecated)]
12use self::time::format_description::FormatItem;
13
14use crate::backend::Backend;
15use crate::deserialize::{self, FromSql};
16use crate::serialize::{self, IsNull, Output, ToSql};
17use crate::sql_types::{Date, Time, Timestamp, TimestamptzSqlite};
18use crate::sqlite::Sqlite;
19
20#[allow(deprecated)]
29const DATE_FORMAT: &[FormatItem<'_>] = const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}] as StaticFormatDescription
}format_description!("[year]-[month]-[day]");
30
31#[allow(deprecated)]
33const ENCODE_TIME_FORMAT_WHOLE_SECOND: &[FormatItem<'_>] =
34 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}] as StaticFormatDescription
}format_description!("[hour]:[minute]:[second]");
35
36#[allow(deprecated)]
38const ENCODE_TIME_FORMAT_SUBSECOND: &[FormatItem<'_>] =
39 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"."),
BorrowedFormatItem::Component {
0: Component::Subsecond(Subsecond::default()),
}] as StaticFormatDescription
}format_description!("[hour]:[minute]:[second].[subsecond]");
40
41#[allow(deprecated)]
43const TIME_FORMATS: [&[FormatItem<'_>]; 9] = [
44 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"."),
BorrowedFormatItem::Component {
0: Component::Subsecond(Subsecond::default()),
}] as StaticFormatDescription
}format_description!("[hour]:[minute]:[second].[subsecond]"),
46 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}] as StaticFormatDescription
}format_description!("[hour]:[minute]:[second]"),
47 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}] as StaticFormatDescription
}format_description!("[hour]:[minute]"),
49 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b"Z")] as
StaticFormatDescription
}format_description!("[hour]:[minute]Z"),
50 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
},
BorrowedFormatItem::Component {
0: Component::OffsetHour({
OffsetHour::default().with_sign_is_mandatory(true)
}),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::OffsetMinute(OffsetMinute::default()),
}] as StaticFormatDescription
}format_description!("[hour]:[minute][offset_hour sign:mandatory]:[offset_minute]"),
51 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"Z")] as
StaticFormatDescription
}format_description!("[hour]:[minute]:[second]Z"),
52 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
},
BorrowedFormatItem::Component {
0: Component::OffsetHour({
OffsetHour::default().with_sign_is_mandatory(true)
}),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::OffsetMinute(OffsetMinute::default()),
}] as StaticFormatDescription
}format_description!("[hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]"),
53 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"."),
BorrowedFormatItem::Component {
0: Component::Subsecond(Subsecond::default()),
}, BorrowedFormatItem::Literal(b"Z")] as
StaticFormatDescription
}format_description!("[hour]:[minute]:[second].[subsecond]Z"),
54 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"."),
BorrowedFormatItem::Component {
0: Component::Subsecond(Subsecond::default()),
},
BorrowedFormatItem::Component {
0: Component::OffsetHour({
OffsetHour::default().with_sign_is_mandatory(true)
}),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::OffsetMinute(OffsetMinute::default()),
}] as StaticFormatDescription
}format_description!(
55 "[hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]:[offset_minute]"
56 ),
57];
58
59#[allow(deprecated)]
61const ENCODE_PRIMITIVE_DATETIME_FORMAT_WHOLE_SECOND: &[FormatItem<'_>] =
62 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}] as StaticFormatDescription
}format_description!("[year]-[month]-[day] [hour]:[minute]:[second]");
63
64#[allow(deprecated)]
66const ENCODE_PRIMITIVE_DATETIME_FORMAT_SUBSECOND: &[FormatItem<'_>] =
67 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"."),
BorrowedFormatItem::Component {
0: Component::Subsecond(Subsecond::default()),
}] as StaticFormatDescription
}format_description!("[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]");
68
69#[allow(deprecated)]
71const ENCODE_DATETIME_FORMAT_WHOLE_SECOND: &[FormatItem<'_>] = const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
},
BorrowedFormatItem::Component {
0: Component::OffsetHour({
OffsetHour::default().with_sign_is_mandatory(true)
}),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::OffsetMinute(OffsetMinute::default()),
}] as StaticFormatDescription
}format_description!(
72 "[year]-[month]-[day] [hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]"
73);
74
75#[allow(deprecated)]
77const ENCODE_DATETIME_FORMAT_SUBSECOND: &[FormatItem<'_>] = const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"."),
BorrowedFormatItem::Component {
0: Component::Subsecond(Subsecond::default()),
},
BorrowedFormatItem::Component {
0: Component::OffsetHour({
OffsetHour::default().with_sign_is_mandatory(true)
}),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::OffsetMinute(OffsetMinute::default()),
}] as StaticFormatDescription
}format_description!(
78 "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]:[offset_minute]"
79);
80
81#[allow(deprecated)]
83const PRIMITIVE_DATETIME_FORMATS: [&[FormatItem<'_>]; 18] = [
84 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"."),
BorrowedFormatItem::Component {
0: Component::Subsecond(Subsecond::default()),
}] as StaticFormatDescription
}format_description!("[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]"),
86 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"."),
BorrowedFormatItem::Component {
0: Component::Subsecond(Subsecond::default()),
},
BorrowedFormatItem::Component {
0: Component::OffsetHour({
OffsetHour::default().with_sign_is_mandatory(true)
}),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::OffsetMinute(OffsetMinute::default()),
}] as StaticFormatDescription
}format_description!(
87 "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]:[offset_minute]"
88 ),
89 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}] as StaticFormatDescription
}format_description!("[year]-[month]-[day] [hour]:[minute]:[second]"),
90 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
},
BorrowedFormatItem::Component {
0: Component::OffsetHour({
OffsetHour::default().with_sign_is_mandatory(true)
}),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::OffsetMinute(OffsetMinute::default()),
}] as StaticFormatDescription
}format_description!(
91 "[year]-[month]-[day] [hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]"
92 ),
93 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}] as StaticFormatDescription
}format_description!("[year]-[month]-[day] [hour]:[minute]"),
95 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b"Z")] as
StaticFormatDescription
}format_description!("[year]-[month]-[day] [hour]:[minute]Z"),
96 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
},
BorrowedFormatItem::Component {
0: Component::OffsetHour({
OffsetHour::default().with_sign_is_mandatory(true)
}),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::OffsetMinute(OffsetMinute::default()),
}] as StaticFormatDescription
}format_description!(
97 "[year]-[month]-[day] [hour]:[minute][offset_hour sign:mandatory]:[offset_minute]"
98 ),
99 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"Z")] as
StaticFormatDescription
}format_description!("[year]-[month]-[day] [hour]:[minute]:[second]Z"),
100 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"."),
BorrowedFormatItem::Component {
0: Component::Subsecond(Subsecond::default()),
}, BorrowedFormatItem::Literal(b"Z")] as
StaticFormatDescription
}format_description!("[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]Z"),
101 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b"T"),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}] as StaticFormatDescription
}format_description!("[year]-[month]-[day]T[hour]:[minute]"),
102 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b"T"),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b"Z")] as
StaticFormatDescription
}format_description!("[year]-[month]-[day]T[hour]:[minute]Z"),
103 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b"T"),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
},
BorrowedFormatItem::Component {
0: Component::OffsetHour({
OffsetHour::default().with_sign_is_mandatory(true)
}),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::OffsetMinute(OffsetMinute::default()),
}] as StaticFormatDescription
}format_description!(
104 "[year]-[month]-[day]T[hour]:[minute][offset_hour sign:mandatory]:[offset_minute]"
105 ),
106 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b"T"),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}] as StaticFormatDescription
}format_description!("[year]-[month]-[day]T[hour]:[minute]:[second]"),
107 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b"T"),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"Z")] as
StaticFormatDescription
}format_description!("[year]-[month]-[day]T[hour]:[minute]:[second]Z"),
108 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b"T"),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
},
BorrowedFormatItem::Component {
0: Component::OffsetHour({
OffsetHour::default().with_sign_is_mandatory(true)
}),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::OffsetMinute(OffsetMinute::default()),
}] as StaticFormatDescription
}format_description!(
109 "[year]-[month]-[day]T[hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]"
110 ),
111 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b"T"),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"."),
BorrowedFormatItem::Component {
0: Component::Subsecond(Subsecond::default()),
}] as StaticFormatDescription
}format_description!("[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond]"),
112 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b"T"),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"."),
BorrowedFormatItem::Component {
0: Component::Subsecond(Subsecond::default()),
}, BorrowedFormatItem::Literal(b"Z")] as
StaticFormatDescription
}format_description!("[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond]Z"),
113 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b"T"),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"."),
BorrowedFormatItem::Component {
0: Component::Subsecond(Subsecond::default()),
},
BorrowedFormatItem::Component {
0: Component::OffsetHour({
OffsetHour::default().with_sign_is_mandatory(true)
}),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::OffsetMinute(OffsetMinute::default()),
}] as StaticFormatDescription
}format_description!(
114 "[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]:[offset_minute]"
115 ),
116];
117
118#[allow(deprecated)]
120const DATETIME_FORMATS: [&[FormatItem<'_>]; 12] = [
121 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"."),
BorrowedFormatItem::Component {
0: Component::Subsecond(Subsecond::default()),
},
BorrowedFormatItem::Component {
0: Component::OffsetHour({
OffsetHour::default().with_sign_is_mandatory(true)
}),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::OffsetMinute(OffsetMinute::default()),
}] as StaticFormatDescription
}format_description!(
123 "[year]-[month]-[day] [hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]:[offset_minute]"
124 ),
125 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
},
BorrowedFormatItem::Component {
0: Component::OffsetHour({
OffsetHour::default().with_sign_is_mandatory(true)
}),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::OffsetMinute(OffsetMinute::default()),
}] as StaticFormatDescription
}format_description!(
126 "[year]-[month]-[day] [hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]"
127 ),
128 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b"Z")] as
StaticFormatDescription
}format_description!("[year]-[month]-[day] [hour]:[minute]Z"),
130 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
},
BorrowedFormatItem::Component {
0: Component::OffsetHour({
OffsetHour::default().with_sign_is_mandatory(true)
}),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::OffsetMinute(OffsetMinute::default()),
}] as StaticFormatDescription
}format_description!(
131 "[year]-[month]-[day] [hour]:[minute][offset_hour sign:mandatory]:[offset_minute]"
132 ),
133 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"Z")] as
StaticFormatDescription
}format_description!("[year]-[month]-[day] [hour]:[minute]:[second]Z"),
134 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b" "),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"."),
BorrowedFormatItem::Component {
0: Component::Subsecond(Subsecond::default()),
}, BorrowedFormatItem::Literal(b"Z")] as
StaticFormatDescription
}format_description!("[year]-[month]-[day] [hour]:[minute]:[second].[subsecond]Z"),
135 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b"T"),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b"Z")] as
StaticFormatDescription
}format_description!("[year]-[month]-[day]T[hour]:[minute]Z"),
136 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b"T"),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
},
BorrowedFormatItem::Component {
0: Component::OffsetHour({
OffsetHour::default().with_sign_is_mandatory(true)
}),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::OffsetMinute(OffsetMinute::default()),
}] as StaticFormatDescription
}format_description!(
137 "[year]-[month]-[day]T[hour]:[minute][offset_hour sign:mandatory]:[offset_minute]"
138 ),
139 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b"T"),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"Z")] as
StaticFormatDescription
}format_description!("[year]-[month]-[day]T[hour]:[minute]:[second]Z"),
140 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b"T"),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
},
BorrowedFormatItem::Component {
0: Component::OffsetHour({
OffsetHour::default().with_sign_is_mandatory(true)
}),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::OffsetMinute(OffsetMinute::default()),
}] as StaticFormatDescription
}format_description!(
141 "[year]-[month]-[day]T[hour]:[minute]:[second][offset_hour sign:mandatory]:[offset_minute]"
142 ),
143 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b"T"),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"."),
BorrowedFormatItem::Component {
0: Component::Subsecond(Subsecond::default()),
}, BorrowedFormatItem::Literal(b"Z")] as
StaticFormatDescription
}format_description!("[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond]Z"),
144 const {
use ::time::format_description::{*, modifier::*};
&[BorrowedFormatItem::Component {
0: Component::Year(Year::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Month(Month::default()),
}, BorrowedFormatItem::Literal(b"-"),
BorrowedFormatItem::Component {
0: Component::Day(Day::default()),
}, BorrowedFormatItem::Literal(b"T"),
BorrowedFormatItem::Component {
0: Component::Hour(Hour::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Minute(Minute::default()),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::Second(Second::default()),
}, BorrowedFormatItem::Literal(b"."),
BorrowedFormatItem::Component {
0: Component::Subsecond(Subsecond::default()),
},
BorrowedFormatItem::Component {
0: Component::OffsetHour({
OffsetHour::default().with_sign_is_mandatory(true)
}),
}, BorrowedFormatItem::Literal(b":"),
BorrowedFormatItem::Component {
0: Component::OffsetMinute(OffsetMinute::default()),
}] as StaticFormatDescription
}format_description!(
145 "[year]-[month]-[day]T[hour]:[minute]:[second].[subsecond][offset_hour sign:mandatory]:[offset_minute]"
146 ),
147];
148
149fn naive_utc(dt: OffsetDateTime) -> PrimitiveDateTime {
150 let dt = dt.to_offset(UtcOffset::UTC);
151 PrimitiveDateTime::new(dt.date(), dt.time())
152}
153
154fn parse_julian(julian_days: f64) -> Result<PrimitiveDateTime, ComponentRange> {
155 const EPOCH_IN_JULIAN_DAYS: f64 = 2_440_587.5;
156 const SECONDS_IN_DAY: f64 = 86400.0;
157 let timestamp = (julian_days - EPOCH_IN_JULIAN_DAYS) * SECONDS_IN_DAY;
158 #[allow(clippy::cast_possible_truncation)] OffsetDateTime::from_unix_timestamp_nanos((timestamp * 1E9) as i128).map(naive_utc)
160}
161
162#[cfg(all(feature = "__sqlite-shared", feature = "time"))]
163impl FromSql<Date, Sqlite> for NaiveDate {
164 fn from_sql(mut value: <Sqlite as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
165 value
166 .parse_string(|s| Self::parse(s, DATE_FORMAT))
167 .map_err(Into::into)
168 }
169}
170
171#[cfg(all(feature = "__sqlite-shared", feature = "time"))]
172impl ToSql<Date, Sqlite> for NaiveDate {
173 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
174 out.set_value(self.format(DATE_FORMAT).map_err(|err| err.to_string())?);
175 Ok(IsNull::No)
176 }
177}
178
179#[cfg(all(feature = "__sqlite-shared", feature = "time"))]
180impl FromSql<Time, Sqlite> for NaiveTime {
181 fn from_sql(mut value: <Sqlite as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
182 value.parse_string(|text| {
183 for format in TIME_FORMATS {
184 if let Ok(time) = Self::parse(text, format) {
185 return Ok(time);
186 }
187 }
188
189 Err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Invalid time {0}", text))
})format!("Invalid time {text}").into())
190 })
191 }
192}
193
194#[cfg(all(feature = "__sqlite-shared", feature = "time"))]
195impl ToSql<Time, Sqlite> for NaiveTime {
196 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
197 let format = if self.microsecond() == 0 {
198 ENCODE_TIME_FORMAT_WHOLE_SECOND
199 } else {
200 ENCODE_TIME_FORMAT_SUBSECOND
201 };
202 out.set_value(self.format(format).map_err(|err| err.to_string())?);
203 Ok(IsNull::No)
204 }
205}
206
207#[cfg(all(feature = "__sqlite-shared", feature = "time"))]
208impl FromSql<Timestamp, Sqlite> for PrimitiveDateTime {
209 fn from_sql(mut value: <Sqlite as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
210 value.parse_string(|text| {
211 for format in PRIMITIVE_DATETIME_FORMATS {
212 if let Ok(dt) = Self::parse(text, format) {
213 return Ok(dt);
214 }
215 }
216
217 if let Ok(julian_days) = text.parse::<f64>()
218 && let Ok(timestamp) = parse_julian(julian_days)
219 {
220 return Ok(timestamp);
221 }
222
223 Err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Invalid datetime {0}", text))
})format!("Invalid datetime {text}").into())
224 })
225 }
226}
227
228#[cfg(all(feature = "__sqlite-shared", feature = "time"))]
229impl ToSql<Timestamp, Sqlite> for PrimitiveDateTime {
230 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
231 let format = if self.nanosecond() == 0 {
232 ENCODE_PRIMITIVE_DATETIME_FORMAT_WHOLE_SECOND
233 } else {
234 ENCODE_PRIMITIVE_DATETIME_FORMAT_SUBSECOND
235 };
236 out.set_value(self.format(format).map_err(|err| err.to_string())?);
237 Ok(IsNull::No)
238 }
239}
240
241#[cfg(all(feature = "__sqlite-shared", feature = "time"))]
242impl FromSql<TimestamptzSqlite, Sqlite> for PrimitiveDateTime {
243 fn from_sql(mut value: <Sqlite as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
244 value.parse_string(|text| {
245 for format in PRIMITIVE_DATETIME_FORMATS {
246 if let Ok(dt) = Self::parse(text, format) {
247 return Ok(dt);
248 }
249 }
250
251 if let Ok(julian_days) = text.parse::<f64>()
252 && let Ok(timestamp) = parse_julian(julian_days)
253 {
254 return Ok(timestamp);
255 }
256
257 Err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Invalid datetime {0}", text))
})format!("Invalid datetime {text}").into())
258 })
259 }
260}
261
262#[cfg(all(feature = "__sqlite-shared", feature = "time"))]
263impl ToSql<TimestamptzSqlite, Sqlite> for PrimitiveDateTime {
264 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
265 let format = if self.nanosecond() == 0 {
266 ENCODE_PRIMITIVE_DATETIME_FORMAT_WHOLE_SECOND
267 } else {
268 ENCODE_PRIMITIVE_DATETIME_FORMAT_SUBSECOND
269 };
270 out.set_value(self.format(format).map_err(|err| err.to_string())?);
271 Ok(IsNull::No)
272 }
273}
274
275#[cfg(all(feature = "__sqlite-shared", feature = "time"))]
276impl FromSql<TimestamptzSqlite, Sqlite> for OffsetDateTime {
277 fn from_sql(mut value: <Sqlite as Backend>::RawValue<'_>) -> deserialize::Result<Self> {
278 if let Ok(dt) = value.parse_string(|text| {
280 for format in DATETIME_FORMATS {
281 if let Ok(dt) = OffsetDateTime::parse(text, format) {
282 return Ok(dt);
283 }
284 }
285
286 Err(())
287 }) {
288 return Ok(dt);
289 }
290
291 let primitive_date_time =
293 <PrimitiveDateTime as FromSql<TimestamptzSqlite, Sqlite>>::from_sql(value)?;
294 Ok(primitive_date_time.assume_utc())
295 }
296}
297
298#[cfg(all(feature = "__sqlite-shared", feature = "time"))]
299impl ToSql<TimestamptzSqlite, Sqlite> for OffsetDateTime {
300 fn to_sql<'b>(&'b self, out: &mut Output<'b, '_, Sqlite>) -> serialize::Result {
301 let dt_utc = self.to_offset(UtcOffset::UTC);
303 let format = if self.nanosecond() == 0 {
304 ENCODE_DATETIME_FORMAT_WHOLE_SECOND
305 } else {
306 ENCODE_DATETIME_FORMAT_SUBSECOND
307 };
308 out.set_value(dt_utc.format(format).map_err(|err| err.to_string())?);
309 Ok(IsNull::No)
310 }
311}
312
313#[cfg(all(test, not(all(target_family = "wasm", target_os = "unknown"))))]
314mod tests {
315 extern crate dotenvy;
316
317 use super::time::{
318 Date as NaiveDate, Duration, OffsetDateTime, PrimitiveDateTime, Time as NaiveTime,
319 macros::{date, datetime},
320 };
321
322 use super::naive_utc;
323
324 use crate::dsl::{now, sql};
325 use crate::prelude::*;
326 use crate::select;
327 use crate::sql_types::{Text, Time, Timestamp, TimestamptzSqlite};
328 use crate::test_helpers::connection;
329
330 #[declare_sql_function]
331 extern "SQL" {
332 fn datetime(x: Text) -> Timestamp;
333 fn time(x: Text) -> Time;
334 fn date(x: Text) -> Date;
335 }
336
337 #[diesel_test_helper::test]
338 fn unix_epoch_encodes_correctly() {
339 let connection = &mut connection();
340 let time = datetime!(1970-1-1 0:0:0);
341 let query = select(datetime("1970-01-01 00:00:00.000000").eq(time));
342 assert_eq!(Ok(true), query.get_result(connection));
343 }
344
345 #[diesel_test_helper::test]
346 fn unix_epoch_decodes_correctly_in_all_possible_formats() {
347 let connection = &mut connection();
348 let time = datetime!(1970-1-1 0:0:0);
349 let valid_epoch_formats = vec![
350 "1970-01-01 00:00",
351 "1970-01-01 00:00:00",
352 "1970-01-01 00:00:00.000",
353 "1970-01-01 00:00:00.000000",
354 "1970-01-01T00:00",
355 "1970-01-01T00:00:00",
356 "1970-01-01T00:00:00.000",
357 "1970-01-01T00:00:00.000000",
358 "1970-01-01 00:00Z",
359 "1970-01-01 00:00:00Z",
360 "1970-01-01 00:00:00.000Z",
361 "1970-01-01 00:00:00.000000Z",
362 "1970-01-01T00:00Z",
363 "1970-01-01T00:00:00Z",
364 "1970-01-01T00:00:00.000Z",
365 "1970-01-01T00:00:00.000000Z",
366 "1970-01-01 00:00+00:00",
367 "1970-01-01 00:00:00+00:00",
368 "1970-01-01 00:00:00.000+00:00",
369 "1970-01-01 00:00:00.000000+00:00",
370 "1970-01-01T00:00+00:00",
371 "1970-01-01T00:00:00+00:00",
372 "1970-01-01T00:00:00.000+00:00",
373 "1970-01-01T00:00:00.000000+00:00",
374 "1970-01-01 00:00+01:00",
375 "1970-01-01 00:00:00+01:00",
376 "1970-01-01 00:00:00.000+01:00",
377 "1970-01-01 00:00:00.000000+01:00",
378 "1970-01-01T00:00+01:00",
379 "1970-01-01T00:00:00+01:00",
380 "1970-01-01T00:00:00.000+01:00",
381 "1970-01-01T00:00:00.000000+01:00",
382 "1970-01-01T00:00-01:00",
383 "1970-01-01T00:00:00-01:00",
384 "1970-01-01T00:00:00.000-01:00",
385 "1970-01-01T00:00:00.000000-01:00",
386 "1970-01-01T00:00-01:00",
387 "1970-01-01T00:00:00-01:00",
388 "1970-01-01T00:00:00.000-01:00",
389 "1970-01-01T00:00:00.000000-01:00",
390 "2440587.5",
391 ];
392
393 for s in valid_epoch_formats {
394 let epoch_from_sql = select(sql::<Timestamp>(&format!("'{s}'"))).get_result(connection);
395 assert_eq!(Ok(time), epoch_from_sql, "format {s} failed");
396 }
397 }
398
399 #[diesel_test_helper::test]
400 fn times_relative_to_now_encode_correctly() {
401 let connection = &mut connection();
402 let time = naive_utc(OffsetDateTime::now_utc()) + Duration::seconds(60);
403 let query = select(now.lt(time));
404 assert_eq!(Ok(true), query.get_result(connection));
405
406 let time = naive_utc(OffsetDateTime::now_utc()) - Duration::seconds(600);
407 let query = select(now.gt(time));
408 assert_eq!(Ok(true), query.get_result(connection));
409 }
410
411 #[diesel_test_helper::test]
412 fn times_of_day_encode_correctly() {
413 let connection = &mut connection();
414
415 let midnight = NaiveTime::from_hms(0, 0, 0).unwrap();
416 let query = select(time("00:00:00").eq(midnight));
417 assert!(query.get_result::<bool>(connection).unwrap());
418
419 let noon = NaiveTime::from_hms(12, 0, 0).unwrap();
420 let query = select(time("12:00:00").eq(noon));
421 assert!(query.get_result::<bool>(connection).unwrap());
422
423 let roughly_half_past_eleven = NaiveTime::from_hms_micro(23, 37, 4, 2200).unwrap();
424 let query = select(sql::<Time>("'23:37:04.0022'").eq(roughly_half_past_eleven));
425 assert!(query.get_result::<bool>(connection).unwrap());
426 }
427
428 #[diesel_test_helper::test]
429 fn times_of_day_decode_correctly() {
430 let connection = &mut connection();
431 let midnight = NaiveTime::from_hms(0, 0, 0).unwrap();
432 let valid_midnight_formats = &[
433 "00:00",
434 "00:00:00",
435 "00:00:00.000",
436 "00:00:00.000000",
437 "00:00Z",
438 "00:00:00Z",
439 "00:00:00.000Z",
440 "00:00:00.000000Z",
441 "00:00+00:00",
442 "00:00:00+00:00",
443 "00:00:00.000+00:00",
444 "00:00:00.000000+00:00",
445 "00:00+01:00",
446 "00:00:00+01:00",
447 "00:00:00.000+01:00",
448 "00:00:00.000000+01:00",
449 "00:00-01:00",
450 "00:00:00-01:00",
451 "00:00:00.000-01:00",
452 "00:00:00.000000-01:00",
453 ];
454 for format in valid_midnight_formats {
455 let query = select(sql::<Time>(&format!("'{format}'")));
456 assert_eq!(
457 Ok(midnight),
458 query.get_result::<NaiveTime>(connection),
459 "format {format} failed"
460 );
461 }
462
463 let noon = NaiveTime::from_hms(12, 0, 0).unwrap();
464 let query = select(sql::<Time>("'12:00:00'"));
465 assert_eq!(Ok(noon), query.get_result::<NaiveTime>(connection));
466
467 let roughly_half_past_eleven = NaiveTime::from_hms_micro(23, 37, 4, 2200).unwrap();
468 let query = select(sql::<Time>("'23:37:04.002200'"));
469 assert_eq!(
470 Ok(roughly_half_past_eleven),
471 query.get_result::<NaiveTime>(connection)
472 );
473 }
474
475 #[diesel_test_helper::test]
476 fn dates_encode_correctly() {
477 let connection = &mut connection();
478 let january_first_2000 = date!(2000 - 1 - 1);
479 let query = select(date("2000-01-01").eq(january_first_2000));
480 assert!(query.get_result::<bool>(connection).unwrap());
481
482 let distant_past = date!(0 - 4 - 11);
483 let query = select(date("0000-04-11").eq(distant_past));
484 assert!(query.get_result::<bool>(connection).unwrap());
485
486 let january_first_2018 = date!(2018 - 1 - 1);
487 let query = select(date("2018-01-01").eq(january_first_2018));
488 assert!(query.get_result::<bool>(connection).unwrap());
489
490 let distant_future = date!(9999 - 1 - 8);
491 let query = select(date("9999-01-08").eq(distant_future));
492 assert!(query.get_result::<bool>(connection).unwrap());
493 }
494
495 #[diesel_test_helper::test]
496 fn dates_decode_correctly() {
497 let connection = &mut connection();
498 let january_first_2000 = date!(2000 - 1 - 1);
499 let query = select(date("2000-01-01"));
500 assert_eq!(
501 Ok(january_first_2000),
502 query.get_result::<NaiveDate>(connection)
503 );
504
505 let distant_past = date!(0 - 4 - 11);
506 let query = select(date("0000-04-11"));
507 assert_eq!(Ok(distant_past), query.get_result::<NaiveDate>(connection));
508
509 let january_first_2018 = date!(2018 - 1 - 1);
510 let query = select(date("2018-01-01"));
511 assert_eq!(
512 Ok(january_first_2018),
513 query.get_result::<NaiveDate>(connection)
514 );
515
516 let distant_future = date!(9999 - 1 - 8);
517 let query = select(date("9999-01-08"));
518 assert_eq!(
519 Ok(distant_future),
520 query.get_result::<NaiveDate>(connection)
521 );
522 }
523
524 #[diesel_test_helper::test]
525 fn datetimes_decode_correctly() {
526 let connection = &mut connection();
527 let january_first_2000 = datetime!(2000-1-1 1:1:1);
528 let query = select(datetime("2000-01-01 01:01:01.000000"));
529 assert_eq!(
530 Ok(january_first_2000),
531 query.get_result::<PrimitiveDateTime>(connection)
532 );
533
534 let distant_past = datetime!(0-4-11 2:2:2);
535 let query = select(datetime("0000-04-11 02:02:02.000000"));
536 assert_eq!(
537 Ok(distant_past),
538 query.get_result::<PrimitiveDateTime>(connection)
539 );
540
541 let january_first_2018 = date!(2018 - 1 - 1);
542 let query = select(date("2018-01-01"));
543 assert_eq!(
544 Ok(january_first_2018),
545 query.get_result::<NaiveDate>(connection)
546 );
547
548 let distant_future = datetime!(9999 - 1 - 8 23:59:59.0001);
549 let query = select(sql::<Timestamp>("'9999-01-08 23:59:59.000100'"));
550 assert_eq!(
551 Ok(distant_future),
552 query.get_result::<PrimitiveDateTime>(connection)
553 );
554 }
555
556 #[diesel_test_helper::test]
557 fn datetimes_encode_correctly() {
558 let connection = &mut connection();
559 let january_first_2000 = datetime!(2000-1-1 0:0:0);
560 let query = select(datetime("2000-01-01 00:00:00").eq(january_first_2000));
561 assert!(query.get_result::<bool>(connection).unwrap());
562
563 let distant_past = datetime!(0-4-11 20:00:20);
564 let query = select(datetime("0000-04-11 20:00:20").eq(distant_past));
565 assert!(query.get_result::<bool>(connection).unwrap());
566
567 let january_first_2018 = datetime!(2018 - 1 - 1 12:00:00.0005);
568 let query = select(sql::<Timestamp>("'2018-01-01 12:00:00.0005'").eq(january_first_2018));
569 assert!(query.get_result::<bool>(connection).unwrap());
570
571 let distant_future = datetime!(9999-1-8 0:0:0);
572 let query = select(datetime("9999-01-08 00:00:00").eq(distant_future));
573 assert!(query.get_result::<bool>(connection).unwrap());
574 }
575
576 #[diesel_test_helper::test]
577 fn insert_timestamptz_into_table_as_text() {
578 crate::table! {
579 #[allow(unused_parens)]
580 test_insert_timestamptz_into_table_as_text(id) {
581 id -> Integer,
582 timestamp_with_tz -> TimestamptzSqlite,
583 }
584 }
585 let conn = &mut connection();
586 crate::sql_query(
587 "CREATE TABLE test_insert_timestamptz_into_table_as_text(id INTEGER PRIMARY KEY, timestamp_with_tz TEXT);",
588 )
589 .execute(conn)
590 .unwrap();
591
592 let time: OffsetDateTime = datetime!(1970-1-1 0:0:0.0 utc);
593
594 crate::insert_into(test_insert_timestamptz_into_table_as_text::table)
595 .values(vec![(
596 test_insert_timestamptz_into_table_as_text::id.eq(1),
597 test_insert_timestamptz_into_table_as_text::timestamp_with_tz.eq(sql::<
598 TimestamptzSqlite,
599 >(
600 "'1970-01-01 00:00:00.000000+00:00'",
601 )),
602 )])
603 .execute(conn)
604 .unwrap();
605
606 let result = test_insert_timestamptz_into_table_as_text::table
607 .select(test_insert_timestamptz_into_table_as_text::timestamp_with_tz)
608 .get_result::<OffsetDateTime>(conn)
609 .unwrap();
610 assert_eq!(result, time);
611 }
612
613 #[diesel_test_helper::test]
614 fn can_query_timestamptz_column_with_between() {
615 crate::table! {
616 #[allow(unused_parens)]
617 test_query_timestamptz_column_with_between(id) {
618 id -> Integer,
619 timestamp_with_tz -> TimestamptzSqlite,
620 }
621 }
622 let conn = &mut connection();
623 crate::sql_query(
624 "CREATE TABLE test_query_timestamptz_column_with_between(id INTEGER PRIMARY KEY, timestamp_with_tz TEXT);",
625 )
626 .execute(conn)
627 .unwrap();
628
629 crate::insert_into(test_query_timestamptz_column_with_between::table)
630 .values(vec![
631 (
632 test_query_timestamptz_column_with_between::id.eq(1),
633 test_query_timestamptz_column_with_between::timestamp_with_tz.eq(sql::<
634 TimestamptzSqlite,
635 >(
636 "'1970-01-01 00:00:01.000000+00:00'",
637 )),
638 ),
639 (
640 test_query_timestamptz_column_with_between::id.eq(2),
641 test_query_timestamptz_column_with_between::timestamp_with_tz.eq(sql::<
642 TimestamptzSqlite,
643 >(
644 "'1970-01-01 00:00:02.000000+00:00'",
645 )),
646 ),
647 (
648 test_query_timestamptz_column_with_between::id.eq(3),
649 test_query_timestamptz_column_with_between::timestamp_with_tz.eq(sql::<
650 TimestamptzSqlite,
651 >(
652 "'1970-01-01 00:00:03.000000+00:00'",
653 )),
654 ),
655 (
656 test_query_timestamptz_column_with_between::id.eq(4),
657 test_query_timestamptz_column_with_between::timestamp_with_tz.eq(sql::<
658 TimestamptzSqlite,
659 >(
660 "'1970-01-01 00:00:04.000000+00:00'",
661 )),
662 ),
663 ])
664 .execute(conn)
665 .unwrap();
666
667 let result = test_query_timestamptz_column_with_between::table
668 .select(test_query_timestamptz_column_with_between::timestamp_with_tz)
669 .filter(
670 test_query_timestamptz_column_with_between::timestamp_with_tz
671 .gt(datetime!(1970-1-1 0:0:0.0 utc)),
672 )
673 .filter(
674 test_query_timestamptz_column_with_between::timestamp_with_tz
675 .lt(datetime!(1970-1-1 0:0:4.0 utc)),
676 )
677 .count()
678 .get_result::<_>(conn);
679 assert_eq!(result, Ok(3));
680 }
681
682 #[diesel_test_helper::test]
683 fn unix_epoch_encodes_correctly_with_timezone() {
684 let connection = &mut connection();
685 let time = datetime!(1970-1-1 0:00:00.001 -1:00);
687 let query = select(sql::<TimestamptzSqlite>("'1970-01-01 01:00:00.001+00:00'").eq(time));
688 assert!(query.get_result::<bool>(connection).unwrap());
689 }
690
691 #[diesel_test_helper::test]
692 fn unix_epoch_encodes_correctly_with_utc_timezone() {
693 let connection = &mut connection();
694 let time: OffsetDateTime = datetime!(1970-1-1 0:0:0.001 utc);
695 let query = select(sql::<TimestamptzSqlite>("'1970-01-01 00:00:00.001+00:00'").eq(time));
696 assert!(query.get_result::<bool>(connection).unwrap());
697
698 let time: OffsetDateTime = datetime!(1970-1-1 0:0:0 utc);
700 let query = select(sql::<TimestamptzSqlite>("'1970-01-01 00:00:00+00:00'").eq(time));
701 assert!(query.get_result::<bool>(connection).unwrap());
702 }
703
704 #[diesel_test_helper::test]
705 fn unix_epoch_decodes_correctly_with_utc_timezone_in_all_possible_formats() {
706 let connection = &mut connection();
707 let time: OffsetDateTime = datetime!(1970-1-1 0:0:0 utc);
708 let valid_epoch_formats = vec![
709 "1970-01-01 00:00Z",
710 "1970-01-01 00:00:00Z",
711 "1970-01-01 00:00:00.000Z",
712 "1970-01-01 00:00:00.000000Z",
713 "1970-01-01T00:00Z",
714 "1970-01-01T00:00:00Z",
715 "1970-01-01T00:00:00.000Z",
716 "1970-01-01T00:00:00.000000Z",
717 "1970-01-01 00:00+00:00",
718 "1970-01-01 00:00:00+00:00",
719 "1970-01-01 00:00:00.000+00:00",
720 "1970-01-01 00:00:00.000000+00:00",
721 "1970-01-01T00:00+00:00",
722 "1970-01-01T00:00:00+00:00",
723 "1970-01-01T00:00:00.000+00:00",
724 "1970-01-01T00:00:00.000000+00:00",
725 "2440587.5",
726 ];
727
728 for s in valid_epoch_formats {
729 let epoch_from_sql =
730 select(sql::<TimestamptzSqlite>(&format!("'{s}'"))).get_result(connection);
731 assert_eq!(Ok(time), epoch_from_sql, "format {s} failed");
732 }
733 }
734}