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