diff --git a/.changeset/empty-views-stop.md b/.changeset/empty-views-stop.md new file mode 100644 index 000000000..520bc5339 --- /dev/null +++ b/.changeset/empty-views-stop.md @@ -0,0 +1,8 @@ +--- +'@getodk/xforms-engine': minor +'@getodk/web-forms': minor +'@getodk/scenario': patch +'@getodk/common': patch +--- + +Adds time question type diff --git a/README.md b/README.md index dd3d3ae8b..5bae9eb18 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ This section is auto generated. Please update `feature-matrix.json` and then run - ##### Question types (basic functionality)
🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩⬜⬜⬜ 82\% + ##### Question types (basic functionality)
🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩⬜⬜⬜ 85\%

@@ -63,7 +63,7 @@ This section is auto generated. Please update `feature-matrix.json` and then run | video | βœ… | | [file](https://github.com/getodk/web-forms/issues/370) | | | date | βœ… | -| time | | +| time | βœ… | | datetime | | | rank | βœ… | | csv-external | βœ… | diff --git a/feature-matrix.json b/feature-matrix.json index adc6dcacc..5fccb770d 100644 --- a/feature-matrix.json +++ b/feature-matrix.json @@ -21,7 +21,7 @@ "video": "βœ…", "[file](https://github.com/getodk/web-forms/issues/370)": "", "date": "βœ…", - "time": "", + "time": "βœ…", "datetime": "", "rank": "βœ…", "csv-external": "βœ…", diff --git a/packages/common/src/constants/datetime.ts b/packages/common/src/constants/datetime.ts index 79d231433..4c604aaa4 100644 --- a/packages/common/src/constants/datetime.ts +++ b/packages/common/src/constants/datetime.ts @@ -6,12 +6,13 @@ const ISO_DATE_LIKE_SUBPATTERN = '\\d{4}-\\d{2}-\\d{2}'; export const ISO_DATE_LIKE_PATTERN = new RegExp(`^${ISO_DATE_LIKE_SUBPATTERN}(?=T|$)`); -const ISO_TIME_LIKE_SUBPATTERN = `(${[ - '\\d{2}:\\d{2}:\\d{2}\\.\\d+', - '\\d{2}:\\d{2}:\\d{2}', - '\\d{2}:\\d{2}', - '\\d{2}', -].join('|')})`; +const STRICT_TIME_FORMATS = ['\\d{2}:\\d{2}:\\d{2}\\.\\d+', '\\d{2}:\\d{2}:\\d{2}']; + +const STRICT_ISO_TIME_SUBPATTERN = `(${[...STRICT_TIME_FORMATS].join('|')})`; + +const ISO_TIME_LIKE_SUBPATTERN = `(${[...STRICT_TIME_FORMATS, '\\d{2}:\\d{2}', '\\d{2}'].join( + '|' +)})`; export const ISO_TIME_LIKE_PATTERN = new RegExp(`^${ISO_TIME_LIKE_SUBPATTERN}$`); @@ -25,7 +26,7 @@ const ISO_OFFSET_SUBPATTERN = `(${TIMEZONE_OFFSET_SUBPATTERN}|Z)`; * Validates a timezone offset (e.g., "+01:00", "-12:30") in the format Β±HH:MM. * Ensures hours are between 00 and 14, and minutes are between 00 and 59, matching standard timezone offset ranges. */ -export const VALID_OFFSET_VALUE = new RegExp('^[+-]([0][0-9]|1[0-4]):([0-5][0-9])$'); +export const VALID_OFFSET_VALUE = new RegExp('^([+-]([0][0-9]|1[0-4]):([0-5][0-9])|Z)$', 'i'); export const ISO_DATE_TIME_LIKE_PATTERN = new RegExp( [ @@ -50,3 +51,7 @@ export const ISO_DATE_OR_DATE_TIME_LIKE_PATTERN = new RegExp( export const ISO_DATE_OR_DATE_TIME_NO_OFFSET_PATTERN = new RegExp( ['^', ISO_DATE_LIKE_SUBPATTERN, `(T${ISO_TIME_LIKE_SUBPATTERN})?`, '$'].join('') ); + +export const ISO_TIME_WITH_OPTIONAL_OFFSET_PATTERN = new RegExp( + ['^', STRICT_ISO_TIME_SUBPATTERN, `(${ISO_OFFSET_SUBPATTERN})?`, '$'].join('') +); diff --git a/packages/common/src/fixtures/date/date.xml b/packages/common/src/fixtures/date-and-time/date-and-time.xml similarity index 87% rename from packages/common/src/fixtures/date/date.xml rename to packages/common/src/fixtures/date-and-time/date-and-time.xml index f1d443dfc..aa9509975 100644 --- a/packages/common/src/fixtures/date/date.xml +++ b/packages/common/src/fixtures/date-and-time/date-and-time.xml @@ -20,6 +20,9 @@ When was the last time you ate vegetables? + + What time is your first meal? + @@ -34,6 +37,9 @@ Quand est-ce que vous avez mangΓ© des lΓ©gumes pour la derniΓ¨re fois ? + + Γ€ quelle heure prends-tu ton premier repas ? + @@ -43,6 +49,7 @@ + @@ -55,6 +62,7 @@ relevant=" /data/dates/date_of_birth != """/> + @@ -72,6 +80,9 @@