private static FormulaValue AddDateTimeAndDay(IRContext irContext, FormulaValue[] args) { DateTime arg0; switch (args[0]) { case DateTimeValue dtv: arg0 = dtv.Value; break; case DateValue dv: arg0 = dv.Value; break; default: return(CommonErrors.RuntimeTypeMismatch(irContext)); } var arg1 = (NumberValue)args[1]; try { var result = arg0.AddDays(arg1.Value); return(new DateTimeValue(irContext, result)); } catch { return(CommonErrors.ArgumentOutOfRange(irContext)); } }
public static FormulaValue Month(IRContext irContext, FormulaValue[] args) { if (args[0] is BlankValue) { return(new NumberValue(irContext, 1)); } DateTime arg0; switch (args[0]) { case DateTimeValue dtv: arg0 = dtv.Value; break; case DateValue dv: arg0 = dv.Value; break; default: return(CommonErrors.RuntimeTypeMismatch(irContext)); } var x = arg0.Month; return(new NumberValue(irContext, x)); }
public static FormulaValue Second(IRContext irContext, FormulaValue[] args) { if (args[0] is BlankValue) { return(new NumberValue(irContext, 0)); } TimeSpan arg0; switch (args[0]) { case DateTimeValue dtv: arg0 = dtv.Value.TimeOfDay; break; case TimeValue dv: arg0 = dv.Value; break; default: return(CommonErrors.RuntimeTypeMismatch(irContext)); } var x = arg0.Seconds; return(new NumberValue(irContext, x)); }
// https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/functions/function-datetime-parts public static FormulaValue Year(IRContext irContext, FormulaValue[] args) { if (args[0] is BlankValue) { // TODO: Standardize the number 0 - year 1900 logic return(new NumberValue(irContext, 1900)); } DateTime arg0; switch (args[0]) { case DateTimeValue dtv: arg0 = dtv.Value; break; case DateValue dv: arg0 = dv.Value; break; default: return(CommonErrors.RuntimeTypeMismatch(irContext)); } var x = arg0.Year; return(new NumberValue(irContext, x)); }
private static FormulaValue TimeOrDateTime(IRContext irContext, int index, FormulaValue arg) { if (arg is TimeValue || arg is DateTimeValue || arg is BlankValue || arg is ErrorValue) { return(arg); } return(CommonErrors.RuntimeTypeMismatch(irContext)); }
private static FormulaValue ExactValueType <T>(IRContext irContext, int index, FormulaValue arg) where T : FormulaValue { if (arg is T || arg is ErrorValue) { return(arg); } else { return(CommonErrors.RuntimeTypeMismatch(irContext)); } }
public static FormulaValue SortTable(EvalVisitor runner, SymbolContext symbolContext, IRContext irContext, FormulaValue[] args) { var arg0 = (TableValue)args[0]; var arg1 = (LambdaFormulaValue)args[1]; var arg2 = (StringValue)args[2]; var pairs = arg0.Rows.Select(row => { if (row.IsValue) { var childContext = symbolContext.WithScopeValues(row.Value); return(new KeyValuePair <DValue <RecordValue>, FormulaValue>(row, arg1.Eval(runner, childContext))); } return(new KeyValuePair <DValue <RecordValue>, FormulaValue>(row, row.ToFormulaValue())); }).ToList(); var errors = new List <ErrorValue>(pairs.Select(pair => pair.Value).OfType <ErrorValue>()); var allNumbers = pairs.All(pair => IsValueTypeErrorOrBlank <NumberValue>(pair.Value)); var allStrings = pairs.All(pair => IsValueTypeErrorOrBlank <StringValue>(pair.Value)); var allBooleans = pairs.All(pair => IsValueTypeErrorOrBlank <BooleanValue>(pair.Value)); if (!(allNumbers || allStrings || allBooleans)) { errors.Add(CommonErrors.RuntimeTypeMismatch(irContext)); return(ErrorValue.Combine(irContext, errors)); } if (errors.Count != 0) { return(ErrorValue.Combine(irContext, errors)); } var compareToResultModifier = 1; if (arg2.Value.ToLower() == "descending") { compareToResultModifier = -1; } if (allNumbers) { return(SortValueType <NumberValue, double>(pairs, irContext, compareToResultModifier)); } else if (allStrings) { return(SortValueType <StringValue, string>(pairs, irContext, compareToResultModifier)); } else { return(SortValueType <BooleanValue, bool>(pairs, irContext, compareToResultModifier)); } }
public static FormulaValue DateToDateTime(IRContext irContext, FormulaValue[] args) { switch (args[0]) { case DateTimeValue dtv: return(dtv); case DateValue dv: return(new DateTimeValue(irContext, dv.Value)); default: return(CommonErrors.RuntimeTypeMismatch(irContext)); } }
public static FormulaValue DateTimeToTime(IRContext irContext, FormulaValue[] args) { DateTime arg0; switch (args[0]) { case DateTimeValue dtv: arg0 = dtv.Value; break; case DateValue dv: arg0 = dv.Value; break; default: return(CommonErrors.RuntimeTypeMismatch(irContext)); } var time = arg0.TimeOfDay; return(new TimeValue(irContext, time)); }
public static FormulaValue DateToNumber(IRContext irContext, FormulaValue[] args) { DateTime arg0; switch (args[0]) { case DateTimeValue dtv: arg0 = dtv.Value; break; case DateValue dv: arg0 = dv.Value; break; default: return(CommonErrors.RuntimeTypeMismatch(irContext)); } var diff = arg0.Subtract(_epoch).TotalDays; return(new NumberValue(irContext, diff)); }
private static FormulaValue GeqDate(IRContext irContext, FormulaValue[] args) { DateTime arg0; switch (args[0]) { case DateTimeValue dtv: arg0 = dtv.Value; break; case DateValue dv: arg0 = dv.Value; break; default: return(CommonErrors.RuntimeTypeMismatch(irContext)); } DateTime arg1; switch (args[1]) { case DateTimeValue dtv: arg1 = dtv.Value; break; case DateValue dv: arg1 = dv.Value; break; default: return(CommonErrors.RuntimeTypeMismatch(irContext)); } var result = arg0 >= arg1; return(new BooleanValue(irContext, result)); }
private static FormulaValue DateDifference(IRContext irContext, FormulaValue[] args) { DateTime arg0; switch (args[0]) { case DateTimeValue dtv: arg0 = dtv.Value; break; case DateValue dv: arg0 = dv.Value; break; default: return(CommonErrors.RuntimeTypeMismatch(irContext)); } DateTime arg1; switch (args[1]) { case DateTimeValue dtv: arg1 = dtv.Value; break; case DateValue dv: arg1 = dv.Value; break; default: return(CommonErrors.RuntimeTypeMismatch(irContext)); } var result = arg0.Subtract(arg1); return(new TimeValue(irContext, result)); }
// https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/functions/function-now-today-istoday public static FormulaValue IsToday(IRContext irContext, FormulaValue[] args) { DateTime arg0; switch (args[0]) { case DateTimeValue dtv: arg0 = dtv.Value; break; case DateValue dv: arg0 = dv.Value; break; default: return(CommonErrors.RuntimeTypeMismatch(irContext)); } var now = DateTime.Today; bool same = (arg0.Year == now.Year) && (arg0.Month == now.Month) && (arg0.Day == now.Day); return(new BooleanValue(irContext, same)); }
public static Func <EvalVisitor, SymbolContext, IRContext, TableValue[], FormulaValue> StandardSingleColumnTable <T>(Func <EvalVisitor, SymbolContext, IRContext, T[], FormulaValue> targetFunction) where T : FormulaValue { return((runner, symbolContext, irContext, args) => { var tableType = (TableType)irContext.ResultType; var resultType = tableType.ToRecord(); var itemType = resultType.GetFieldType(BuiltinFunction.OneColumnTableResultNameStr); var arg0 = args[0]; var resultRows = new List <DValue <RecordValue> >(); foreach (var row in arg0.Rows) { if (row.IsValue) { var value = row.Value.GetField(BuiltinFunction.ColumnName_ValueStr); NamedValue namedValue; namedValue = value switch { T t => new NamedValue(BuiltinFunction.OneColumnTableResultNameStr, targetFunction(runner, symbolContext, IRContext.NotInSource(itemType), new T[] { t })), BlankValue bv => new NamedValue(BuiltinFunction.OneColumnTableResultNameStr, bv), ErrorValue ev => new NamedValue(BuiltinFunction.OneColumnTableResultNameStr, ev), _ => new NamedValue(BuiltinFunction.OneColumnTableResultNameStr, CommonErrors.RuntimeTypeMismatch(IRContext.NotInSource(itemType))) }; var record = new InMemoryRecordValue(IRContext.NotInSource(resultType), new List <NamedValue>() { namedValue }); resultRows.Add(DValue <RecordValue> .Of(record)); } else if (row.IsBlank) { resultRows.Add(DValue <RecordValue> .Of(row.Blank)); } else { resultRows.Add(DValue <RecordValue> .Of(row.Error)); } } return new InMemoryTableValue(irContext, resultRows); }); }
// https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/show-text-dates-times // https://docs.microsoft.com/en-us/powerapps/maker/canvas-apps/functions/function-dateadd-datediff public static FormulaValue DateAdd(IRContext irContext, FormulaValue[] args) { DateTime datetime; switch (args[0]) { case DateTimeValue dtv: datetime = dtv.Value; break; case DateValue dv: datetime = dv.Value; break; default: return(CommonErrors.RuntimeTypeMismatch(irContext)); } var delta = (NumberValue)args[1]; var units = (StringValue)args[2]; try { DateTime newDate; switch (units.Value.ToLower()) { case "milliseconds": newDate = datetime.AddMilliseconds(delta.Value); break; case "seconds": newDate = datetime.AddSeconds(delta.Value); break; case "minutes": newDate = datetime.AddMinutes(delta.Value); break; case "hours": newDate = datetime.AddHours(delta.Value); break; case "days": newDate = datetime.AddDays(delta.Value); break; case "months": newDate = datetime.AddMonths((int)delta.Value); break; case "quarters": newDate = datetime.AddMonths((int)delta.Value * 3); break; case "years": newDate = datetime.AddYears((int)delta.Value); break; default: // TODO: Task 10723372: Implement Unit Functionality in DateAdd, DateDiff Functions return(CommonErrors.NotYetImplementedError(irContext, "DateAdd Only supports Days for the unit field")); } if (args[0] is DateTimeValue) { return(new DateTimeValue(irContext, newDate)); } else { return(new DateValue(irContext, newDate.Date)); } } catch { return(CommonErrors.ArgumentOutOfRange(irContext)); } }
public static FormulaValue DateDiff(IRContext irContext, FormulaValue[] args) { DateTime start; switch (args[0]) { case DateTimeValue dtv: start = dtv.Value; break; case DateValue dv: start = dv.Value; break; default: return(CommonErrors.RuntimeTypeMismatch(irContext)); } DateTime end; switch (args[1]) { case DateTimeValue dtv: end = dtv.Value; break; case DateValue dv: end = dv.Value; break; default: return(CommonErrors.RuntimeTypeMismatch(irContext)); } var units = (StringValue)args[2]; TimeSpan diff = end - start; // The function DateDiff only returns a whole number of the units being subtracted, and the precision is given in the unit specified. switch (units.Value.ToLower()) { case "milliseconds": double milliseconds = Math.Floor(diff.TotalMilliseconds); return(new NumberValue(irContext, milliseconds)); case "seconds": double seconds = Math.Floor(diff.TotalSeconds); return(new NumberValue(irContext, seconds)); case "minutes": double minutes = Math.Floor(diff.TotalMinutes); return(new NumberValue(irContext, minutes)); case "hours": double hours = Math.Floor(diff.TotalHours); return(new NumberValue(irContext, hours)); case "days": double days = Math.Floor(diff.TotalDays); return(new NumberValue(irContext, days)); case "months": double months = (end.Year - start.Year) * 12 + end.Month - start.Month; return(new NumberValue(irContext, months)); case "quarters": double quarters = (end.Year - start.Year) * 4 + Math.Floor(end.Month / 3.0) - Math.Floor(start.Month / 3.0); return(new NumberValue(irContext, quarters)); case "years": double years = end.Year - start.Year; return(new NumberValue(irContext, years)); default: // TODO: Task 10723372: Implement Unit Functionality in DateAdd, DateDiff Functions return(CommonErrors.NotYetImplementedError(irContext, "DateDiff Only supports Days for the unit field")); } }