コード例 #1
0
ファイル: LibraryOperators.cs プロジェクト: jgrisham/Power-Fx
        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));
            }
        }
コード例 #2
0
ファイル: LibraryDate.cs プロジェクト: jgrisham/Power-Fx
        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));
        }
コード例 #3
0
ファイル: LibraryDate.cs プロジェクト: jgrisham/Power-Fx
        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));
        }
コード例 #4
0
ファイル: LibraryDate.cs プロジェクト: jgrisham/Power-Fx
        // 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));
        }
コード例 #5
0
 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));
 }
コード例 #6
0
 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));
     }
 }
コード例 #7
0
ファイル: LibraryTable.cs プロジェクト: jgrisham/Power-Fx
        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));
            }
        }
コード例 #8
0
ファイル: LibraryUnary.cs プロジェクト: jgrisham/Power-Fx
        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));
            }
        }
コード例 #9
0
ファイル: LibraryUnary.cs プロジェクト: jgrisham/Power-Fx
        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));
        }
コード例 #10
0
ファイル: LibraryUnary.cs プロジェクト: jgrisham/Power-Fx
        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));
        }
コード例 #11
0
ファイル: LibraryOperators.cs プロジェクト: jgrisham/Power-Fx
        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));
        }
コード例 #12
0
ファイル: LibraryOperators.cs プロジェクト: jgrisham/Power-Fx
        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));
        }
コード例 #13
0
ファイル: LibraryDate.cs プロジェクト: jgrisham/Power-Fx
        // 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));
        }
コード例 #14
0
        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);
            });
        }
コード例 #15
0
ファイル: LibraryDate.cs プロジェクト: jgrisham/Power-Fx
        // 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));
            }
        }
コード例 #16
0
ファイル: LibraryDate.cs プロジェクト: jgrisham/Power-Fx
        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"));
            }
        }