Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Power-Fx WORKDAY function #2638

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,11 @@ internal static class TexlStrings
public static StringGetter DateAddArg2 = (b) => StringResources.Get("DateAddArg2", b);
public static StringGetter DateAddArg3 = (b) => StringResources.Get("DateAddArg3", b);

public static StringGetter AboutWorkday = (b) => StringResources.Get("AboutWorkday", b);
public static StringGetter WorkdayArg1 = (b) => StringResources.Get("WorkdayArg1", b);
public static StringGetter WorkdayArg2 = (b) => StringResources.Get("WorkdayArg2", b);
public static StringGetter WorkdayArg3 = (b) => StringResources.Get("WorkdayArg3", b);

public static StringGetter AboutDateAddT = (b) => StringResources.Get("AboutDateAddT", b);
public static StringGetter DateAddTArg1 = (b) => StringResources.Get("DateAddTArg1", b);
public static StringGetter DateAddTArg2 = (b) => StringResources.Get("DateAddTArg2", b);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ internal class BuiltinFunctionsCore
public static readonly TexlFunction Date = _library.Add(new DateFunction());
public static readonly TexlFunction DateAdd = _library.Add(new DateAddFunction());
public static readonly TexlFunction DateAddT = _library.Add(new DateAddTFunction());
public static readonly TexlFunction Workday = _library.Add(new WorkdayFunction());
public static readonly TexlFunction DateDiff = _library.Add(new DateDiffFunction());
public static readonly TexlFunction DateDiffT = _library.Add(new DateDiffTFunction());
public static readonly TexlFunction DateTime = _library.Add(new DateTimeFunction());
Expand Down
57 changes: 55 additions & 2 deletions src/libraries/Microsoft.PowerFx.Core/Texl/Builtins/DateTime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -620,8 +620,61 @@ public override bool CheckTypes(CheckTypesContext context, TexlNode[] args, DTyp

return fValid;
}
}
}

// Workday(timestamp: d, delta: n) : d
internal sealed class WorkdayFunction : BuiltinFunction
{
public override bool IsSelfContained => true;

public WorkdayFunction()
: base("Workday", TexlStrings.AboutWorkday, FunctionCategories.DateTime, DType.DateTime, 0, 2, 2, DType.DateTime, DType.Number)
{
}

public override IEnumerable<TexlStrings.StringGetter[]> GetSignatures()
{
yield return new[] { TexlStrings.WorkdayArg1, TexlStrings.WorkdayArg2 };
}

public override bool CheckTypes(CheckTypesContext context, TexlNode[] args, DType[] argTypes, IErrorContainer errors, out DType returnType, out Dictionary<TexlNode, DType> nodeToCoercedTypeMap)
{
Contracts.AssertValue(args);
Contracts.AssertAllValues(args);
Contracts.AssertValue(argTypes);
Contracts.Assert(args.Length == argTypes.Length);
Contracts.AssertValue(errors);
Contracts.Assert(MinArity <= args.Length && args.Length <= MaxArity);

var fValid = base.CheckTypes(context, args, argTypes, errors, out returnType, out nodeToCoercedTypeMap);
Contracts.Assert(returnType == DType.DateTime);

var type0 = argTypes[0];

if (fValid)
{
if (type0.Kind == DKind.Date || type0.Kind == DKind.DateTime || type0.Kind == DKind.Time)
{
// Arg0 should be a Time, DateTime or Date.
returnType = type0;
}
else if (nodeToCoercedTypeMap != null && nodeToCoercedTypeMap.TryGetValue(args[0], out var coercedType))
{
// Or a type that can be coerced to it
returnType = coercedType;
}
else
{
fValid = false;
errors.EnsureError(DocumentErrorSeverity.Severe, args[0], TexlStrings.ErrDateExpected);
returnType = ReturnType;
}
}

return fValid;
}
}

// DateDiff(startdate: d, enddate : d, [ unit: TimeUnits ]) : n
internal sealed class DateDiffFunction : BuiltinFunction
{
Expand All @@ -636,7 +689,7 @@ public DateDiffFunction()

public override IEnumerable<TexlStrings.StringGetter[]> GetSignatures()
{
yield return new[] { TexlStrings.DateDiffArg1, TexlStrings.DateDiffArg2 };
yield return new[] { TexlStrings.DateDiffArg1, TexlStrings.DateDiffArg2 };
yield return new[] { TexlStrings.DateDiffArg1, TexlStrings.DateDiffArg2, TexlStrings.DateDiffArg3 };
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,22 @@ static Library()
returnBehavior: ReturnBehavior.ReturnBlankIfAnyArgIsBlank,
targetFunction: DateAdd)
},
{
BuiltinFunctionsCore.Workday,
StandardErrorHandling<FormulaValue>(
BuiltinFunctionsCore.Workday.Name,
expandArguments: InsertDefaultValues(outputArgsCount: 2, fillWith: new BlankValue(IRContext.NotInSource(FormulaType.Blank))),
replaceBlankValues: ReplaceBlankWith(
new DateTimeValue(IRContext.NotInSource(FormulaType.DateTime), _epoch),
new NumberValue(IRContext.NotInSource(FormulaType.Number), 0)),
checkRuntimeTypes: ExactSequence(
DateOrTimeOrDateTime,
ExactValueTypeOrBlank<NumberValue>,
StringOrOptionSetBackedByString),
checkRuntimeValues: DeferRuntimeValueChecking,
returnBehavior: ReturnBehavior.ReturnBlankIfAnyArgIsBlank,
targetFunction: Workday)
},
{
BuiltinFunctionsCore.DateDiff,
StandardErrorHandling<FormulaValue>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,68 @@ public static FormulaValue DateAdd(EvalVisitor runner, EvalVisitorContext contex
}
}

public static FormulaValue Workday(EvalVisitor runner, EvalVisitorContext context, IRContext irContext, FormulaValue[] args)
{
var timeZoneInfo = runner.TimeZoneInfo;

DateTime dateTime = runner.GetNormalizedDateTimeAllowTimeValue(args[0]);

int delta;
string timeUnit;

if (args[1] is NumberValue number)
{
delta = (int)number.Value;
timeUnit = "days";
}
else
{
//throw new NotImplementedException();
return CommonErrors.RuntimeTypeMismatch(args[1].IRContext);
}

var useUtcConversion = NeedToConvertToUtc(runner, dateTime, timeUnit);

if (useUtcConversion)
{
dateTime = TimeZoneInfo.ConvertTimeToUtc(dateTime, timeZoneInfo);
}

try
{
// Determine the increment direction (forward or backward)
int increment = delta > 0 ? 1 : -1;

// Add days until the required number of workdays is reached
while (delta != 0)
{
dateTime = dateTime.AddDays(increment);

// If the current date is a weekend, continue without decreasing days
if (dateTime.DayOfWeek == DayOfWeek.Saturday || dateTime.DayOfWeek == DayOfWeek.Sunday)
{
continue;
}

// If it's a valid workday, decrement the days
delta -= increment;
}

if (useUtcConversion)
{
dateTime = TimeZoneInfo.ConvertTimeFromUtc(dateTime, timeZoneInfo);
}

dateTime = MakeValidDateTime(runner, dateTime, timeZoneInfo);

return new DateValue(irContext, dateTime);
}
catch
{
return CommonErrors.ArgumentOutOfRange(irContext);
}
}

private static DateTime MakeValidDateTime(EvalVisitor runner, DateTime dateTime, TimeZoneInfo timeZoneInfo)
{
return MakeValidDateTime(runner.TimeZoneInfo, dateTime);
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.bg-BG.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,10 @@
<data name="AboutDateAdd" xml:space="preserve">
<value>Добавя указания брой единици към дадена дата.</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>Добавете брой работни дни преди или след дата.</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>Изчислява разликата между две дати.</value>
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.ca-ES.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,10 @@
<data name="AboutDateAdd" xml:space="preserve">
<value>Afegeix el nombre d'unitats especificat a una data.</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>Afegir el nombre de dies laborables abans o després d’una data.</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>Calcula la diferència entre dues dates.</value>
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.cs-CZ.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,10 @@
<data name="AboutDateAdd" xml:space="preserve">
<value>Přičte ke kalendářnímu datu zadaný počet jednotek.</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>Přidejte počet pracovních dnů před nebo po datu.</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>Vypočítá rozdíl mezi dvěma kalendářními daty.</value>
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.da-DK.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,10 @@
<data name="AboutDateAdd" xml:space="preserve">
<value>Føj det angivne antal enheder til en dato.</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>Tilføj antal arbejdsdage før eller efter en dato.</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>Beregn forskellen mellem de to datoer.</value>
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.de-DE.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2587,6 +2587,10 @@
<value>Fügt einem Datum die angegebene Anzahl Einheiten hinzu.</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>Anzahl der Arbeitstage vor oder nach einem Datum hinzufügen.</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>Berechnet die Differenz zwischen zwei Datumswerten.</value>

Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.el-GR.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,10 @@
<data name="AboutDateAdd" xml:space="preserve">
<value>Προσθέτει τον καθορισμένο αριθμό μονάδων σε μια ημερομηνία.</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>Добавяне на брой работни дни преди или след дата.</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>Υπολογίζει τη διαφορά μεταξύ δύο ημερομηνιών.</value>
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.en-US.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2587,6 +2587,10 @@
<value>Add the specified number of units to a date.</value>
<comment>Description of 'DateAdd' function.</comment>
</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>Add number of working days before or after a date.</value>
<comment>Description of 'Workday' function.</comment>
</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>Calculate the difference between two dates.</value>
<comment>Description of 'DateDiff' function</comment>
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.es-ES.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,10 @@
<data name="AboutDateAdd" xml:space="preserve">
<value>Agregue el número especificado de unidades a una fecha.</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>Agregar el número de días hábiles antes o después de una fecha.</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>Calcule la diferencia entre dos fechas.</value>
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.et-EE.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,10 @@
<data name="AboutDateAdd" xml:space="preserve">
<value>Lisab kuupäevale määratud arvu ühikuid.</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>Lisage tööpäevade arv enne või pärast kuupäeva.</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>Arvutab kahe kuupäeva vahelise erinevuse.</value>
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.eu-ES.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,10 @@
<data name="AboutDateAdd" xml:space="preserve">
<value>Gehitu zehaztutako unitate kopurua data batean.</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>Gehitu lanegun kopurua data baten aurretik edo ondoren.</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>Kalkulatu bi daten arteko aldea.</value>
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.fi-FI.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,10 @@
<data name="AboutDateAdd" xml:space="preserve">
<value>Lisää määritetty määrä yksiköitä päivämäärään.</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>Päivämäärää edeltävien tai sen jälkeisten työpäivien määrän lisääminen.</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>Laske kahden päivämäärän välinen ero.</value>
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.fr-FR.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,10 @@
<data name="AboutDateAdd" xml:space="preserve">
<value>Ajouter le nombre spécifié d’unités à une date.</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>Ajouter le nombre de jours ouvrables avant ou après une date.</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>Calculer l’écart entre deux dates.</value>
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.gl-ES.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,10 @@
<data name="AboutDateAdd" xml:space="preserve">
<value>Engade o número especificado de unidades a unha data.</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>Engadir número de días laborables antes ou despois dunha data.</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>Calcule a diferenza entre dúas datas.</value>
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.hi-IN.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,10 @@
<data name="AboutDateAdd" xml:space="preserve">
<value>किसी दिनांक की निर्दिष्ट इकाईयों की संख्या जोड़ता है.</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>तारीख से पहले या बाद में कार्य दिवसों की संख्या जोड़ें.</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>दो दिनांकों के बीच अंतर की गणना करता है.</value>
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.hr-HR.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,10 @@
<data name="AboutDateAdd" xml:space="preserve">
<value>Dodavanje navedenog broja jedinica u datum.</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>Dodajte broj radnih dana prije ili poslije datuma.</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>Izračun razlike između dva datuma.</value>
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.hu-HU.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,10 @@
<data name="AboutDateAdd" xml:space="preserve">
<value>Hozzáadja a megadott számú egységet egy dátumhoz.</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>Adja meg a munkanapok számát egy dátum előtt vagy után.</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>Kiszámítja a különbséget két dátum között.</value>
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.id-ID.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,10 @@
<data name="AboutDateAdd" xml:space="preserve">
<value>Menambahkan jumlah unit yang ditentukan untuk tanggal.</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>Tambahkan jumlah hari kerja sebelum atau sesudah tanggal.</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>Menghitung Selisih dua tanggal.</value>
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.it-IT.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,10 @@
<data name="AboutDateAdd" xml:space="preserve">
<value>Aggiunge il numero di unità specificato a una data.</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>Aggiungi il numero di giorni lavorativi prima o dopo una data.</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>Calcola la differenza tra due date.</value>
Expand Down
4 changes: 4 additions & 0 deletions src/strings/PowerFxResources.ja-JP.resx
Original file line number Diff line number Diff line change
Expand Up @@ -2586,6 +2586,10 @@
<data name="AboutDateAdd" xml:space="preserve">
<value>日付に、指定数の単位を追加します。</value>

</data>
<data name="AboutWorkday_date" xml:space="preserve">
<value>日付の前後の稼働日数を追加します。</value>

</data>
<data name="AboutDateDiff" xml:space="preserve">
<value>2 つの日付の差を計算します。</value>
Expand Down
Loading
Loading