1- crate :: data_type! ( DateTime ) ;
1+ use open62541_sys :: { UA_DATETIME_UNIX_EPOCH , UA_DATETIME_USEC } ;
22
3- impl DateTime {
4- /// Returns the UNIX timestamp with nanosecond precision.
5- #[ must_use]
6- pub fn as_unix_timestamp_nanos ( & self ) -> i128 {
7- use open62541_sys:: { UA_DATETIME_UNIX_EPOCH , UA_DATETIME_USEC } ;
3+ use crate :: Error ;
84
9- // OPC UA encodes `DateTime` as Windows file time: a 64-bit value that represents the number
10- // of 100-nanosecond intervals that have elapsed since 12:00 A.M. January 1, 1601 (UTC).
11- let ua_ticks = i128:: from ( self . 0 ) ;
12- let unix_ticks = ua_ticks - i128:: from ( UA_DATETIME_UNIX_EPOCH ) ;
13- unix_ticks * i128:: from ( 1000 / UA_DATETIME_USEC )
14- }
5+ crate :: data_type!( DateTime ) ;
156
7+ impl DateTime {
168 /// Creates [`DateTime`] from a UNIX timestamp with nanosecond precision.
179 ///
10+ /// /// # Examples
11+ ///
12+ /// ```
13+ /// use open62541::ua;
14+ ///
15+ /// // Unix timestamp (1707482096 seconds) corresponding to 9th February 2024, 12:34:56 UTC.
16+ /// let dt = ua::DateTime::try_from_unix_timestamp_nanos(1_707_482_096_000_000_000).unwrap();
17+ ///
18+ /// assert_eq!(format!("{dt:?}"), "\"2024-02-09T12:34:56Z\"");
19+ /// ```
20+ ///
1821 /// # Errors
1922 ///
2023 /// The UNIX timestamp must be valid and in range of the 64-bit representation of [`DateTime`].
21- pub fn try_from_unix_timestamp_nanos ( unix_timestamp_nanos : i128 ) -> Result < Self , crate :: Error > {
22- use open62541_sys:: { UA_DATETIME_UNIX_EPOCH , UA_DATETIME_USEC } ;
23-
24+ pub fn try_from_unix_timestamp_nanos ( unix_timestamp_nanos : i128 ) -> Result < Self , Error > {
2425 // OPC UA encodes `DateTime` as Windows file time: a 64-bit value that represents the number
2526 // of 100-nanosecond intervals that have elapsed since 12:00 A.M. January 1, 1601 (UTC).
26- let ticks_unix = unix_timestamp_nanos / i128:: from ( 1000 / UA_DATETIME_USEC ) ;
27- let ticks_ua = ticks_unix + i128:: from ( UA_DATETIME_UNIX_EPOCH ) ;
27+ let unix_ticks = unix_timestamp_nanos / i128:: from ( 1000 / UA_DATETIME_USEC ) ;
28+ let ua_ticks = unix_ticks + i128:: from ( UA_DATETIME_UNIX_EPOCH ) ;
2829
29- i64:: try_from ( ticks_ua)
30- // Explicit module path to avoid linter errors when feature is not enable by `#[cfg()]`.
31- . map_err ( |_| crate :: Error :: internal ( "DateTime should be in range" ) )
30+ i64:: try_from ( ua_ticks)
31+ . map_err ( |_| Error :: internal ( "DateTime should be in range" ) )
3232 . map ( Self )
3333 }
34+
35+ /// Returns the UNIX timestamp with nanosecond precision.
36+ #[ must_use]
37+ pub fn as_unix_timestamp_nanos ( & self ) -> i128 {
38+ // OPC UA encodes `DateTime` as Windows file time: a 64-bit value that represents the number
39+ // of 100-nanosecond intervals that have elapsed since 12:00 A.M. January 1, 1601 (UTC).
40+ let ua_ticks = i128:: from ( self . 0 ) ;
41+ let unix_ticks = ua_ticks - i128:: from ( UA_DATETIME_UNIX_EPOCH ) ;
42+
43+ unix_ticks * i128:: from ( 1000 / UA_DATETIME_USEC )
44+ }
3445}
3546
3647#[ cfg( feature = "time" ) ]
3748impl DateTime {
38- // TODO (breaking change): Return time::UtcDateTime instead of time::OffsetDateTime.
49+ // TODO (breaking change): Return ` time::UtcDateTime` instead of ` time::OffsetDateTime` .
3950 #[ must_use]
4051 pub fn to_utc ( & self ) -> Option < time:: OffsetDateTime > {
4152 time:: OffsetDateTime :: from_unix_timestamp_nanos ( self . as_unix_timestamp_nanos ( ) ) . ok ( )
4253 }
4354}
4455
56+ // TODO (breaking change): Upgrade `time` (0.3.38), add conversion from `time::UtcDateTime`.
4557#[ cfg( feature = "time" ) ]
4658impl TryFrom < time:: OffsetDateTime > for DateTime {
47- // Explicit module path to avoid linter errors when feature is not enable by `#[cfg()]`.
48- type Error = crate :: Error ;
59+ type Error = Error ;
4960
5061 /// Creates [`DateTime`] from [`time::OffsetDateTime`].
5162 ///
@@ -56,6 +67,8 @@ impl TryFrom<time::OffsetDateTime> for DateTime {
5667 /// use time::macros::datetime;
5768 ///
5869 /// let dt: ua::DateTime = datetime!(2024-02-09 12:34:56 UTC).try_into().unwrap();
70+ ///
71+ /// assert_eq!(format!("{dt:?}"), "\"2024-02-09T12:34:56Z\"");
5972 /// ```
6073 ///
6174 /// # Errors
0 commit comments