rusthound_ce/utils/
date.rs

1use chrono::{NaiveDateTime, Local};
2use std::convert::TryInto;
3use std::error::Error;
4//use log::trace;
5// special thanks to: https://github.com/NH-RED-TEAM/RustHound/pull/30/commits/e4b5dbc0f147dd0f8efe64d515e0a18b69937aeb
6
7/// Change date timestamp format to epoch format.
8pub fn convert_timestamp(timestamp: i64) -> i64
9{
10    let offset: i64 = 134774*24*60*60;
11    let epoch: i64 = timestamp/10000000-offset;
12    epoch
13}
14
15/// Function to change string to epoch format.
16pub fn string_to_epoch(date: &str) -> Result<i64, Box<dyn Error>> {
17    // Extract the portion before the dot
18    // yyyyMMddHHmmss.0z to epoch format
19    let str_representation = date.split('.').next().ok_or("Invalid date format")?;
20    
21    // Parse the date and convert to epoch
22    let naive_date = NaiveDateTime::parse_from_str(str_representation, "%Y%m%d%H%M%S")?;
23    Ok(naive_date.and_utc().timestamp())
24}
25
26
27/// Function to return current hours.
28pub fn return_current_time() -> String
29{
30    Local::now().format("%T").to_string()
31}
32
33/// Function to return current date.
34pub fn return_current_date() -> String
35{
36    Local::now().format("%D").to_string()
37}
38
39/// Function to return current date.
40pub fn return_current_fulldate() -> String
41{
42    Local::now().format("%Y%m%d%H%M%S").to_string()
43}
44
45/// Function to convert pKIExpirationPeriod Vec<u8> format to i64 Windows format (nanoseconds).
46pub fn filetime_to_span(filetime: Vec<u8>) -> Result<i64, Box<dyn Error>> {
47    if filetime.len() >= 8 {
48        // Convert the first 8 bytes into an i64 using native endianness
49        let span = i64::from_ne_bytes(filetime[0..8].try_into()?);
50        return Ok(span);
51    }
52    Ok(0)
53}
54
55/// Function to change Windows span format (nanoseconds) to String output date.
56pub fn span_to_string(span: i64) -> String {
57    // Convert span from 100-nanosecond units to seconds
58    let span_in_seconds = span / 10_000_000; // 1 second = 10^7 100-nanosecond units
59    let span_abs = span_in_seconds.abs();
60
61    if span_abs % 31536000 == 0 && span_abs / 31536000 >= 1 {
62        if span_abs / 31536000 == 1 {
63            "1 year".to_string()
64        } else {
65            format!("{} years", span_abs / 31536000)
66        }
67    } else if span_abs % 2592000 == 0 && span_abs / 2592000 >= 1 {
68        if span_abs / 2592000 == 1 {
69            "1 month".to_string()
70        } else {
71            format!("{} months", span_abs / 2592000)
72        }
73    } else if span_abs % 604800 == 0 && span_abs / 604800 >= 1 {
74        if span_abs / 604800 == 1 {
75            "1 week".to_string()
76        } else {
77            format!("{} weeks", span_abs / 604800)
78        }
79    } else if span_abs % 86400 == 0 && span_abs / 86400 >= 1 {
80        if span_abs / 86400 == 1 {
81            "1 day".to_string()
82        } else {
83            format!("{} days", span_abs / 86400)
84        }
85    } else if span_abs % 3600 == 0 && span_abs / 3600 >= 1 {
86        if span_abs / 3600 == 1 {
87            "1 hour".to_string()
88        } else {
89            format!("{} hours", span_abs / 3600)
90        }
91    } else if span_abs % 60 == 0 && span_abs / 60 >= 1 {
92        if span_abs / 60 == 1 {
93            "1 minute".to_string()
94        } else {
95            format!("{} minutes", span_abs / 60)
96        }
97    } else {
98        "less than a minute".to_string()
99    }
100}