Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 25 additions & 7 deletions packages/main/src/Calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -394,7 +395,11 @@ class Calendar extends CalendarPart {
* @private
*/
_setSelectedDates(selectedDates: Array<number>) {
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
Expand All @@ -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
Expand All @@ -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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that if there is no format will be good to return false

Copy link
Contributor Author

@hinzzx hinzzx Dec 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That’s why we have a fallback. I think it's the safest approach.

return !!date;
}

Expand Down Expand Up @@ -478,8 +487,13 @@ class Calendar extends CalendarPart {
const uniqueDates = new Set();
const uniqueSpecialDates: Array<SpecialCalendarDateT> = [];

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)) {
Expand Down Expand Up @@ -738,9 +752,13 @@ class Calendar extends CalendarPart {
}

_fireEventAndUpdateSelectedDates(selectedDates: Array<number>) {
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 });
Expand Down
181 changes: 132 additions & 49 deletions packages/main/src/DateComponentBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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);
}
Expand All @@ -211,40 +244,66 @@ 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) {
if (!timestamp) {
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) {
if (!timestamp) {
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() {
Expand All @@ -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;
}
Expand Down
Loading
Loading