diff --git a/src/fnc/mod.rs b/src/fnc/mod.rs index ba39eb6e..089430f6 100644 --- a/src/fnc/mod.rs +++ b/src/fnc/mod.rs @@ -137,6 +137,7 @@ pub fn run(ctx: &Runtime, name: &String, args: Vec) -> Result args::check(ctx, name, args, Args::NoneOne, time::day), "time::floor" => args::check(ctx, name, args, Args::Two, time::floor), + "time::group" => args::check(ctx, name, args, Args::Two, time::group), "time::hour" => args::check(ctx, name, args, Args::NoneOne, time::hour), "time::mins" => args::check(ctx, name, args, Args::NoneOne, time::mins), "time::month" => args::check(ctx, name, args, Args::NoneOne, time::month), diff --git a/src/fnc/time.rs b/src/fnc/time.rs index 6abb103c..b37feb3c 100644 --- a/src/fnc/time.rs +++ b/src/fnc/time.rs @@ -2,6 +2,7 @@ use crate::dbs::Runtime; use crate::err::Error; use crate::sql::datetime::Datetime; use crate::sql::value::Value; +use chrono::prelude::*; use chrono::Datelike; use chrono::DurationRound; use chrono::Timelike; @@ -33,6 +34,39 @@ pub fn floor(_: &Runtime, mut args: Vec) -> Result { } } +pub fn group(_: &Runtime, mut args: Vec) -> Result { + match args.remove(0) { + Value::Datetime(v) => match args.remove(0) { + Value::Strand(g) => match g.value.as_str() { + "year" => Ok(Utc.ymd(v.value.year(), 1, 1).and_hms(0, 0, 0).into()), + "month" => Ok(Utc.ymd(v.value.year(), v.value.month(), 1).and_hms(0, 0, 0).into()), + "day" => Ok(Utc + .ymd(v.value.year(), v.value.month(), v.value.day()) + .and_hms(0, 0, 0) + .into()), + "hour" => Ok(Utc + .ymd(v.value.year(), v.value.month(), v.value.day()) + .and_hms(v.value.hour(), 0, 0) + .into()), + "minute" => Ok(Utc + .ymd(v.value.year(), v.value.month(), v.value.day()) + .and_hms(v.value.hour(), v.value.minute(), 0) + .into()), + "second" => Ok(Utc + .ymd(v.value.year(), v.value.month(), v.value.day()) + .and_hms(v.value.hour(), v.value.minute(), v.value.second()) + .into()), + _ => Err(Error::ArgumentsError { + name: String::from("time::group"), + message: String::from("The second argument must be a string, and can be one of 'year', 'month', 'day', 'hour', 'minute', or 'second'."), + }), + }, + _ => Ok(Value::None), + }, + _ => Ok(Value::None), + } +} + pub fn hour(_: &Runtime, mut args: Vec) -> Result { match args.len() { 0 => Ok(Utc::now().hour().into()), diff --git a/src/sql/function.rs b/src/sql/function.rs index 1a00fbf0..7b3d4598 100644 --- a/src/sql/function.rs +++ b/src/sql/function.rs @@ -321,6 +321,7 @@ fn function_time(i: &str) -> IResult<&str, &str> { tag("time::age"), tag("time::day"), tag("time::floor"), + tag("time::group"), tag("time::hour"), tag("time::mins"), tag("time::month"),