wtime/local/mod.rs
1use super::{
2    calc::{calc_date, duration_since, get_millis, get_minute, get_nanos, get_second},
3    tz::tz_number,
4    utc::{utc_ts_millis, utc_ts_nanos, utc_ts_sec},
5};
6use std::time::{Duration, SystemTime, UNIX_EPOCH};
7
8/// ### local_now()
9///
10/// Retrieves the current local time based on a variable timezone offset.
11///
12/// This function returns the current local system time as a `SystemTime` object,
13/// adjusted from the current UTC time by a timezone offset obtained from a function.
14/// This allows for dynamic adjustments based on different timezone settings, which may
15/// be particularly useful for applications that need to handle multiple timezones,
16/// including daylight saving changes.
17///
18/// ### Example
19///
20/// ```
21/// use wtime::local::local_now;
22///
23/// let now = local_now();
24/// println!("Current local time: {:?}", now);
25/// ```
26///
27/// ### Panics
28///
29/// This function does not panic under normal circumstances; however, it may panic
30/// if there is an issue with the system clock, such as if the current time is before
31/// the Unix epoch (January 1, 1970). It may also panic if the conversion to a
32/// `Duration` fails due to time going backwards or an invalid timezone offset.
33///
34/// ### Note
35///
36/// The timezone offset is obtained dynamically via the `tz_number()` function,
37/// allowing for more flexibility than a hard-coded offset. Ensure that `tz_number()`
38/// accurately reflects the intended timezone offset in hours. Calculating the offset
39/// in seconds allows for precise adjustment of the UTC time to the local time.
40///
41/// <small>End Fun Doc</small>
42pub fn local_now() -> SystemTime {
43    // Timezone offset
44    let timezone_offset_hours: i64 = tz_number();
45
46    // Calculate the offset in seconds
47    let offset_in_seconds = timezone_offset_hours * 3600;
48
49    // Get the duration since the Unix epoch for the UTC time
50    let duration_since_epoch = duration_since();
51
52    // Calculate the new duration for the local time
53    let local_duration = duration_since_epoch + Duration::from_secs(offset_in_seconds as u64);
54
55    // Convert back to SystemTime
56    UNIX_EPOCH + local_duration
57}
58
59/// ### local_ts_sec()
60///
61/// Retrieves the current local time as a UNIX timestamp in seconds.
62///
63/// This function calculates the local time in seconds since the UNIX epoch by
64/// adding the local timezone offset (in hours) to the current UTC timestamp.
65/// This is useful for obtaining a UNIX timestamp that reflects the local time
66/// settings.
67///
68/// ### Example
69///
70/// ```
71/// use wtime::local::local_ts_sec;
72///
73/// let local_timestamp = local_ts_sec();
74/// println!("Current Local Timestamp in Seconds: {}", local_timestamp);
75/// ```
76///
77/// ### Returns
78///
79/// Returns the current local time as a `u64` representing the number of seconds
80/// since the UNIX epoch.
81///
82/// <small>End Fun Doc</small>
83pub fn local_ts_sec() -> u64 {
84    utc_ts_sec() + (tz_number() * 60 * 60) as u64
85}
86
87/// ### local_ts_millis()
88///
89/// Retrieves the current local time as a UNIX timestamp in milliseconds.
90///
91/// This function calculates the local time in milliseconds since the UNIX epoch
92/// by adding the local timezone offset (in hours) to the current UTC timestamp.
93/// This is useful for obtaining a timestamp that is precise to the millisecond for
94/// applications that require high-resolution timing.
95///
96/// ### Example
97///
98/// ```
99/// use wtime::local::local_ts_millis;
100///
101/// let local_timestamp_millis = local_ts_millis();
102/// println!("Current Local Timestamp in Milliseconds: {}", local_timestamp_millis);
103/// ```
104///
105/// ### Returns
106///
107/// Returns the current local time as a `u128` representing the number of milliseconds
108/// since the UNIX epoch.
109///
110/// <small>End Fun Doc</small>
111pub fn local_ts_millis() -> u128 {
112    utc_ts_millis() + (tz_number() * 60 * 60 * 1_000) as u128
113}
114
115/// ### local_ts_nanos()
116///
117/// Retrieves the current local time as a UNIX timestamp in nanoseconds.
118///
119/// This function calculates the local time in nanoseconds since the UNIX epoch
120/// by adding the local timezone offset (in hours) to the current UTC timestamp.
121/// This is useful for applications that require extremely high-resolution timestamps.
122///
123/// ### Example
124///
125/// ```
126/// use wtime::local::local_ts_nanos;
127///
128/// let local_timestamp_nanos = local_ts_nanos();
129/// println!("Current Local Timestamp in Nanoseconds: {}", local_timestamp_nanos);
130/// ```
131///
132/// ### Returns
133///
134/// Returns the current local time as a `u128` representing the number of nanoseconds
135/// since the UNIX epoch.
136///
137/// <small>End Fun Doc</small>
138pub fn local_ts_nanos() -> u128 {
139    utc_ts_nanos() + (tz_number() * 60 * 60 * 1_000_000) as u128
140}
141
142/// ### get_local_year() -> u64
143///
144/// Retrieves the current year.
145///
146/// This function calculates the current year based on the current local timestamp.
147///
148/// ### Example
149///
150/// ```
151/// use wtime::local::get_local_year;
152///
153/// let year = get_local_year();
154/// println!("Current year: {}", year);
155/// ```
156///
157/// ### Returns
158///
159/// Returns the current year as a `u64`.
160///
161/// <small>End Fun Doc</small>
162pub fn get_local_year() -> u64 {
163    let (year, _, _) = calc_date(local_ts_sec());
164    year
165}
166
167/// ### get_local_month() -> u64
168///
169/// Retrieves the current month.
170///
171/// This function calculates the current month based on the current local timestamp.
172///
173/// ### Example
174///
175/// ```
176/// use wtime::local::get_local_month;
177///
178/// let month = get_local_month();
179/// println!("Current month: {}", month);
180/// ```
181///
182/// ### Returns
183///
184/// Returns the current month as a `u64`.
185///
186/// <small>End Fun Doc</small>
187pub fn get_local_month() -> u64 {
188    let (_, month, _) = calc_date(local_ts_sec());
189    month
190}
191
192/// ### get_local_day() -> u64
193///
194/// Retrieves the current day of the month.
195///
196/// This function calculates the current day based on the current local timestamp.
197///
198/// ### Example
199///
200/// ```
201/// use wtime::local::get_local_day;
202///
203/// let day = get_local_day();
204/// println!("Current day: {}", day);
205/// ```
206///
207/// ### Returns
208///
209/// Returns the current day of the month as a `u64`.
210///
211/// <small>End Fun Doc</small>
212pub fn get_local_day() -> u64 {
213    let (_, _, day) = calc_date(local_ts_sec());
214    day
215}
216
217/// ### get_local_hour() -> u64
218///
219/// Retrieves the current hour of the day.
220///
221/// This function calculates the current hour based on the current local timestamp.
222/// The hour is returned in 24-hour format (0-23).
223///
224/// ### Example
225///
226/// ```
227/// use wtime::local::get_local_hour;
228///
229/// let hour = get_local_hour();
230/// println!("Current hour: {}", hour);
231/// ```
232///
233/// ### Returns
234///
235/// Returns the current hour of the day as a `u64`.
236///
237/// <small>End Fun Doc</small>
238pub fn get_local_hour() -> u64 {
239    let hour = ((local_ts_sec() / 3600) % 24 + 24) % 24; // Handle wrap around for negative hours
240    hour
241}
242
243/// ### format_local_ts()
244///
245/// Retrieves the current local timestamp formatted as a string.
246///
247/// This function generates a formatted timestamp string in the structure
248/// `year-month-day-hour-minute-second-millis-nanos`, adhering to the
249/// following specifications for each component:
250/// - Year: 4 digits (e.g., `2024`)
251/// - Month: 2 digits, zero-padded (01-12)
252/// - Day: 2 digits, zero-padded (01-31)
253/// - Hour: 2 digits, zero-padded (00-23)
254/// - Minute: 2 digits, zero-padded (00-59)
255/// - Second: 2 digits, zero-padded (00-59)
256/// - Milliseconds: 3 digits, zero-padded (000-999)
257/// - Nanoseconds: 6 digits, zero-padded (000000-999999)
258///
259/// This function does not perform error handling or validation beyond the necessary
260/// calculations for the timestamp components. It is assumed that the underlying
261/// time retrieval functions are functioning correctly and return valid values.
262///
263/// ### Usage for Creating Unique Identifiers (IDs)
264///
265/// The formatted timestamp generated by this function can be used as part of unique
266/// identifiers (IDs). You can create a timestamp-based ID that is likely to be unique
267/// within your application's context, either by combining it with a unique suffix or
268/// using it by itself.
269///
270/// Here's an example using a unique suffix:
271/// ```rust
272/// use wtime::local::format_local_ts;
273///
274/// let timestamp = format_local_ts();
275///     
276/// // Simulate generating a unique ID with a suffix
277/// let unique_id_with_suffix = format!("ID-{}-{}", format_local_ts(), "random_suffix"); // Replace with actual random suffix function
278/// println!("Generated Unique ID with Suffix: {}", unique_id_with_suffix);
279/// ```
280///
281/// And here's an example using the timestamp by itself:
282/// ```rust
283/// use wtime::local::format_local_ts;
284///
285/// let timestamp = format_local_ts();
286///
287/// // Simulate generating a unique ID without a suffix
288/// let unique_id_without_suffix = format!("ID-{}", format_local_ts());
289/// println!("Generated Unique ID without Suffix: {}", unique_id_without_suffix);
290/// ```
291///
292/// ### Usage in Blog Posts
293///
294/// You can also use the formatted timestamp for logging or identifying blog posts.
295/// By generating a unique local timestamp string for each blog post, you ensure that
296/// there is a clear and systematic way to track each post's creation time.
297///
298/// Example:
299/// ```rust
300/// use wtime::local::format_local_ts;
301///
302/// let blog_post_timestamp = format!("BlogPost Timestamp: {}", format_local_ts());
303/// println!("Generated Blog Post Local Timestamp: {}", blog_post_timestamp);
304/// ```
305///
306/// ### Example
307///
308/// ```rust
309/// use wtime::local::format_local_ts;
310///
311/// let timestamp = format_local_ts();
312/// println!("Formatted Local Timestamp: {}", timestamp);
313/// ```
314///
315/// ### Returns
316///
317/// Returns a `String` representing the current local timestamp formatted in the specified
318/// manner. The length of the returned string is guaranteed to be 30 characters if all
319/// components are valid.
320///
321/// ### Note
322///
323/// - Ensure that any dependencies or underlying functionality that this function relies
324///   upon (such as time retrieval functions) are functioning correctly to avoid unexpected
325///   results. No panic conditions are raised in this function; any potential issues should
326///   be managed by the developer as appropriate for their use case.
327///
328/// <small>End Fun Doc</small>
329pub fn format_local_ts() -> String {
330    let year = get_local_year();
331    let month = get_local_month();
332    let day = get_local_day();
333    let hour = get_local_hour();
334    let minute = get_minute();
335    let second = get_second();
336    let millis = get_millis();
337    let nanos = get_nanos();
338
339    // Create the formatted string with updated formatting
340    format!(
341        "{:04}-{:02}-{:02}-{:02}-{:02}-{:02}-{:03}-{:06}",
342        year, month, day, hour, minute, second, millis, nanos,
343    )
344}