rl_lang/interpreter/stdlib/time/
format_time.rs1use crate::interpreter::{
10 evaluator::Evaluator,
11 stdlib::common::{verr, vok, vs},
12 values::Value,
13};
14
15pub fn unix_to_parts(timestamp: i64) -> (i32, u32, u32, u32, u32, u32) {
16 let total_seconds = timestamp;
17 let time_of_day = total_seconds % 86400;
18 let hour = time_of_day / 3600;
19 let minute = (time_of_day % 3600) / 60;
20 let second = time_of_day % 60;
21
22 let days_since_epoch = total_seconds / 86400;
23 let days_since_march0 = days_since_epoch + 719468;
24
25 let century = days_since_march0.div_euclid(146097);
26 let day_in_century = days_since_march0.rem_euclid(146097);
27 let year_in_century = (day_in_century - day_in_century / 1460 + day_in_century / 36524
28 - day_in_century / 146096)
29 / 365;
30 let day_in_year =
31 day_in_century - (365 * year_in_century + year_in_century / 4 - year_in_century / 100);
32 let month_index = (5 * day_in_year + 2) / 153;
33 let day = day_in_year - (153 * month_index + 2) / 5 + 1;
34 let month = if month_index < 10 {
35 month_index + 3
36 } else {
37 month_index - 9
38 };
39 let year = year_in_century + century * 400 + if month <= 2 { 1 } else { 0 };
40
41 (
42 year as i32,
43 month as u32,
44 day as u32,
45 hour as u32,
46 minute as u32,
47 second as u32,
48 )
49}
50
51fn apply_pattern(
52 pattern: &str,
53 year: i32,
54 month: u32,
55 day: u32,
56 hour: u32,
57 minute: u32,
58 second: u32,
59) -> String {
60 pattern
61 .replace("%Y", &format!("{:04}", year))
62 .replace("%m", &format!("{:02}", month))
63 .replace("%d", &format!("{:02}", day))
64 .replace("%H", &format!("{:02}", hour))
65 .replace("%M", &format!("{:02}", minute))
66 .replace("%S", &format!("{:02}", second))
67}
68
69pub fn format_time(_: &mut Evaluator, timestamp: i64, pattern: String) -> Value {
70 if timestamp < 0 {
71 return verr!(vs!("timestamp is negative".to_string()));
72 }
73 let (year, month, day, hour, minute, second) = unix_to_parts(timestamp);
74 vok!(vs!(apply_pattern(
75 &pattern, year, month, day, hour, minute, second,
76 )))
77}
78
79pub fn date_str(_: &mut Evaluator, timestamp: i64) -> Value {
80 if timestamp < 0 {
81 return verr!(vs!("timestamp is negative".to_string()));
82 }
83 let (year, month, day, hour, minute, second) = unix_to_parts(timestamp);
84 vok!(vs!(apply_pattern(
85 "%Y-%m-%d", year, month, day, hour, minute, second,
86 )))
87}
88
89pub fn time_str(_: &mut Evaluator, timestamp: i64) -> Value {
90 if timestamp < 0 {
91 return verr!(vs!("timestamp is negative".to_string()));
92 }
93 let (year, month, day, hour, minute, second) = unix_to_parts(timestamp);
94 vok!(vs!(apply_pattern(
95 "%H:%M:%S", year, month, day, hour, minute, second,
96 )))
97}