diff --git a/src/lib.rs b/src/lib.rs index 44cd4a9bd4..2ac19027b1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -129,18 +129,20 @@ mod macros; /// Tantivy uses [`time`](https://crates.io/crates/time) for dates. pub use time; +use crate::time::format_description::well_known::Rfc3339; use crate::time::{OffsetDateTime, PrimitiveDateTime, UtcOffset}; /// A date/time value with second precision. /// -/// This timestamp does not carry any time zone information. +/// This timestamp does not carry any explicit time zone information. /// Users are responsible for applying the provided conversion -/// functions consistently. +/// functions consistently. Internally the time zone is assumed +/// to be UTC, which is also used implicitly for JSON serialization. /// /// All constructors and conversions are provided as explicit /// functions and not by implementing any `From`/`Into` traits /// to prevent unintended usage. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct DateTime { unix_timestamp: i64, } @@ -200,6 +202,13 @@ impl DateTime { } } +impl fmt::Debug for DateTime { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let utc_rfc3339 = self.to_utc().format(&Rfc3339).map_err(|_| fmt::Error)?; + f.write_str(&utc_rfc3339) + } +} + pub use crate::error::TantivyError; /// Tantivy result. diff --git a/src/query/query_parser/query_parser.rs b/src/query/query_parser/query_parser.rs index 2b4ba2d62a..55ed2d9431 100644 --- a/src/query/query_parser/query_parser.rs +++ b/src/query/query_parser/query_parser.rs @@ -1039,9 +1039,10 @@ mod test { #[test] fn test_json_field_possibly_a_date() { + // Subseconds are discarded test_parse_query_to_logical_ast_helper( r#"json.date:"2019-10-12T07:20:50.52Z""#, - r#"(Term(type=Json, field=14, path=date, vtype=Date, DateTime { unix_timestamp: 1570864850 }) "[(0, Term(type=Json, field=14, path=date, vtype=Str, "2019")), (1, Term(type=Json, field=14, path=date, vtype=Str, "10")), (2, Term(type=Json, field=14, path=date, vtype=Str, "12t07")), (3, Term(type=Json, field=14, path=date, vtype=Str, "20")), (4, Term(type=Json, field=14, path=date, vtype=Str, "50")), (5, Term(type=Json, field=14, path=date, vtype=Str, "52z"))]")"#, + r#"(Term(type=Json, field=14, path=date, vtype=Date, 2019-10-12T07:20:50Z) "[(0, Term(type=Json, field=14, path=date, vtype=Str, "2019")), (1, Term(type=Json, field=14, path=date, vtype=Str, "10")), (2, Term(type=Json, field=14, path=date, vtype=Str, "12t07")), (3, Term(type=Json, field=14, path=date, vtype=Str, "20")), (4, Term(type=Json, field=14, path=date, vtype=Str, "50")), (5, Term(type=Json, field=14, path=date, vtype=Str, "52z"))]")"#, true, ); } diff --git a/src/schema/field_type.rs b/src/schema/field_type.rs index 7c6669ef3d..2a46ecf2db 100644 --- a/src/schema/field_type.rs +++ b/src/schema/field_type.rs @@ -361,10 +361,8 @@ mod tests { let doc_json = r#"{"date": "2019-10-12T07:20:50.52+02:00"}"#; let doc = schema.parse_document(doc_json).unwrap(); let date = doc.get_first(date_field).unwrap(); - assert_eq!( - format!("{:?}", date), - "Date(DateTime { unix_timestamp: 1570857650 })" - ); + // Time zone is converted to UTC and subseconds are discarded + assert_eq!("Date(2019-10-12T05:20:50Z)", format!("{:?}", date)); } #[test]