mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-26 11:31:37 +08:00
Check Rfc3339 before stripping Z
So that "2013-10-07T08:23:19Z" and "2013-10-07T08:23:19.120Z" are correctly parsed.
This commit is contained in:
parent
0075671b09
commit
0241350af3
@ -37,6 +37,11 @@ impl ToSql for OffsetDateTime {
|
|||||||
impl FromSql for OffsetDateTime {
|
impl FromSql for OffsetDateTime {
|
||||||
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
value.as_str().and_then(|s| {
|
value.as_str().and_then(|s| {
|
||||||
|
if s.len() > 10 && s.as_bytes()[10] == b'T' {
|
||||||
|
// YYYY-MM-DDTHH:MM:SS.SSS[+-]HH:MM
|
||||||
|
return OffsetDateTime::parse(s, &Rfc3339)
|
||||||
|
.map_err(|err| FromSqlError::Other(Box::new(err)));
|
||||||
|
}
|
||||||
let s = s.strip_suffix('Z').unwrap_or(s);
|
let s = s.strip_suffix('Z').unwrap_or(s);
|
||||||
match s.len() {
|
match s.len() {
|
||||||
len if len <= 19 => {
|
len if len <= 19 => {
|
||||||
@ -44,10 +49,6 @@ impl FromSql for OffsetDateTime {
|
|||||||
PrimitiveDateTime::parse(s, &PRIMITIVE_SHORT_DATE_TIME_FORMAT)
|
PrimitiveDateTime::parse(s, &PRIMITIVE_SHORT_DATE_TIME_FORMAT)
|
||||||
.map(|d| d.assume_utc())
|
.map(|d| d.assume_utc())
|
||||||
}
|
}
|
||||||
_ if s.as_bytes()[10] == b'T' => {
|
|
||||||
// YYYY-MM-DDTHH:MM:SS.SSS[+-]HH:MM
|
|
||||||
OffsetDateTime::parse(s, &Rfc3339)
|
|
||||||
}
|
|
||||||
_ if s.as_bytes()[19] == b':' => {
|
_ if s.as_bytes()[19] == b':' => {
|
||||||
// legacy
|
// legacy
|
||||||
OffsetDateTime::parse(s, &LEGACY_DATE_TIME_FORMAT)
|
OffsetDateTime::parse(s, &LEGACY_DATE_TIME_FORMAT)
|
||||||
@ -71,15 +72,10 @@ mod test {
|
|||||||
use time::format_description::well_known::Rfc3339;
|
use time::format_description::well_known::Rfc3339;
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
|
|
||||||
fn checked_memory_handle() -> Result<Connection> {
|
|
||||||
let db = Connection::open_in_memory()?;
|
|
||||||
db.execute_batch("CREATE TABLE foo (t TEXT, i INTEGER, f FLOAT)")?;
|
|
||||||
Ok(db)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_offset_date_time() -> Result<()> {
|
fn test_offset_date_time() -> Result<()> {
|
||||||
let db = checked_memory_handle()?;
|
let db = Connection::open_in_memory()?;
|
||||||
|
db.execute_batch("CREATE TABLE foo (t TEXT, i INTEGER, f FLOAT)")?;
|
||||||
|
|
||||||
let mut ts_vec = vec![];
|
let mut ts_vec = vec![];
|
||||||
|
|
||||||
@ -108,8 +104,20 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_string_values() -> Result<()> {
|
fn test_string_values() -> Result<()> {
|
||||||
let db = checked_memory_handle()?;
|
let db = Connection::open_in_memory()?;
|
||||||
for (s, t) in vec![
|
for (s, t) in vec![
|
||||||
|
(
|
||||||
|
"2013-10-07 08:23:19",
|
||||||
|
Ok(OffsetDateTime::parse("2013-10-07T08:23:19Z", &Rfc3339).unwrap()),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"2013-10-07 08:23:19Z",
|
||||||
|
Ok(OffsetDateTime::parse("2013-10-07T08:23:19Z", &Rfc3339).unwrap()),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"2013-10-07T08:23:19Z",
|
||||||
|
Ok(OffsetDateTime::parse("2013-10-07T08:23:19Z", &Rfc3339).unwrap()),
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"2013-10-07 08:23:19.120",
|
"2013-10-07 08:23:19.120",
|
||||||
Ok(OffsetDateTime::parse("2013-10-07T08:23:19.120Z", &Rfc3339).unwrap()),
|
Ok(OffsetDateTime::parse("2013-10-07T08:23:19.120Z", &Rfc3339).unwrap()),
|
||||||
@ -118,11 +126,22 @@ mod test {
|
|||||||
"2013-10-07 08:23:19.120Z",
|
"2013-10-07 08:23:19.120Z",
|
||||||
Ok(OffsetDateTime::parse("2013-10-07T08:23:19.120Z", &Rfc3339).unwrap()),
|
Ok(OffsetDateTime::parse("2013-10-07T08:23:19.120Z", &Rfc3339).unwrap()),
|
||||||
),
|
),
|
||||||
//"2013-10-07T08:23:19.120Z", // TODO
|
(
|
||||||
|
"2013-10-07T08:23:19.120Z",
|
||||||
|
Ok(OffsetDateTime::parse("2013-10-07T08:23:19.120Z", &Rfc3339).unwrap()),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"2013-10-07 04:23:19-04:00",
|
||||||
|
Ok(OffsetDateTime::parse("2013-10-07T04:23:19-04:00", &Rfc3339).unwrap()),
|
||||||
|
),
|
||||||
(
|
(
|
||||||
"2013-10-07 04:23:19.120-04:00",
|
"2013-10-07 04:23:19.120-04:00",
|
||||||
Ok(OffsetDateTime::parse("2013-10-07T04:23:19.120-04:00", &Rfc3339).unwrap()),
|
Ok(OffsetDateTime::parse("2013-10-07T04:23:19.120-04:00", &Rfc3339).unwrap()),
|
||||||
),
|
),
|
||||||
|
(
|
||||||
|
"2013-10-07T04:23:19.120-04:00",
|
||||||
|
Ok(OffsetDateTime::parse("2013-10-07T04:23:19.120-04:00", &Rfc3339).unwrap()),
|
||||||
|
),
|
||||||
] {
|
] {
|
||||||
let result: Result<OffsetDateTime> = db.query_row("SELECT ?", [s], |r| r.get(0));
|
let result: Result<OffsetDateTime> = db.query_row("SELECT ?", [s], |r| r.get(0));
|
||||||
assert_eq!(result, t);
|
assert_eq!(result, t);
|
||||||
@ -132,7 +151,7 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_sqlite_functions() -> Result<()> {
|
fn test_sqlite_functions() -> Result<()> {
|
||||||
let db = checked_memory_handle()?;
|
let db = Connection::open_in_memory()?;
|
||||||
let result: Result<OffsetDateTime> =
|
let result: Result<OffsetDateTime> =
|
||||||
db.query_row("SELECT CURRENT_TIMESTAMP", [], |r| r.get(0));
|
db.query_row("SELECT CURRENT_TIMESTAMP", [], |r| r.get(0));
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
@ -141,7 +160,7 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_param() -> Result<()> {
|
fn test_param() -> Result<()> {
|
||||||
let db = checked_memory_handle()?;
|
let db = Connection::open_in_memory()?;
|
||||||
let result: Result<bool> = db.query_row("SELECT 1 WHERE ? BETWEEN datetime('now', '-1 minute') AND datetime('now', '+1 minute')", [OffsetDateTime::now_utc()], |r| r.get(0));
|
let result: Result<bool> = db.query_row("SELECT 1 WHERE ? BETWEEN datetime('now', '-1 minute') AND datetime('now', '+1 minute')", [OffsetDateTime::now_utc()], |r| r.get(0));
|
||||||
assert!(result.is_ok());
|
assert!(result.is_ok());
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user