keramics_datetime/
posix.rs1use std::fmt;
15
16use keramics_types::{bytes_to_i32_be, bytes_to_i32_le};
17
18use super::epoch::Epoch;
19use super::util::{get_date_values, get_time_values};
20
21const POSIX_EPOCH: Epoch = Epoch {
22 year: 1970,
23 month: 1,
24 day_of_month: 1,
25};
26
27#[derive(Clone, Debug, Default, PartialEq)]
29pub struct PosixTime32 {
30 pub timestamp: i32,
33}
34
35impl PosixTime32 {
36 pub fn new(timestamp: i32) -> Self {
38 Self {
39 timestamp: timestamp,
40 }
41 }
42
43 pub fn from_be_bytes(data: &[u8]) -> Self {
45 let timestamp: i32 = bytes_to_i32_be!(data, 0);
46 Self {
47 timestamp: timestamp,
48 }
49 }
50
51 pub fn from_le_bytes(data: &[u8]) -> Self {
53 let timestamp: i32 = bytes_to_i32_le!(data, 0);
54 Self {
55 timestamp: timestamp,
56 }
57 }
58
59 pub fn to_iso8601_string(&self) -> String {
61 let (days, hours, minutes, seconds): (i64, u8, u8, u8) =
62 get_time_values(self.timestamp as i64);
63 let (year, month, day_of_month): (i16, u8, u8) = get_date_values(days, &POSIX_EPOCH);
64 format!(
65 "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}",
66 year, month, day_of_month, hours, minutes, seconds
67 )
68 }
69}
70
71impl fmt::Display for PosixTime32 {
72 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
74 write!(
75 formatter,
76 "{} ({})",
77 self.to_iso8601_string(),
78 self.timestamp
79 )
80 }
81}
82
83#[derive(Clone, Debug, Default, PartialEq)]
85pub struct PosixTime64Ns {
86 pub timestamp: i64,
89
90 pub fraction: u32,
92}
93
94impl PosixTime64Ns {
95 pub fn new(timestamp: i64, fraction: u32) -> Self {
97 Self {
98 timestamp: timestamp,
99 fraction: fraction,
100 }
101 }
102
103 pub fn to_iso8601_string(&self) -> String {
105 let (days, hours, minutes, seconds): (i64, u8, u8, u8) = get_time_values(self.timestamp);
106 let (year, month, day_of_month): (i16, u8, u8) = get_date_values(days, &POSIX_EPOCH);
107 format!(
108 "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}.{:09}",
109 year, month, day_of_month, hours, minutes, seconds, self.fraction
110 )
111 }
112}
113
114impl fmt::Display for PosixTime64Ns {
115 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
117 write!(
118 formatter,
119 "{} ({}.{})",
120 self.to_iso8601_string(),
121 self.timestamp,
122 self.fraction
123 )
124 }
125}
126
127#[cfg(test)]
128mod tests {
129 use super::*;
130
131 #[test]
132 fn test_posix_time32_from_be_bytes() {
133 let test_data: [u8; 4] = [0x67, 0x54, 0x0d, 0xd9];
134
135 let test_struct: PosixTime32 = PosixTime32::from_be_bytes(&test_data);
136 assert_eq!(test_struct.timestamp, 1733561817);
137 }
138
139 #[test]
140 fn test_posix_time32_from_le_bytes() {
141 let test_data: [u8; 4] = [0xd9, 0x0d, 0x54, 0x67];
142
143 let test_struct: PosixTime32 = PosixTime32::from_le_bytes(&test_data);
144 assert_eq!(test_struct.timestamp, 1733561817);
145 }
146
147 #[test]
148 fn test_posix_time32_to_iso8601_string() {
149 let test_struct: PosixTime32 = PosixTime32::new(1281643591);
150
151 let string: String = test_struct.to_iso8601_string();
152 assert_eq!(string.as_str(), "2010-08-12T20:06:31");
153
154 let test_struct: PosixTime32 = PosixTime32::new(-1281643591);
155
156 let string: String = test_struct.to_iso8601_string();
157 assert_eq!(string.as_str(), "1929-05-22T03:53:29");
158 }
159
160 #[test]
161 fn test_posix_time64ns_to_iso8601_string() {
162 let test_struct: PosixTime64Ns = PosixTime64Ns::new(1281643591, 987654321);
163
164 let string: String = test_struct.to_iso8601_string();
165 assert_eq!(string.as_str(), "2010-08-12T20:06:31.987654321");
166
167 let test_struct: PosixTime64Ns = PosixTime64Ns::new(-1281643592, 12345679);
168
169 let string: String = test_struct.to_iso8601_string();
170 assert_eq!(string.as_str(), "1929-05-22T03:53:28.012345679");
171 }
172}