зеркало из https://github.com/microsoft/Power-Fx.git
Out of range number to date returns an error (#1100)
Issue #1098 Out of range number to date returns an error instead of throwing an exception.
This commit is contained in:
Родитель
8071b3b3fc
Коммит
83e3f81772
|
@ -556,6 +556,7 @@ namespace Microsoft.PowerFx.Core.Localization
|
|||
public static ErrorResourceKey ErrTextTooLarge = new ErrorResourceKey("ErrTextTooLarge");
|
||||
public static ErrorResourceKey ErrTextFormatTooLarge = new ErrorResourceKey("ErrTextFormatTooLarge");
|
||||
public static ErrorResourceKey ErrTextInvalidFormat = new ErrorResourceKey("ErrTextInvalidFormat");
|
||||
public static ErrorResourceKey ErrTextInvalidArgDateTime = new ErrorResourceKey("ErrTextInvalidArgDateTime");
|
||||
public static ErrorResourceKey ErrBooleanExpected = new ErrorResourceKey("ErrBooleanExpected");
|
||||
public static ErrorResourceKey ErrOnlyOneViewExpected = new ErrorResourceKey("ErrOnlyOneViewExpected");
|
||||
public static ErrorResourceKey ErrViewFromCurrentTableExpected = new ErrorResourceKey("ErrViewFromCurrentTableExpected");
|
||||
|
|
|
@ -18,6 +18,7 @@ using Microsoft.PowerFx.Core.Types.Enums;
|
|||
using Microsoft.PowerFx.Core.Utils;
|
||||
using Microsoft.PowerFx.Interpreter;
|
||||
using Microsoft.PowerFx.Types;
|
||||
using static Microsoft.PowerFx.Core.Localization.TexlStrings;
|
||||
|
||||
namespace Microsoft.PowerFx.Functions
|
||||
{
|
||||
|
@ -259,6 +260,7 @@ namespace Microsoft.PowerFx.Functions
|
|||
{
|
||||
// It's a number, formatted as date/time. Let's convert it to a date/time value first
|
||||
var newDateTime = Library.NumberToDateTime(formatInfo, IRContext.NotInSource(FormulaType.DateTime), num);
|
||||
|
||||
return TryExpandDateTimeExcelFormatSpecifiersToStringValue(irContext, formatString, "g", newDateTime.GetConvertedValue(timeZoneInfo), culture, formatInfo.CancellationToken, out result);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.PowerFx.Core.Errors;
|
||||
using Microsoft.PowerFx.Core.IR;
|
||||
using Microsoft.PowerFx.Core.IR.Nodes;
|
||||
|
@ -432,12 +431,21 @@ namespace Microsoft.PowerFx.Functions
|
|||
|
||||
public static DateTimeValue NumberToDateTime(FormattingInfo formatInfo, IRContext irContext, NumberValue value)
|
||||
{
|
||||
var n = value.Value;
|
||||
var date = _epoch.AddDays(n);
|
||||
try
|
||||
{
|
||||
var n = value.Value;
|
||||
var date = _epoch.AddDays(n);
|
||||
|
||||
date = MakeValidDateTime(formatInfo.TimeZoneInfo, date);
|
||||
date = MakeValidDateTime(formatInfo.TimeZoneInfo, date);
|
||||
|
||||
return new DateTimeValue(irContext, date);
|
||||
return new DateTimeValue(irContext, date);
|
||||
}
|
||||
catch (ArgumentOutOfRangeException)
|
||||
{
|
||||
(var shortMessage, _) = ErrorUtils.GetLocalizedErrorContent(TexlStrings.ErrTextInvalidArgDateTime, formatInfo.CultureInfo, out _);
|
||||
|
||||
throw new CustomFunctionErrorException(shortMessage, ErrorKind.InvalidArgument);
|
||||
}
|
||||
}
|
||||
|
||||
public static FormulaValue DateToDateTime(EvalVisitor runner, EvalVisitorContext context, IRContext irContext, FormulaValue[] args)
|
||||
|
|
|
@ -1849,6 +1849,10 @@
|
|||
<value>Invalid format.</value>
|
||||
<comment>Error Message returned by the Text function when the format passed to it is invalid.</comment>
|
||||
</data>
|
||||
<data name="ErrTextInvalidArgDateTime" xml:space="preserve">
|
||||
<value>The argument does not represent a valid date or time value.</value>
|
||||
<comment>Error Message returned by the Text function when the number to date format exceeds the max days to add.</comment>
|
||||
</data>
|
||||
<data name="ErrInvalidDataSource" xml:space="preserve">
|
||||
<value>This Data source is invalid. Please fix the error in "Data sources" pane by clicking "Content -> Data sources" or "View -> Options"</value>
|
||||
<comment>Error Message.</comment>
|
||||
|
|
|
@ -636,6 +636,10 @@ Error({Kind:ErrorKind.InvalidArgument})
|
|||
>> Text(30470.01953125, "YYYY-MM-DD HH:MM:SS.00000000")
|
||||
Error({Kind:ErrorKind.InvalidArgument})
|
||||
|
||||
// Number 4492800 exceeds the max days that DateTime.AddDays can take.
|
||||
>> Text(4492800,DateTimeFormat.LongDate)
|
||||
Error({Kind:ErrorKind.InvalidArgument})
|
||||
|
||||
// C# interpreter can handle up to 7 decimals after the second
|
||||
>> Text(DateTimeValue("2023-01-03 00:01:02.3456789"), "yyyy-mm-dd hh:mm:ss.0000000")
|
||||
"2023-01-03 00:01:02.3456789"
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
// Licensed under the MIT license.
|
||||
|
||||
using System;
|
||||
using System.Numerics;
|
||||
using Microsoft.PowerFx;
|
||||
using Microsoft.PowerFx.Core.Tests;
|
||||
using Microsoft.PowerFx.Interpreter;
|
||||
using Microsoft.PowerFx.Types;
|
||||
using Xunit;
|
||||
|
||||
|
@ -53,6 +55,17 @@ namespace Microsoft.PowerFx.Tests
|
|||
TryCoerceToTargetTypes(FormulaValue.New(DateTime.Parse(value)), exprBool, exprNumber, exprStr, exprDateTime);
|
||||
}
|
||||
|
||||
// From number to datetime, expects an exception
|
||||
[Theory]
|
||||
[InlineData(4496200)]
|
||||
[InlineData(4E8)]
|
||||
public void TryCoerceFromNumberExpectsExceptionTest(double value)
|
||||
{
|
||||
var inputValue = FormulaValue.New(value);
|
||||
|
||||
Assert.Throws<CustomFunctionErrorException>(() => inputValue.TryCoerceTo(out DateTimeValue resultDateTime));
|
||||
}
|
||||
|
||||
private void TryCoerceToTargetTypes(FormulaValue inputValue, string exprBool, string exprNumber, string exprStr, string exprDateTime)
|
||||
{
|
||||
bool isSucceeded = inputValue.TryCoerceTo(out BooleanValue resultBoolean);
|
||||
|
@ -79,16 +92,16 @@ namespace Microsoft.PowerFx.Tests
|
|||
Assert.Null(resultNumber);
|
||||
}
|
||||
|
||||
isSucceeded = inputValue.TryCoerceTo(out StringValue resultString);
|
||||
isSucceeded = inputValue.TryCoerceTo(out StringValue resultValue);
|
||||
if (exprStr != null)
|
||||
{
|
||||
Assert.True(isSucceeded);
|
||||
Assert.Equal(exprStr, resultString.Value);
|
||||
Assert.Equal(exprStr, resultValue.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.False(isSucceeded);
|
||||
Assert.Null(resultString);
|
||||
Assert.IsType<ErrorValue>(resultValue);
|
||||
}
|
||||
|
||||
isSucceeded = inputValue.TryCoerceTo(out DateTimeValue resultDateTime);
|
||||
|
|
Загрузка…
Ссылка в новой задаче