diff --git a/packages/main/src/Calendar.ts b/packages/main/src/Calendar.ts index 686373f355f0..c971ea6003ce 100644 --- a/packages/main/src/Calendar.ts +++ b/packages/main/src/Calendar.ts @@ -366,8 +366,9 @@ class Calendar extends CalendarPart { if (this.selectionMode === CalendarSelectionMode.Range) { const range = this.dates.find(date => date.hasAttribute("ui5-date-range")); - const startDate = range && range.startValue && this.getFormat().parse(range.startValue, true) as Date; - const endDate = range && range.endValue && this.getFormat().parse(range.endValue, true) as Date; + const format = this.getFormat(); + const startDate = range && range.startValue && format ? format.parse(range.startValue, true) as Date : null; + const endDate = range && range.endValue && format ? format.parse(range.endValue, true) as Date : null; if (startDate) { selectedDates.push(startDate.getTime() / 1000); @@ -394,7 +395,11 @@ class Calendar extends CalendarPart { * @private */ _setSelectedDates(selectedDates: Array) { - const selectedUTCDates = selectedDates.map(timestamp => this.getFormat().format(UI5Date.getInstance(timestamp * 1000), true)); + const format = this.getFormat(); + if (!format) { + return; + } + const selectedUTCDates = selectedDates.map(timestamp => format.format(UI5Date.getInstance(timestamp * 1000), true)); if (this.selectionMode === CalendarSelectionMode.Range) { // Create tags for the selected dates that don't already exist in DOM @@ -418,7 +423,7 @@ class Calendar extends CalendarPart { }); } } else { - const valuesInDOM = this._selectedDatesTimestamps.map(timestamp => this.getFormat().format(UI5Date.getInstance(timestamp * 1000))); + const valuesInDOM = this._selectedDatesTimestamps.map(timestamp => format.format(UI5Date.getInstance(timestamp * 1000))); // Remove all elements for dates that are no longer selected this.dates @@ -442,7 +447,11 @@ class Calendar extends CalendarPart { } _isValidCalendarDate(dateString: string): boolean { - const date = this.getFormat().parse(dateString); + const format = this.getFormat(); + if (!format) { + return false; + } + const date = format.parse(dateString); return !!date; } @@ -478,8 +487,13 @@ class Calendar extends CalendarPart { const uniqueDates = new Set(); const uniqueSpecialDates: Array = []; + const format = this.getFormat(); + if (!format) { + return uniqueSpecialDates; + } + validSpecialDates.forEach(date => { - const dateFromValue = this.getFormat().parse(date.value) as Date | UI5Date; + const dateFromValue = format.parse(date.value) as Date | UI5Date; const timestamp = dateFromValue.getTime(); if (!uniqueDates.has(timestamp)) { @@ -738,9 +752,13 @@ class Calendar extends CalendarPart { } _fireEventAndUpdateSelectedDates(selectedDates: Array) { + const format = this.getFormat(); + if (!format) { + return; + } const datesValues = selectedDates.map(timestamp => { const calendarDate = CalendarDateComponent.fromTimestamp(timestamp * 1000, this._primaryCalendarType); - return this.getFormat().format(calendarDate.toUTCJSDate(), true); + return format.format(calendarDate.toUTCJSDate(), true); }); const defaultPrevented = !this.fireDecoratorEvent("selection-change", { timestamp: this.timestamp, selectedDates: [...selectedDates], selectedValues: datesValues }); diff --git a/packages/main/src/DateComponentBase.ts b/packages/main/src/DateComponentBase.ts index 70615a98d8e1..a6de2a95fd42 100644 --- a/packages/main/src/DateComponentBase.ts +++ b/packages/main/src/DateComponentBase.ts @@ -125,6 +125,20 @@ class DateComponentBase extends UI5Element { super(); } + /** + * Checks if CLDR data is loaded and available for date formatting. + * @private + */ + _isCLDRReady(): boolean { + try { + // Try to get locale data - this will throw if CLDR is not loaded + const localeData = getCachedLocaleDataInstance(getLocale()); + return !!localeData; + } catch (e) { + return false; + } + } + get _primaryCalendarType() { const localeData = getCachedLocaleDataInstance(getLocale()); return this.primaryCalendarType || getCalendarType() || localeData.getPreferredCalendarType(); @@ -175,25 +189,44 @@ class DateComponentBase extends UI5Element { } _getMinMaxCalendarDateFromString(date: string) { - if (this.getFormat().parse(date)) { + const format = this.getFormat(); + if (format && format.parse(date)) { return this._getCalendarDateFromString(date); } - const jsDate = this.getISOFormat().parse(date) as Date; + const isoFormat = this.getISOFormat(); + if (!isoFormat) { + // CLDR not loaded yet + return undefined; + } + + const jsDate = isoFormat.parse(date) as Date; if (jsDate) { return CalendarDate.fromLocalJSDate(jsDate, this._primaryCalendarType); } } _getCalendarDateFromString(value: string) { - const jsDate = this.getValueFormat().parse(value) as Date; + const format = this.getValueFormat(); + if (!format) { + // CLDR not loaded yet + return undefined; + } + + const jsDate = format.parse(value) as Date; if (jsDate) { return CalendarDate.fromLocalJSDate(jsDate, this._primaryCalendarType); } } _getCalendarDateFromStringDisplayValue(value: string) { - const jsDate = this.getDisplayFormat().parse(value) as Date; + const format = this.getDisplayFormat(); + if (!format) { + // CLDR not loaded yet + return undefined; + } + + const jsDate = format.parse(value) as Date; if (jsDate) { return CalendarDate.fromLocalJSDate(jsDate, this._primaryCalendarType); } @@ -211,8 +244,14 @@ class DateComponentBase extends UI5Element { return ""; } + const format = this.getFormat(); + if (!format) { + // CLDR not loaded yet + return ""; + } + const localDate = UI5Date.getInstance(timestamp); - return this.getFormat().format(localDate, true); + return format.format(localDate, true); } _getDisplayStringFromTimestamp(timestamp: number) { @@ -220,8 +259,14 @@ class DateComponentBase extends UI5Element { return ""; } + const format = this.getDisplayFormat(); + if (!format) { + // CLDR not loaded yet + return ""; + } + const localDate = UI5Date.getInstance(timestamp); - return this.getDisplayFormat().format(localDate, true); + return format.format(localDate, true); } _getValueStringFromTimestamp(timestamp: number) { @@ -229,22 +274,36 @@ class DateComponentBase extends UI5Element { return ""; } + const format = this.getValueFormat(); + if (!format) { + // CLDR not loaded yet + return ""; + } + const localDate = UI5Date.getInstance(timestamp); - return this.getValueFormat().format(localDate, true); + return format.format(localDate, true); } - getFormat() { - return this._isPattern - ? DateFormat.getDateInstance({ - strictParsing: true, - pattern: this._formatPattern, - calendarType: this._primaryCalendarType, - }) - : DateFormat.getDateInstance({ - strictParsing: true, - style: this._formatPattern, - calendarType: this._primaryCalendarType, - }); + getFormat(): DateFormat | null { + if (!this._isCLDRReady()) { + return null; + } + + try { + return this._isPattern + ? DateFormat.getDateInstance({ + strictParsing: true, + pattern: this._formatPattern, + calendarType: this._primaryCalendarType, + }) + : DateFormat.getDateInstance({ + strictParsing: true, + style: this._formatPattern, + calendarType: this._primaryCalendarType, + }); + } catch (e) { + return null; + } } get _displayFormat() { @@ -267,45 +326,69 @@ class DateComponentBase extends UI5Element { return ""; } - getDisplayFormat() { - return this._isDisplayFormatPattern - ? DateFormat.getDateInstance({ - strictParsing: true, - pattern: this._displayFormat, - calendarType: this._primaryCalendarType, - }) - : DateFormat.getDateInstance({ - strictParsing: true, - style: this._displayFormat, - calendarType: this._primaryCalendarType, - }); + getDisplayFormat(): DateFormat | null { + if (!this._isCLDRReady()) { + return null; + } + + try { + return this._isDisplayFormatPattern + ? DateFormat.getDateInstance({ + strictParsing: true, + pattern: this._displayFormat, + calendarType: this._primaryCalendarType, + }) + : DateFormat.getDateInstance({ + strictParsing: true, + style: this._displayFormat, + calendarType: this._primaryCalendarType, + }); + } catch (e) { + return null; + } } - getValueFormat() { + getValueFormat(): DateFormat | null { if (!this._valueFormat) { return this.getISOFormat(); } - return this._isValueFormatPattern - ? DateFormat.getDateInstance({ - strictParsing: true, - pattern: this._valueFormat, - calendarType: this._primaryCalendarType, - }) - : DateFormat.getDateInstance({ - strictParsing: true, - style: this._valueFormat, - calendarType: this._primaryCalendarType, - }); + if (!this._isCLDRReady()) { + return null; + } + + try { + return this._isValueFormatPattern + ? DateFormat.getDateInstance({ + strictParsing: true, + pattern: this._valueFormat, + calendarType: this._primaryCalendarType, + }) + : DateFormat.getDateInstance({ + strictParsing: true, + style: this._valueFormat, + calendarType: this._primaryCalendarType, + }); + } catch (e) { + return null; + } } - getISOFormat() { + getISOFormat(): DateFormat | null { + if (!this._isCLDRReady()) { + return null; + } + if (!this._isoFormatInstance) { - this._isoFormatInstance = DateFormat.getDateInstance({ - strictParsing: true, - pattern: "yyyy-MM-dd", - calendarType: this._primaryCalendarType, - }); + try { + this._isoFormatInstance = DateFormat.getDateInstance({ + strictParsing: true, + pattern: "yyyy-MM-dd", + calendarType: this._primaryCalendarType, + }); + } catch (e) { + return null; + } } return this._isoFormatInstance; } diff --git a/packages/main/src/DatePicker.ts b/packages/main/src/DatePicker.ts index 9884dbce8ae8..360f59259ca1 100644 --- a/packages/main/src/DatePicker.ts +++ b/packages/main/src/DatePicker.ts @@ -404,12 +404,16 @@ class DatePicker extends DateComponentBase implements IFormInputElement { const validity = this.formValidity; if (validity.valueMissing) { + const format = this.getFormat(); // @ts-ignore oFormatOptions is a private API of DateFormat - return DatePicker.i18nBundle.getText(DATEPICKER_VALUE_MISSING, this.getFormat().oFormatOptions.pattern as string); + const pattern = format ? format.oFormatOptions?.pattern : this._formatPattern; + return DatePicker.i18nBundle.getText(DATEPICKER_VALUE_MISSING, pattern as string); } if (validity.patternMismatch) { - // @ts-ignore oFormatOptions is a private API of DateFormat - return DatePicker.i18nBundle.getText(DATEPICKER_PATTERN_MISSMATCH, this.getFormat().oFormatOptions.pattern as string); + const format = this.getFormat(); + // @ts-ignore oFormatOptions is private API of DateFormat + const pattern = format ? format.oFormatOptions?.pattern : this._formatPattern; + return DatePicker.i18nBundle.getText(DATEPICKER_PATTERN_MISSMATCH, pattern as string); } if (validity.rangeUnderflow) { return DatePicker.i18nBundle.getText(DATEPICKER_RANGE_UNDERFLOW, this.minDate); @@ -622,19 +626,35 @@ class DatePicker extends DateComponentBase implements IFormInputElement { } getValueFromDisplayValue(value: string): string { - if (!this.getDisplayFormat().parse(value)) { + const displayFormat = this.getDisplayFormat(); + const valueFormat = this.getValueFormat(); + + if (!displayFormat || !valueFormat) { + // CLDR not loaded yet return value; } - return this.getValueFormat().format(this.getDisplayFormat().parse(value)); + if (!displayFormat.parse(value)) { + return value; + } + + return valueFormat.format(displayFormat.parse(value)); } getDisplayValueFromValue(value: string): string { - if (!this.getValueFormat().parse(value)) { + const valueFormat = this.getValueFormat(); + const displayFormat = this.getDisplayFormat(); + + if (!valueFormat || !displayFormat) { + // CLDR not loaded yet return value; } - return this.getDisplayFormat().format(this.getValueFormat().parse(value)); + if (!valueFormat.parse(value)) { + return value; + } + + return displayFormat.format(valueFormat.parse(value)); } /** @@ -702,7 +722,13 @@ class DatePicker extends DateComponentBase implements IFormInputElement { return true; } - return !!this.getFormat().parse(value); + const format = this.getFormat(); + if (!format) { + // CLDR data not loaded yet + return false; + } + + return !!format.parse(value); } /** @@ -715,7 +741,13 @@ class DatePicker extends DateComponentBase implements IFormInputElement { return true; } - return !!this.getValueFormat().parse(value); + const format = this.getValueFormat(); + if (!format) { + // CLDR data not loaded yet + return false; + } + + return !!format.parse(value); } /** @@ -728,7 +760,13 @@ class DatePicker extends DateComponentBase implements IFormInputElement { return true; } - return !!this.getDisplayFormat().parse(value); + const format = this.getDisplayFormat(); + if (!format) { + // CLDR data not loaded yet + return false; + } + + return !!format.parse(value); } /** @@ -801,7 +839,13 @@ class DatePicker extends DateComponentBase implements IFormInputElement { return value; } - return this.getFormat().format(this.getFormat().parse(value, true), true); // it is important to both parse and format the date as UTC + const format = this.getFormat(); + if (!format) { + // CLDR not loaded yet + return value; + } + + return format.format(format.parse(value, true), true); // it is important to both parse and format the date as UTC } /** @@ -809,7 +853,14 @@ class DatePicker extends DateComponentBase implements IFormInputElement { * @protected */ normalizeFormattedValue(value: string) { - if (!this.getValueFormat().parse(value, true)) { + const format = this.getValueFormat(); + + if (!format) { + // CLDR not loaded yet + return ""; + } + + if (!format.parse(value, true)) { return ""; } @@ -817,7 +868,7 @@ class DatePicker extends DateComponentBase implements IFormInputElement { return value; } - return this.getValueFormat().format(this.getValueFormat().parse(value, true), true); // it is important to both parse and format the date as UTC + return format.format(format.parse(value, true), true); // it is important to both parse and format the date as UTC } /** @@ -825,17 +876,31 @@ class DatePicker extends DateComponentBase implements IFormInputElement { * @protected */ normalizeDisplayValue(value: string) { - if (value === "" || !this.getDisplayFormat().parse(value, true)) { + const format = this.getDisplayFormat(); + + if (!format) { + // CLDR not loaded yet + return value; + } + + if (value === "" || !format.parse(value, true)) { return value; } - return this.getDisplayFormat().format(this.getDisplayFormat().parse(value, true), true); // it is important to both parse and format the date as UTC + return format.format(format.parse(value, true), true); // it is important to both parse and format the date as UTC } get _lastDayOfTheYear() { const currentYear = UI5Date.getInstance().getFullYear(); const lastDayOfTheYear = UI5Date.getInstance(currentYear, 11, 31, 23, 59, 59); - return this.getFormat().format(lastDayOfTheYear); + const format = this.getFormat(); + + if (!format) { + // CLDR not loaded yet - return ISO format as fallback + return `${currentYear}-12-31`; + } + + return format.format(lastDayOfTheYear); } /** @@ -863,7 +928,15 @@ class DatePicker extends DateComponentBase implements IFormInputElement { } get displayValue(): string { - if (!this.getValueFormat().parse(this.value, true)) { + const valueFormat = this.getValueFormat(); + const displayFormat = this.getDisplayFormat(); + + if (!valueFormat || !displayFormat) { + // CLDR not loaded yet + return this.value; + } + + if (!valueFormat.parse(this.value, true)) { return this.value; } @@ -875,7 +948,7 @@ class DatePicker extends DateComponentBase implements IFormInputElement { return this.liveValue!; } - return this.getDisplayFormat().format(this.getValueFormat().parse(this.value, true), true); + return displayFormat.format(valueFormat.parse(this.value, true), true); } get accInfo(): InputAccInfo { @@ -978,7 +1051,13 @@ class DatePicker extends DateComponentBase implements IFormInputElement { } get _calendarPickersMode() { - const format = this.getFormat() as DateFormat & { aFormatArray: Array<{ type: string }> }; + const format = this.getFormat() as DateFormat & { aFormatArray: Array<{ type: string }> } | null; + + if (!format) { + // CLDR not loaded yet - default to most common mode + return CalendarPickersMode.DAY_MONTH_YEAR; + } + const patternSymbolTypes = format.aFormatArray.map(patternSymbolSettings => { return patternSymbolSettings.type.toLowerCase(); }); @@ -1029,7 +1108,14 @@ class DatePicker extends DateComponentBase implements IFormInputElement { * @returns The date as string */ formatValue(date: Date): string { - return this.getValueFormat().format(date); + const format = this.getValueFormat(); + + if (!format) { + // CLDR not loaded yet - return ISO format as fallback + return date.toISOString().split("T")[0]; + } + + return format.format(date); } _togglePicker(): void { @@ -1047,11 +1133,25 @@ class DatePicker extends DateComponentBase implements IFormInputElement { * @default null */ get dateValue(): Date | null { - return this.liveValue ? this.getValueFormat().parse(this.liveValue) as Date : this.getValueFormat().parse(this.value) as Date; + const format = this.getValueFormat(); + + if (!format) { + // CLDR not loaded yet + return null; + } + + return this.liveValue ? format.parse(this.liveValue) as Date : format.parse(this.value) as Date; } get dateValueUTC(): Date | null { - return this.liveValue ? this.getValueFormat().parse(this.liveValue, true) as Date : this.getValueFormat().parse(this.value) as Date; + const format = this.getValueFormat(); + + if (!format) { + // CLDR not loaded yet + return null; + } + + return this.liveValue ? format.parse(this.liveValue, true) as Date : format.parse(this.value) as Date; } get styles() { diff --git a/packages/main/src/DateRangePicker.ts b/packages/main/src/DateRangePicker.ts index 2772dfcff4f2..b483d632587b 100644 --- a/packages/main/src/DateRangePicker.ts +++ b/packages/main/src/DateRangePicker.ts @@ -90,12 +90,16 @@ class DateRangePicker extends DatePicker implements IFormInputElement { const validity = this.formValidity; if (validity.valueMissing) { + const format = this.getFormat(); // @ts-ignore oFormatOptions is a private API of DateFormat - return DateRangePicker.i18nBundle.getText(DATERANGE_VALUE_MISSING, this.getFormat().oFormatOptions.pattern as string); + const pattern = format ? format.oFormatOptions.pattern : this._formatPattern; + return DateRangePicker.i18nBundle.getText(DATERANGE_VALUE_MISSING, pattern as string); } if (validity.patternMismatch) { + const format = this.getFormat(); // @ts-ignore oFormatOptions is a private API of DateFormat - return DateRangePicker.i18nBundle.getText(DATERANGE_PATTERN_MISMATCH, this.getFormat().oFormatOptions.pattern as string); + const pattern = format ? format.oFormatOptions.pattern : this._formatPattern; + return DateRangePicker.i18nBundle.getText(DATERANGE_PATTERN_MISMATCH, pattern as string); } if (validity.rangeUnderflow) { return DateRangePicker.i18nBundle.getText(DATERANGE_UNDERFLOW, this.minDate); @@ -163,7 +167,15 @@ class DateRangePicker extends DatePicker implements IFormInputElement { } get _tempTimestamp() { - return this._tempValue && (this.getValueFormat().parse(this._tempValue, true) as Date).getTime() / 1000; // valueformat + if (!this._tempValue) { + return undefined; + } + const format = this.getValueFormat(); + if (!format) { + return undefined; + } + const parsedDate = format.parse(this._tempValue, true) as Date; + return parsedDate ? parsedDate.getTime() / 1000 : undefined; } /** @@ -227,7 +239,13 @@ class DateRangePicker extends DatePicker implements IFormInputElement { const lastDayOfTheYear = UI5Date.getInstance(currentYear, 11, 31, 23, 59, 59); const sevenDaysBeforeLastDayOfYear = UI5Date.getInstance(currentYear, 11, 24, 23, 59, 59); - return `${this.getFormat().format(sevenDaysBeforeLastDayOfYear)} ${this._effectiveDelimiter} ${this.getFormat().format(lastDayOfTheYear)}`; + const format = this.getFormat(); + if (!format) { + // CLDR not loaded yet - return ISO format as fallback + return `${currentYear}-12-24 ${this._effectiveDelimiter} ${currentYear}-12-31`; + } + + return `${format.format(sevenDaysBeforeLastDayOfYear)} ${this._effectiveDelimiter} ${format.format(lastDayOfTheYear)}`; } /** @@ -440,8 +458,9 @@ class DateRangePicker extends DatePicker implements IFormInputElement { _splitValueByDelimiter(value: string) { const valuesArray: Array = []; const partsArray = value.split(this._prevDelimiter || this._effectiveDelimiter); + const format = this.getValueFormat(); // if format successfully parse the value, the value contains only single date - if (this.getValueFormat().parse(value)) { + if (format && format.parse(value)) { valuesArray[0] = partsArray.join(this._effectiveDelimiter); valuesArray[1] = ""; } else { @@ -484,8 +503,15 @@ class DateRangePicker extends DatePicker implements IFormInputElement { } const dateStrings = this._splitValueByDelimiter(value); // at least one item guaranteed due to the checks above (non-empty and valid) + const format = this.getValueFormat(); + if (!format) { + return undefined; + } - const parsedDate = this.getValueFormat().parse(dateStrings[0], true) as Date; + const parsedDate = format.parse(dateStrings[0], true) as Date; + if (!parsedDate) { + return undefined; + } return parsedDate.getTime() / 1000; } @@ -502,7 +528,14 @@ class DateRangePicker extends DatePicker implements IFormInputElement { let dateStrings = this._splitValueByDelimiter(value); dateStrings = dateStrings.filter(str => str !== " "); // remove empty strings if (dateStrings[1]) { - const parsedDate = this.getValueFormat().parse(dateStrings[1], true) as Date; + const format = this.getValueFormat(); + if (!format) { + return undefined; + } + const parsedDate = format.parse(dateStrings[1], true) as Date; + if (!parsedDate) { + return undefined; + } return parsedDate.getTime() / 1000; } @@ -516,7 +549,11 @@ class DateRangePicker extends DatePicker implements IFormInputElement { } if (value) { - const parsedDate = this.getDisplayFormat().parse(value, true) as Date; + const format = this.getDisplayFormat(); + if (!format) { + return undefined; + } + const parsedDate = format.parse(value, true) as Date; return parsedDate.getTime() / 1000; } diff --git a/packages/main/src/DateTimePicker.ts b/packages/main/src/DateTimePicker.ts index 6dd9314e62bc..2d770e34dbf0 100644 --- a/packages/main/src/DateTimePicker.ts +++ b/packages/main/src/DateTimePicker.ts @@ -204,7 +204,8 @@ class DateTimePicker extends DatePicker implements IFormInputElement { // If current value is invalid, use the last valid value for time selection if (!timeSelectionValue || !this.isValidValue(timeSelectionValue)) { - timeSelectionValue = this._lastValidValue || this.getValueFormat().format(UI5Date.getInstance()); + const format = this.getValueFormat(); + timeSelectionValue = this._lastValidValue || (format ? format.format(UI5Date.getInstance()) : ""); } this._previewValues = { @@ -218,12 +219,16 @@ class DateTimePicker extends DatePicker implements IFormInputElement { const validity = this.formValidity; if (validity.valueMissing) { + const format = this.getFormat(); // @ts-ignore oFormatOptions is a private API of DateFormat - return DateTimePicker.i18nBundle.getText(DATETIME_VALUE_MISSING, this.getFormat().oFormatOptions.pattern as string); + const pattern = format ? format.oFormatOptions?.pattern : this._formatPattern; + return DateTimePicker.i18nBundle.getText(DATETIME_VALUE_MISSING, pattern as string); } if (validity.patternMismatch) { + const format = this.getFormat(); // @ts-ignore oFormatOptions is a private API of DateFormat - return DateTimePicker.i18nBundle.getText(DATETIME_PATTERN_MISMATCH, this.getFormat().oFormatOptions.pattern as string); + const pattern = format ? format.oFormatOptions?.pattern : this._formatPattern; + return DateTimePicker.i18nBundle.getText(DATETIME_PATTERN_MISMATCH, pattern as string); } if (validity.rangeUnderflow) { return DateTimePicker.i18nBundle.getText(DATETIME_RANGEUNDERFLOW, this.minDate); @@ -344,7 +349,8 @@ class DateTimePicker extends DatePicker implements IFormInputElement { // but fallback to last valid value if current picker time is empty or invalid let timeValue = this._clocks?.value || ""; if (!timeValue || !this.isValidValue(timeValue)) { - timeValue = this._lastValidValue || this.getValueFormat().format(UI5Date.getInstance()); + const format = this.getValueFormat(); + timeValue = this._lastValidValue || (format ? format.format(UI5Date.getInstance()) : ""); } this._previewValues = { @@ -392,8 +398,14 @@ class DateTimePicker extends DatePicker implements IFormInputElement { */ _submitClick() { const selectedDate = this.getSelectedDateTime(); + const format = this.getValueFormat(); - const value = this.getValueFormat().format(selectedDate); + if (!selectedDate || !format) { + this._togglePicker(); + return; + } + + const value = format.format(selectedDate); if (this.value !== value) { this._updateValueAndFireEvents(value, true, ["change", "value-changed"]); } @@ -462,9 +474,13 @@ class DateTimePicker extends DatePicker implements IFormInputElement { } getSelectedDateTime() { - const selectedDate = this.getValueFormat().parse(this._calendarSelectedDates[0]) as Date; - const selectedTime = this.getValueFormat().parse(this._timeSelectionValue) as Date; - if (selectedTime) { + const format = this.getValueFormat(); + if (!format) { + return null; + } + const selectedDate = format.parse(this._calendarSelectedDates[0]) as Date; + const selectedTime = format.parse(this._timeSelectionValue) as Date; + if (selectedTime && selectedDate) { selectedDate.setHours(selectedTime.getHours()); selectedDate.setMinutes(selectedTime.getMinutes()); selectedDate.setSeconds(selectedTime.getSeconds()); diff --git a/packages/main/src/DayPicker.ts b/packages/main/src/DayPicker.ts index 6b39305e959a..7ade485413cd 100644 --- a/packages/main/src/DayPicker.ts +++ b/packages/main/src/DayPicker.ts @@ -867,7 +867,14 @@ class DayPicker extends CalendarPart implements ICalendarPicker { } try { - const jsDate = this.getValueFormat().parse(dateValue) as Date; + const format = this.getValueFormat(); + if (!format) { + return 0; + } + const jsDate = format.parse(dateValue) as Date; + if (!jsDate) { + return 0; + } const calendarDate = CalendarDate.fromLocalJSDate( jsDate, this._primaryCalendarType,