From ad29967fbd5c5eb8cbc99409862ebc9fb06f255e Mon Sep 17 00:00:00 2001 From: Shuai Wang Date: Sun, 19 Jan 2020 22:51:42 +0800 Subject: [PATCH 1/8] fix datetime converter --- .../src/builtInFunction.ts | 10 +- .../src/formatConverter.ts | 497 ++++++++++++++++++ .../tests/expression.test.js | 1 + 3 files changed, 507 insertions(+), 1 deletion(-) create mode 100644 libraries/botframework-expressions/src/formatConverter.ts diff --git a/libraries/botframework-expressions/src/builtInFunction.ts b/libraries/botframework-expressions/src/builtInFunction.ts index 7e7ef84470..2f2dbd7e0a 100644 --- a/libraries/botframework-expressions/src/builtInFunction.ts +++ b/libraries/botframework-expressions/src/builtInFunction.ts @@ -18,6 +18,7 @@ import { EvaluateExpressionDelegate, ExpressionEvaluator, ValidateExpressionDele import { ExpressionType } from './expressionType'; import { Extensions } from './extensions'; import { TimeZoneConverter } from './timeZoneConverter'; +import { convertCSharpDateTimeToMomentJS } from './formatConverter'; import { MemoryInterface, SimpleObjectMemory, ComposedMemory } from './memory'; /** @@ -620,7 +621,14 @@ export class BuiltInFunctions { } public static timestampFormatter(formatter: string): string { - return formatter.replace(/dd/g, 'DD').replace(/yyyy/g, 'YYYY').replace(/d/g, 'D').replace(/y/g, 'Y'); + let result = formatter; + try { + result = convertCSharpDateTimeToMomentJS(formatter); + } catch(e) { + // do nothing + } + + return result; } public static timeUnitTransformer(duration: number, cSharpStr: string): { duration: number; tsStr: string } { diff --git a/libraries/botframework-expressions/src/formatConverter.ts b/libraries/botframework-expressions/src/formatConverter.ts new file mode 100644 index 0000000000..675d12b263 --- /dev/null +++ b/libraries/botframework-expressions/src/formatConverter.ts @@ -0,0 +1,497 @@ +enum State { + None, + LowerD1, + LowerD2, + LowerD3, + LowerD4, + LowerF1, + LowerF2, + LowerF3, + LowerF4, + LowerF5, + LowerF6, + LowerF7, + CapitalF1, + CapitalF2, + CapitalF3, + CapitalF4, + CapitalF5, + CapitalF6, + CapitalF7, + LowerG, + LowerH1, + LowerH2, + CapitalH1, + CapitalH2, + CapitalK, + LowerM1, + LowerM2, + CapitalM1, + CapitalM2, + CapitalM3, + CapitalM4, + LowerS1, + LowerS2, + LowerT1, + LowerT2, + LowerY1, + LowerY2, + LowerY3, + LowerY4, + LowerY5, + LowerZ1, + LowerZ2, + LowerZ3, + InSingleQuoteLiteral, + InDoubleQuoteLiteral, + EscapeSequence, +} + +export function convertCSharpDateTimeToMomentJS(fmtString: string): string { + let fmtResult = ''; + let fmtState: any = State.None; + const fmtTolerant = true; + let lTokenBuffer = ''; + const changeState = (newState): void => { + switch (fmtState) + { + case State.LowerD1: + fmtResult += 'D'; + break; + case State.LowerD2: + fmtResult += 'DD'; + break; + case State.LowerD3: + fmtResult += 'ddd'; + break; + case State.LowerD4: + fmtResult += 'dddd'; + break; + case State.LowerF1: + case State.CapitalF1: + fmtResult += 'S'; + break; + case State.LowerF2: + case State.CapitalF2: + fmtResult += 'SS'; + break; + case State.LowerF3: + case State.CapitalF3: + fmtResult += 'SSS'; + break; + case State.LowerF4: + case State.CapitalF4: + fmtResult += 'SSSS'; + break; + case State.LowerF5: + case State.CapitalF5: + fmtResult += 'SSSSS'; + break; + case State.LowerF6: + case State.CapitalF6: + fmtResult += 'SSSSSS'; + break; + case State.LowerF7: + case State.CapitalF7: + fmtResult += 'SSSSSSS'; + break; + case State.LowerG: + throw Error('Era not supported in MomentJS'); + case State.LowerH1: + fmtResult += 'h'; + break; + case State.LowerH2: + fmtResult += 'hh'; + break; + case State.CapitalH1: + fmtResult += 'H'; + break; + case State.CapitalH2: + fmtResult += 'HH'; + break; + case State.LowerM1: + fmtResult += 'm'; + break; + case State.LowerM2: + fmtResult += 'mm'; + break; + case State.CapitalM1: + fmtResult += 'M'; + break; + case State.CapitalM2: + fmtResult += 'MM'; + break; + case State.CapitalM3: + fmtResult += 'MMM'; + break; + case State.CapitalM4: + fmtResult += 'MMMM'; + break; + case State.LowerS1: + fmtResult += 's'; + break; + case State.LowerS2: + fmtResult += 'ss'; + break; + case State.LowerT1: + if (fmtTolerant) + { + fmtResult += 'A'; + } + else + { + throw Error('Single Letter AM/PM not supported in MomentJS'); + } + break; + case State.LowerT2: + fmtResult += 'A'; + break; + case State.LowerY1: + if (fmtTolerant) + { + fmtResult += 'YY'; + } + else + { + throw Error('Single Letter Year not supported in MomentJS'); + } + break; + case State.LowerY2: + fmtResult += 'YY'; + break; + case State.LowerY3: + if (fmtTolerant) + { + fmtResult += 'YYYY'; + } + else + { + throw Error('Three Letter Year not supported in MomentJS'); + } + break; + case State.LowerY4: + fmtResult += 'YYYY'; + break; + case State.LowerY5: + if (fmtTolerant) + { + fmtResult += 'Y'; + } + else + { + throw Error('Five or more Letter Year not supported in MomentJS'); + } + break; + case State.LowerZ1: + case State.LowerZ2: + if (fmtTolerant) + { + fmtResult += 'ZZ'; + } + else + { + throw Error('Hours offset not supported in MomentJS'); + } + break; + case State.LowerZ3: + fmtResult += 'Z'; + break; + case State.InSingleQuoteLiteral: + case State.InDoubleQuoteLiteral: + case State.EscapeSequence: + for (const lCharacter of lTokenBuffer) + { + fmtResult += lCharacter; + } + break; + } + + lTokenBuffer = ''; + fmtState = newState; + }; + + for(const character of fmtString) { + if (fmtState === State.EscapeSequence) + { + lTokenBuffer += character; + changeState(State.None); + } + else if (fmtState === State.InDoubleQuoteLiteral) + { + if (character == '\`') + { + changeState(State.None); + } + else + { + lTokenBuffer += character; + } + } + else if (fmtState == State.InSingleQuoteLiteral) + { + if (character == '\'') + { + changeState(State.None); + } + else + { + lTokenBuffer += character; + } + } + else + { + switch (character) + { + case 'd': + switch (fmtState) + { + case State.LowerD1: + fmtState = State.LowerD2; + break; + case State.LowerD2: + fmtState = State.LowerD3; + break; + case State.LowerD3: + fmtState = State.LowerD4; + break; + case State.LowerD4: + break; + default: + changeState(State.LowerD1); + break; + } + break; + case 'f': + switch (fmtState) + { + case State.LowerF1: + fmtState = State.LowerF2; + break; + case State.LowerF2: + fmtState = State.LowerF3; + break; + case State.LowerF3: + fmtState = State.LowerF4; + break; + case State.LowerF4: + fmtState = State.LowerF5; + break; + case State.LowerF5: + fmtState = State.LowerF6; + break; + case State.LowerF6: + fmtState = State.LowerF7; + break; + case State.LowerF7: + break; + default: + changeState(State.LowerF1); + break; + } + break; + case 'F': + switch (fmtState) + { + case State.CapitalF1: + fmtState = State.CapitalF2; + break; + case State.CapitalF2: + fmtState = State.CapitalF3; + break; + case State.CapitalF3: + fmtState = State.CapitalF4; + break; + case State.CapitalF4: + fmtState = State.CapitalF5; + break; + case State.CapitalF5: + fmtState = State.CapitalF6; + break; + case State.CapitalF6: + fmtState = State.CapitalF7; + break; + case State.CapitalF7: + break; + default: + changeState(State.CapitalF1); + break; + } + break; + case 'g': + switch (fmtState) + { + case State.LowerG: + break; + default: + changeState(State.LowerG); + break; + } + break; + case 'h': + switch (fmtState) + { + case State.LowerH1: + fmtState = State.LowerH2; + break; + case State.LowerH2: + break; + default: + changeState(State.LowerH1); + break; + } + break; + case 'H': + switch (fmtState) + { + case State.CapitalH1: + fmtState = State.CapitalH2; + break; + case State.CapitalH2: + break; + default: + changeState(State.CapitalH1); + break; + } + break; + case 'K': + changeState(State.None); + if (fmtTolerant) + { + fmtResult += `Z`; + } + else + { + throw Error(`TimeZoneInformation not supported in MomentJS`); + } + break; + case 'm': + switch (fmtState) + { + case State.LowerM1: + fmtState = State.LowerM2; + break; + case State.LowerM2: + break; + default: + changeState(State.LowerM1); + break; + } + break; + case 'M': + switch (fmtState) + { + case State.CapitalM1: + fmtState = State.CapitalM2; + break; + case State.CapitalM2: + fmtState = State.CapitalM3; + break; + case State.CapitalM3: + fmtState = State.CapitalM4; + break; + case State.CapitalM4: + break; + default: + changeState(State.CapitalM1); + break; + } + break; + case 's': + switch (fmtState) + { + case State.LowerS1: + fmtState = State.LowerS2; + break; + case State.LowerS2: + break; + default: + changeState(State.LowerS1); + break; + } + break; + case 't': + switch (fmtState) + { + case State.LowerT1: + fmtState = State.LowerT2; + break; + case State.LowerT2: + break; + default: + changeState(State.LowerT1); + break; + } + break; + case 'y': + switch (fmtState) + { + case State.LowerY1: + fmtState = State.LowerY2; + break; + case State.LowerY2: + fmtState = State.LowerY3; + break; + case State.LowerY3: + fmtState = State.LowerY4; + break; + case State.LowerY4: + fmtState = State.LowerY5; + break; + case State.LowerY5: + break; + default: + changeState(State.LowerY1); + break; + } + break; + case 'z': + switch (fmtState) + { + case State.LowerZ1: + fmtState = State.LowerZ2; + break; + case State.LowerZ2: + fmtState = State.LowerZ3; + break; + case State.LowerZ3: + break; + default: + changeState(State.LowerZ1); + break; + } + break; + case ':': + changeState(State.None); + fmtResult += ':'; + break; + case '/': + changeState(State.None); + fmtResult += ':'; + break; + case '\`': + changeState(State.InDoubleQuoteLiteral); + break; + case '\'': + changeState(State.InSingleQuoteLiteral); + break; + case '%': + changeState(State.None); + break; + case '\\': + changeState(State.EscapeSequence); + break; + default: + changeState(State.None); + fmtResult += character; + break; + } + } + } + + if (fmtState == State.EscapeSequence || fmtState == State.InDoubleQuoteLiteral || fmtState == State.InSingleQuoteLiteral){ + throw Error(`Invalid Format String`); + } + + changeState(State.None); + return fmtResult; +} \ No newline at end of file diff --git a/libraries/botframework-expressions/tests/expression.test.js b/libraries/botframework-expressions/tests/expression.test.js index f346cd1075..8f73680e27 100644 --- a/libraries/botframework-expressions/tests/expression.test.js +++ b/libraries/botframework-expressions/tests/expression.test.js @@ -285,6 +285,7 @@ const dataSource = [ ['utcNow(\'MM-DD-YY\')', moment(new Date().toISOString()).format('MM-DD-YY')], ['formatDateTime(notISOTimestamp)', '2018-03-15T13:00:00.000Z'], ['formatDateTime(notISOTimestamp, \'MM-dd-yy\')', '03-15-18'], + ['formatDateTime(notISOTimestamp, \'ddd\')', '03-15-18'], ['formatDateTime(\'2018-03-15\')', '2018-03-15T00:00:00.000Z'], ['formatDateTime(timestampObj)', '2018-03-15T13:00:00.000Z'], ['formatDateTime(unixTimestamp)', '2018-03-15T13:00:00.000Z'], From c0f9a0a6d749fc0246e113f1032bbaac746e6ff0 Mon Sep 17 00:00:00 2001 From: Shuai Wang Date: Sun, 19 Jan 2020 23:02:17 +0800 Subject: [PATCH 2/8] add test cases --- libraries/botframework-expressions/tests/expression.test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/botframework-expressions/tests/expression.test.js b/libraries/botframework-expressions/tests/expression.test.js index 8f73680e27..b6d6ed1065 100644 --- a/libraries/botframework-expressions/tests/expression.test.js +++ b/libraries/botframework-expressions/tests/expression.test.js @@ -285,7 +285,8 @@ const dataSource = [ ['utcNow(\'MM-DD-YY\')', moment(new Date().toISOString()).format('MM-DD-YY')], ['formatDateTime(notISOTimestamp)', '2018-03-15T13:00:00.000Z'], ['formatDateTime(notISOTimestamp, \'MM-dd-yy\')', '03-15-18'], - ['formatDateTime(notISOTimestamp, \'ddd\')', '03-15-18'], + ['formatDateTime(notISOTimestamp, \'ddd\')', 'Thu'], + ['formatDateTime(notISOTimestamp, \'dddd\')', 'Thursday'], ['formatDateTime(\'2018-03-15\')', '2018-03-15T00:00:00.000Z'], ['formatDateTime(timestampObj)', '2018-03-15T13:00:00.000Z'], ['formatDateTime(unixTimestamp)', '2018-03-15T13:00:00.000Z'], From 1bcb6648e5b64938d691dbf711f5bd4685f8c07d Mon Sep 17 00:00:00 2001 From: Shuai Wang Date: Mon, 20 Jan 2020 10:28:27 +0800 Subject: [PATCH 3/8] fix issues --- .../src/formatConverter.ts | 69 ++++++------------- .../tests/expression.test.js | 3 + 2 files changed, 23 insertions(+), 49 deletions(-) diff --git a/libraries/botframework-expressions/src/formatConverter.ts b/libraries/botframework-expressions/src/formatConverter.ts index 675d12b263..807eb1f061 100644 --- a/libraries/botframework-expressions/src/formatConverter.ts +++ b/libraries/botframework-expressions/src/formatConverter.ts @@ -1,3 +1,12 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/** + * @module botframework-expressions + */ +/** + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. + */ + enum State { None, LowerD1, @@ -47,10 +56,14 @@ enum State { EscapeSequence, } +/** + * Convert a CSharp style datetime format string to a Moment.js style datetime format string. Ref: https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings + * @param fmtString A CSharp style datetime format string. Ref: https://devhints.io/moment + * @returns A Momengt.js style datetime format string. + */ export function convertCSharpDateTimeToMomentJS(fmtString: string): string { let fmtResult = ''; let fmtState: any = State.None; - const fmtTolerant = true; let lTokenBuffer = ''; const changeState = (newState): void => { switch (fmtState) @@ -134,64 +147,29 @@ export function convertCSharpDateTimeToMomentJS(fmtString: string): string { fmtResult += 'ss'; break; case State.LowerT1: - if (fmtTolerant) - { - fmtResult += 'A'; - } - else - { - throw Error('Single Letter AM/PM not supported in MomentJS'); - } + fmtResult += 'A'; break; case State.LowerT2: fmtResult += 'A'; break; case State.LowerY1: - if (fmtTolerant) - { - fmtResult += 'YY'; - } - else - { - throw Error('Single Letter Year not supported in MomentJS'); - } + fmtResult += 'YY'; break; case State.LowerY2: fmtResult += 'YY'; break; case State.LowerY3: - if (fmtTolerant) - { - fmtResult += 'YYYY'; - } - else - { - throw Error('Three Letter Year not supported in MomentJS'); - } + fmtResult += 'YYYY'; break; case State.LowerY4: fmtResult += 'YYYY'; break; case State.LowerY5: - if (fmtTolerant) - { - fmtResult += 'Y'; - } - else - { - throw Error('Five or more Letter Year not supported in MomentJS'); - } + fmtResult += 'Y'; break; case State.LowerZ1: case State.LowerZ2: - if (fmtTolerant) - { - fmtResult += 'ZZ'; - } - else - { - throw Error('Hours offset not supported in MomentJS'); - } + fmtResult += 'ZZ'; break; case State.LowerZ3: fmtResult += 'Z'; @@ -355,14 +333,7 @@ export function convertCSharpDateTimeToMomentJS(fmtString: string): string { break; case 'K': changeState(State.None); - if (fmtTolerant) - { - fmtResult += `Z`; - } - else - { - throw Error(`TimeZoneInformation not supported in MomentJS`); - } + fmtResult += `Z`; break; case 'm': switch (fmtState) diff --git a/libraries/botframework-expressions/tests/expression.test.js b/libraries/botframework-expressions/tests/expression.test.js index b6d6ed1065..3e94154182 100644 --- a/libraries/botframework-expressions/tests/expression.test.js +++ b/libraries/botframework-expressions/tests/expression.test.js @@ -287,6 +287,9 @@ const dataSource = [ ['formatDateTime(notISOTimestamp, \'MM-dd-yy\')', '03-15-18'], ['formatDateTime(notISOTimestamp, \'ddd\')', 'Thu'], ['formatDateTime(notISOTimestamp, \'dddd\')', 'Thursday'], + ['formatDateTime(\'2018-03-15T00:00:00.000Z\', \'yyyy\')', '2018'], + ['formatDateTime(\'2018-03-15T00:00:00.123Z\', \'fff\')', '123'], + ['formatDateTime(\'2018-03-15T11:00:00.123Z\', \'t\')', 'PM'], ['formatDateTime(\'2018-03-15\')', '2018-03-15T00:00:00.000Z'], ['formatDateTime(timestampObj)', '2018-03-15T13:00:00.000Z'], ['formatDateTime(unixTimestamp)', '2018-03-15T13:00:00.000Z'], From 21d3110826549aa99efbe8403b0af6b7ad1fd000 Mon Sep 17 00:00:00 2001 From: Shuai Wang Date: Mon, 20 Jan 2020 11:02:16 +0800 Subject: [PATCH 4/8] add a new test --- libraries/botframework-expressions/tests/expression.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/botframework-expressions/tests/expression.test.js b/libraries/botframework-expressions/tests/expression.test.js index 3e94154182..9f13a94c9b 100644 --- a/libraries/botframework-expressions/tests/expression.test.js +++ b/libraries/botframework-expressions/tests/expression.test.js @@ -290,6 +290,7 @@ const dataSource = [ ['formatDateTime(\'2018-03-15T00:00:00.000Z\', \'yyyy\')', '2018'], ['formatDateTime(\'2018-03-15T00:00:00.123Z\', \'fff\')', '123'], ['formatDateTime(\'2018-03-15T11:00:00.123Z\', \'t\')', 'PM'], + ['formatDateTime(\'2018-03-15T11:00:00.123Z\', \'tt\')', 'PM'], ['formatDateTime(\'2018-03-15\')', '2018-03-15T00:00:00.000Z'], ['formatDateTime(timestampObj)', '2018-03-15T13:00:00.000Z'], ['formatDateTime(unixTimestamp)', '2018-03-15T13:00:00.000Z'], From 971a1152b51b92fae1bfff301ff58facc7c749ce Mon Sep 17 00:00:00 2001 From: Shuai Wang Date: Mon, 20 Jan 2020 15:15:29 +0800 Subject: [PATCH 5/8] fix formatDateTime test cases --- libraries/botframework-expressions/tests/expression.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/botframework-expressions/tests/expression.test.js b/libraries/botframework-expressions/tests/expression.test.js index 9f13a94c9b..f7db1a95b4 100644 --- a/libraries/botframework-expressions/tests/expression.test.js +++ b/libraries/botframework-expressions/tests/expression.test.js @@ -289,8 +289,8 @@ const dataSource = [ ['formatDateTime(notISOTimestamp, \'dddd\')', 'Thursday'], ['formatDateTime(\'2018-03-15T00:00:00.000Z\', \'yyyy\')', '2018'], ['formatDateTime(\'2018-03-15T00:00:00.123Z\', \'fff\')', '123'], - ['formatDateTime(\'2018-03-15T11:00:00.123Z\', \'t\')', 'PM'], - ['formatDateTime(\'2018-03-15T11:00:00.123Z\', \'tt\')', 'PM'], + ['formatDateTime(\'2018-03-15T11:00:00.123\', \'t\')', 'AM'], + ['formatDateTime(\'2018-03-15T11:00:00.123\', \'tt\')', 'AM'], ['formatDateTime(\'2018-03-15\')', '2018-03-15T00:00:00.000Z'], ['formatDateTime(timestampObj)', '2018-03-15T13:00:00.000Z'], ['formatDateTime(unixTimestamp)', '2018-03-15T13:00:00.000Z'], From 92e0f532574db2d10f0d380483e4320540e4534a Mon Sep 17 00:00:00 2001 From: Shuai Wang Date: Tue, 21 Jan 2020 16:32:58 +0800 Subject: [PATCH 6/8] add convert for standard datetime format --- .../src/formatConverter.ts | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/libraries/botframework-expressions/src/formatConverter.ts b/libraries/botframework-expressions/src/formatConverter.ts index 807eb1f061..acf9e54018 100644 --- a/libraries/botframework-expressions/src/formatConverter.ts +++ b/libraries/botframework-expressions/src/formatConverter.ts @@ -65,6 +65,24 @@ export function convertCSharpDateTimeToMomentJS(fmtString: string): string { let fmtResult = ''; let fmtState: any = State.None; let lTokenBuffer = ''; + if (fmtString.length === 0) { + return fmtResult; + } + if (fmtString.length === 1) { + switch (fmtString) { + case 'R': + case 'r': + throw Error(`RFC 1123 not supported in MomentJS`); + case 'O': + case 'o': + return 'YYYY-MM-DDTHH:mm:ss.SSSSSSSZ'; + case 'U': + throw new Error(`Universal Fulll Format not supported in MomentJS`); + case 'u': + throw new Error(`Universal Sortable Format not supported in MomentJS`); + } + } + const changeState = (newState): void => { switch (fmtState) { @@ -333,7 +351,7 @@ export function convertCSharpDateTimeToMomentJS(fmtString: string): string { break; case 'K': changeState(State.None); - fmtResult += `Z`; + fmtResult += 'Z'; break; case 'm': switch (fmtState) From 82fa635d1be820ef7cadb32a744d677091604361 Mon Sep 17 00:00:00 2001 From: Shuai Wang Date: Mon, 3 Feb 2020 22:25:40 +0800 Subject: [PATCH 7/8] fix comments and add more tests --- .../botframework-expressions/src/formatConverter.ts | 5 +++-- .../botframework-expressions/tests/expression.test.js | 9 +++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/libraries/botframework-expressions/src/formatConverter.ts b/libraries/botframework-expressions/src/formatConverter.ts index acf9e54018..56c12282bd 100644 --- a/libraries/botframework-expressions/src/formatConverter.ts +++ b/libraries/botframework-expressions/src/formatConverter.ts @@ -75,14 +75,15 @@ export function convertCSharpDateTimeToMomentJS(fmtString: string): string { throw Error(`RFC 1123 not supported in MomentJS`); case 'O': case 'o': - return 'YYYY-MM-DDTHH:mm:ss.SSSSSSSZ'; + fmtString = 'YYYY-MM-DDTHH:mm:ss.SSSSSSSZ'; + break; case 'U': throw new Error(`Universal Fulll Format not supported in MomentJS`); case 'u': throw new Error(`Universal Sortable Format not supported in MomentJS`); } } - + const changeState = (newState): void => { switch (fmtState) { diff --git a/libraries/botframework-expressions/tests/expression.test.js b/libraries/botframework-expressions/tests/expression.test.js index f7db1a95b4..d57b33adb3 100644 --- a/libraries/botframework-expressions/tests/expression.test.js +++ b/libraries/botframework-expressions/tests/expression.test.js @@ -288,6 +288,15 @@ const dataSource = [ ['formatDateTime(notISOTimestamp, \'ddd\')', 'Thu'], ['formatDateTime(notISOTimestamp, \'dddd\')', 'Thursday'], ['formatDateTime(\'2018-03-15T00:00:00.000Z\', \'yyyy\')', '2018'], + ['formatDateTime(\'2018-03-15T00:00:00.000Z\', \'yyyy-MM-dd-\\d\')', '2018-03-15-4'], + ['formatDateTime(\'2018-03-15T00:00:00.010Z\', \'FFFF\')', '0100'], + ['formatDateTime(\'2018-03-15T00:00:00.010Z\', \'FFF\')', '010'], + ['formatDateTime(\'2018-03-15T09:00:00.010\', \'hh\')', '09'], + ['formatDateTime(\'2018-03-15T09:00:00.010\', \'MMMM\')', 'March'], + ['formatDateTime(\'2018-03-15T09:00:00.010\', \'MMM\')', 'Mar'], + ['length(formatDateTime(\'2018-03-15T09:00:00.010\', \'z\'))', 5], + ['length(formatDateTime(\'2018-03-15T09:00:00.010\', \'zzz\'))', 6], + ['formatDateTime(formatDateTime(\'2018-03-15T00:00:00.000Z\', \'o\'), \'yyyy\')', '2018'], ['formatDateTime(\'2018-03-15T00:00:00.123Z\', \'fff\')', '123'], ['formatDateTime(\'2018-03-15T11:00:00.123\', \'t\')', 'AM'], ['formatDateTime(\'2018-03-15T11:00:00.123\', \'tt\')', 'AM'], From 7f52d3762412cf19c43096f6725c409fa41cdf6a Mon Sep 17 00:00:00 2001 From: Shuai Wang Date: Tue, 4 Feb 2020 14:16:50 +0800 Subject: [PATCH 8/8] add a test --- libraries/botframework-expressions/tests/expression.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/botframework-expressions/tests/expression.test.js b/libraries/botframework-expressions/tests/expression.test.js index d57b33adb3..598a3e32fe 100644 --- a/libraries/botframework-expressions/tests/expression.test.js +++ b/libraries/botframework-expressions/tests/expression.test.js @@ -290,6 +290,7 @@ const dataSource = [ ['formatDateTime(\'2018-03-15T00:00:00.000Z\', \'yyyy\')', '2018'], ['formatDateTime(\'2018-03-15T00:00:00.000Z\', \'yyyy-MM-dd-\\d\')', '2018-03-15-4'], ['formatDateTime(\'2018-03-15T00:00:00.010Z\', \'FFFF\')', '0100'], + ['formatDateTime(\'2018-03-15T00:00:00.010Z\', \'FFFFFF\')', '010000'], ['formatDateTime(\'2018-03-15T00:00:00.010Z\', \'FFF\')', '010'], ['formatDateTime(\'2018-03-15T09:00:00.010\', \'hh\')', '09'], ['formatDateTime(\'2018-03-15T09:00:00.010\', \'MMMM\')', 'March'],