use chrono::{DateTime, Datelike, Duration, Timelike, Utc};
use serde_json::Value;
use std::collections::HashMap;
use crate::data::DataTimeseries;
impl DataTimeseries {
pub fn group_by_interval(
&self,
data: &Value,
date_key: &str,
interval: &str,
) -> HashMap<String, Vec<Value>> {
group_by_interval(data, date_key, interval)
}
}
pub fn group_by_interval(
data: &Value,
date_key: &str,
interval: &str,
) -> HashMap<String, Vec<Value>> {
let mut grouped_data: HashMap<String, Vec<Value>> = HashMap::new();
if let Value::Array(items) = data {
for item in items {
if let Some(date_value) = item.get(date_key)
&& let Some(date_str) = date_value.as_str()
&& let Ok(date) = DateTime::parse_from_rfc3339(date_str)
{
let date: DateTime<Utc> = date.with_timezone(&Utc);
let key: String = match interval {
"hour" => format!(
"{:04}-{:02}-{:02} {:02}:00",
date.year(),
date.month(),
date.day(),
date.hour()
),
"day" => {
format!("{:04}-{:02}-{:02}", date.year(), date.month(), date.day())
}
"week" => {
let week_start =
date - Duration::days(date.weekday().num_days_from_monday() as i64);
format!(
"Week of {:04}-{:02}-{:02}",
week_start.year(),
week_start.month(),
week_start.day()
)
}
"year" => format!("{:04}", date.year()),
_ => continue,
};
grouped_data.entry(key).or_default().push(item.clone());
}
}
}
grouped_data
}