Added better Duration toString and Date makeWithYear functionality

This commit is contained in:
Ozzie Gooen 2022-05-22 21:40:06 -04:00
parent 364190dc7b
commit f1d2a1a12f
3 changed files with 40 additions and 10 deletions

View File

@ -192,15 +192,16 @@ const SquiggleItem: React.FC<SquiggleItemProps> = ({
case "date": case "date":
return ( return (
<VariableBox heading="Date" showTypes={showTypes}> <VariableBox heading="Date" showTypes={showTypes}>
{expression.value.toString()} {expression.value.toDateString()}
</VariableBox> </VariableBox>
); );
case "timeDuration": case "timeDuration":{
return ( return (
<VariableBox heading="Time Duration" showTypes={showTypes}> <VariableBox heading="Time Duration" showTypes={showTypes}>
<NumberShower precision={3} number={expression.value} /> <NumberShower precision={3} number={expression.value} />
</VariableBox> </VariableBox>
); );
}
case "lambda": case "lambda":
return ( return (
<FunctionChart <FunctionChart

View File

@ -7,7 +7,10 @@ let dateDispatch = (call: ExpressionValue.functionCall, env: DistributionOperati
switch call { switch call {
| ("toString", [EvDate(t)]) => EvString(E.Date.toString(t))->Ok->Some | ("toString", [EvDate(t)]) => EvString(E.Date.toString(t))->Ok->Some
| ("makeDateFromYear", [EvNumber(year)]) => | ("makeDateFromYear", [EvNumber(year)]) =>
EvDate(E.Date.makeWithYM(~year, ~month=0.0, ()))->Ok->Some switch E.Date.makeWithYear(Belt.Float.toInt(year)) {
| Ok(t) => EvDate(t)->Ok->Some
| Error(e) => RETodo(e)->Error->Some
}
| ("fromMilliseconds", [EvNumber(f)]) => EvDate(E.Date.fromFloat(f))->Ok->Some | ("fromMilliseconds", [EvNumber(f)]) => EvDate(E.Date.fromFloat(f))->Ok->Some
| ("toMilliseconds", [EvDate(f)]) => EvNumber(E.Date.toFloat(f))->Ok->Some | ("toMilliseconds", [EvDate(f)]) => EvNumber(E.Date.toFloat(f))->Ok->Some
| ("subtract", [EvDate(d1), EvDate(d2)]) => | ("subtract", [EvDate(d1), EvDate(d2)]) =>
@ -22,14 +25,16 @@ let dateDispatch = (call: ExpressionValue.functionCall, env: DistributionOperati
} }
} }
let durationDispatch = (call: ExpressionValue.functionCall, env: DistributionOperation.env): option< let durationDispatch = (call: ExpressionValue.functionCall, _: DistributionOperation.env): option<
result<expressionValue, QuriSquiggleLang.Reducer_ErrorValue.errorValue>, result<expressionValue, QuriSquiggleLang.Reducer_ErrorValue.errorValue>,
> => { > => {
switch call { switch call {
| ("toString", [EvTimeDuration(t)]) => EvString(E.Duration.toString(t))->Ok->Some | ("toString", [EvTimeDuration(t)]) => EvString(E.Duration.toString(t))->Ok->Some
| ("hours", [EvNumber(f)]) => EvTimeDuration(E.Duration.fromHours(f))->Ok->Some | ("hours", [EvNumber(f)]) => EvTimeDuration(E.Duration.fromHours(f))->Ok->Some
| ("days", [EvNumber(f)]) => EvTimeDuration(E.Duration.fromDays(f))->Ok->Some
| ("years", [EvNumber(f)]) => EvTimeDuration(E.Duration.fromYears(f))->Ok->Some | ("years", [EvNumber(f)]) => EvTimeDuration(E.Duration.fromYears(f))->Ok->Some
| ("toHours", [EvTimeDuration(f)]) => EvNumber(E.Duration.toHours(f))->Ok->Some | ("toHours", [EvTimeDuration(f)]) => EvNumber(E.Duration.toHours(f))->Ok->Some
| ("toDays", [EvTimeDuration(f)]) => EvNumber(E.Duration.toDays(f))->Ok->Some
| ("toYears", [EvTimeDuration(f)]) => EvNumber(E.Duration.toYears(f))->Ok->Some | ("toYears", [EvTimeDuration(f)]) => EvNumber(E.Duration.toYears(f))->Ok->Some
| ( | (
("add" | "subtract" | "multiply" | "divide") as op, ("add" | "subtract" | "multiply" | "divide") as op,

View File

@ -840,7 +840,7 @@ module Duration = {
let minute = Belt.Float.fromInt(60 * 1000) let minute = Belt.Float.fromInt(60 * 1000)
let hour = Belt.Float.fromInt(60 * 60 * 1000) let hour = Belt.Float.fromInt(60 * 60 * 1000)
let day = Belt.Float.fromInt(24 * 60 * 60 * 1000) let day = Belt.Float.fromInt(24 * 60 * 60 * 1000)
let year = Belt.Float.fromInt(24 * 60 * 60 * 1000 * 365) let year = Belt.Float.fromInt(24 * 60 * 60 * 1000) *. 365.25
let fromFloat = (f: float): t => f let fromFloat = (f: float): t => f
let toFloat = (d: t): float => d let toFloat = (d: t): float => d
let fromHours = (h: float): t => h *. hour let fromHours = (h: float): t => h *. hour
@ -849,7 +849,19 @@ module Duration = {
let toHours = (t: t): float => t /. hour let toHours = (t: t): float => t /. hour
let toDays = (t: t): float => t /. day let toDays = (t: t): float => t /. day
let toYears = (t: t): float => t /. year let toYears = (t: t): float => t /. year
let toString = (t: t) => `${Float.with2DigitsPrecision(t)}ms` let toString = (t: t): string => {
if t >= year {
Float.with3DigitsPrecision(t /. year) ++ " years"
} else if t >= day {
Float.with3DigitsPrecision(t /. day) ++ " days"
} else if t >= hour {
Float.with3DigitsPrecision(t /. hour) ++ " hours"
} else if t >= minute {
Float.with3DigitsPrecision(t /. minute) ++ " minutes"
} else {
Float.toFixed(t) ++ "ms"
}
}
let add = (t1, t2): t => t1 +. t2 let add = (t1, t2): t => t1 +. t2
let subtract = (t1, t2): t => t1 -. t2 let subtract = (t1, t2): t => t1 -. t2
let multiply = (t1, t2): t => t1 *. t2 let multiply = (t1, t2): t => t1 *. t2
@ -857,12 +869,24 @@ module Duration = {
} }
module Date = { module Date = {
//The Rescript/JS implementation of Date is pretty mediocre. It would be good to improve upon later.
type t = Js.Date.t type t = Js.Date.t
type year
let makeWithYM = Js.Date.makeWithYM
let toString = Js.Date.toString
let fromFloat = Js.Date.fromFloat
let toFloat = Js.Date.getTime let toFloat = Js.Date.getTime
let getFullYear = Js.Date.getFullYear
//The Js.Date.makeWithYM function accepts a float, but only treats it as a whole number.
//Our version takes an integer to make this distinction clearer.
let makeWithYear = (y: int): result<t, string> => {
if y < 100 {
Error("Year must be over 100")
} else if y > 200000 {
Error("Year must be less than 200000")
} else {
Ok(Js.Date.makeWithYM(~year=Belt.Float.fromInt(y), ~month=0.0, ()))
}
}
let toString = Js.Date.toDateString
let fromFloat = Js.Date.fromFloat
let fmap = (t: t, fn: float => float) => t->toFloat->fn->fromFloat let fmap = (t: t, fn: float => float) => t->toFloat->fn->fromFloat
let subtract = (t1: t, t2: t) => { let subtract = (t1: t, t2: t) => {
let (f1, f2) = (toFloat(t1), toFloat(t2)) let (f1, f2) = (toFloat(t1), toFloat(t2))