sklears_preprocessing/temporal/
datetime_utils.rs1use sklears_core::types::Float;
7
8#[derive(Debug, Clone, Copy)]
10pub struct DateTime {
11 pub timestamp: i64,
13}
14
15impl DateTime {
16 pub fn from_timestamp(timestamp: i64) -> Self {
18 Self { timestamp }
19 }
20
21 pub fn to_components(&self, timezone_offset: Option<Float>) -> DateComponents {
24 let mut timestamp = self.timestamp;
25
26 if let Some(offset) = timezone_offset {
28 timestamp += (offset * 3600.0) as i64;
29 }
30
31 let days_since_epoch = timestamp / 86400;
33 let seconds_in_day = timestamp % 86400;
34
35 let mut year = 1970;
37 let mut remaining_days = days_since_epoch;
38
39 while remaining_days >= 365 {
41 let days_in_year = if Self::is_leap_year(year) { 366 } else { 365 };
42 if remaining_days >= days_in_year {
43 remaining_days -= days_in_year;
44 year += 1;
45 } else {
46 break;
47 }
48 }
49
50 let days_in_months = if Self::is_leap_year(year) {
52 [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
53 } else {
54 [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
55 };
56
57 let mut month = 1;
58 let mut day_of_month = remaining_days + 1;
59
60 for &days_in_month in &days_in_months {
61 if day_of_month > days_in_month {
62 day_of_month -= days_in_month;
63 month += 1;
64 } else {
65 break;
66 }
67 }
68
69 let hour = (seconds_in_day / 3600) as u8;
71 let minute = ((seconds_in_day % 3600) / 60) as u8;
72 let second = (seconds_in_day % 60) as u8;
73
74 let day_of_week = ((days_since_epoch + 4) % 7) as u8; let quarter = ((month - 1) / 3 + 1) as u8;
77 let day_of_year = Self::calculate_day_of_year(year, month as u8, day_of_month as u8);
78 let week_of_year = Self::calculate_week_of_year(year, month as u8, day_of_month as u8);
79
80 DateComponents {
81 year: year as u32,
82 month: month as u8,
83 day: day_of_month as u8,
84 hour,
85 minute,
86 second,
87 day_of_week,
88 quarter,
89 day_of_year,
90 week_of_year,
91 }
92 }
93
94 fn is_leap_year(year: i64) -> bool {
95 (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
96 }
97
98 fn calculate_day_of_year(year: i64, month: u8, day: u8) -> u16 {
99 let days_in_months = if Self::is_leap_year(year) {
100 [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
101 } else {
102 [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
103 };
104
105 let mut day_of_year = day as u16;
106 for i in 0..(month - 1) {
107 day_of_year += days_in_months[i as usize] as u16;
108 }
109 day_of_year
110 }
111
112 fn calculate_week_of_year(year: i64, month: u8, day: u8) -> u8 {
113 let day_of_year = Self::calculate_day_of_year(year, month, day);
114 ((day_of_year - 1) / 7 + 1) as u8
116 }
117}
118
119#[derive(Debug, Clone, Copy)]
121pub struct DateComponents {
122 pub year: u32,
123 pub month: u8, pub day: u8, pub hour: u8, pub minute: u8, pub second: u8, pub day_of_week: u8, pub quarter: u8, pub day_of_year: u16, pub week_of_year: u8, }