diff --git a/src/tds/codec/column_data.rs b/src/tds/codec/column_data.rs index ada32781..7771083f 100644 --- a/src/tds/codec/column_data.rs +++ b/src/tds/codec/column_data.rs @@ -31,6 +31,7 @@ use crate::{ }; use bytes::BufMut; pub(crate) use bytes_mut_with_type_info::BytesMutWithTypeInfo; +use chrono::{Duration, NaiveDate}; use std::borrow::{BorrowMut, Cow}; use uuid::Uuid; @@ -594,6 +595,25 @@ impl<'a> Encode> for ColumnData<'a> { time.encode(&mut *dst)?; } #[cfg(feature = "tds73")] + (ColumnData::DateTime2(opt), Some(TypeInfo::VarLenSized(vlc))) + if vlc.r#type() == VarLenType::Datetimen => + { + if let Some(dt2) = opt { + dst.put_u8(8); + let dt2_days = dt2.date().days(); + let dt2_date = + NaiveDate::from_ymd_opt(1, 1, 1).unwrap() + Duration::days(dt2_days.into()); + let dt1_days = dt2_days.checked_sub(693595).ok_or_else(|| crate::Error::Conversion( + format!("invalid datetime, expecting datetime not earlier than 1900-01-01 but got {:?}", dt2_date) + .into()))?; // minus days gap between year 1 and year 1900 + let seconds_fragments = dt2.time().increments() * 100 * 300 / 1e9 as u64; // degrade second's precision + dst.put_u32_le(dt1_days as u32); + dst.put_u32_le(seconds_fragments as u32); + } else { + dst.put_u8(0); + } + } + #[cfg(feature = "tds73")] (ColumnData::DateTime2(opt), Some(TypeInfo::VarLenSized(vlc))) if vlc.r#type() == VarLenType::Datetime2 => { diff --git a/src/tds/time/chrono.rs b/src/tds/time/chrono.rs index 4bdb59a5..7207ccd3 100644 --- a/src/tds/time/chrono.rs +++ b/src/tds/time/chrono.rs @@ -13,7 +13,7 @@ use crate::tds::codec::ColumnData; #[cfg(feature = "tds73")] #[cfg_attr(feature = "docs", doc(cfg(feature = "tds73")))] pub use chrono::offset::{FixedOffset, Utc}; -pub use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime}; +pub use chrono::{Duration, DateTime, NaiveDate, NaiveDateTime, NaiveTime}; #[cfg(feature = "tds73")] use std::ops::Sub;