From 0be3b4e7a64c0c4b81f6bc6849549d8d7e53669c Mon Sep 17 00:00:00 2001 From: baonudesifeizhai <85092850+baonudesifeizhai@users.noreply.github.com> Date: Sat, 9 Aug 2025 23:05:55 -0400 Subject: [PATCH] fix: Add internationalization support for date input formatting Fixes #23266 (#23678) --- .../date-picker/index.tsx | 3 +- .../base/date-and-time-picker/utils/dayjs.ts | 46 +++++++++++++++++++ .../components/base/markdown-blocks/form.tsx | 17 ++++++- web/i18n/en-US/time.ts | 8 ++++ web/i18n/ja-JP/time.ts | 8 ++++ web/i18n/zh-Hans/time.ts | 8 ++++ 6 files changed, 86 insertions(+), 4 deletions(-) diff --git a/web/app/components/base/date-and-time-picker/date-picker/index.tsx b/web/app/components/base/date-and-time-picker/date-picker/index.tsx index f4fc86101..f99b8257c 100644 --- a/web/app/components/base/date-and-time-picker/date-picker/index.tsx +++ b/web/app/components/base/date-and-time-picker/date-picker/index.tsx @@ -78,7 +78,6 @@ const DatePicker = ({ setCurrentDate(prev => getDateWithTimezone({ date: prev, timezone })) setSelectedDate(prev => prev ? getDateWithTimezone({ date: prev, timezone }) : undefined) } - // eslint-disable-next-line react-hooks/exhaustive-deps }, [timezone]) const handleClickTrigger = (e: React.MouseEvent) => { @@ -192,7 +191,7 @@ const DatePicker = ({ setView(ViewType.date) } - const timeFormat = needTimePicker ? 'MMMM D, YYYY hh:mm A' : 'MMMM D, YYYY' + const timeFormat = needTimePicker ? t('time.dateFormats.displayWithTime') : t('time.dateFormats.display') const displayValue = value?.format(timeFormat) || '' const displayTime = selectedDate?.format('hh:mm A') || '--:-- --' const placeholderDate = isOpen && selectedDate ? selectedDate.format(timeFormat) : (placeholder || t('time.defaultPlaceholder')) diff --git a/web/app/components/base/date-and-time-picker/utils/dayjs.ts b/web/app/components/base/date-and-time-picker/utils/dayjs.ts index cdc392419..80dc0f780 100644 --- a/web/app/components/base/date-and-time-picker/utils/dayjs.ts +++ b/web/app/components/base/date-and-time-picker/utils/dayjs.ts @@ -90,3 +90,49 @@ export const convertTimezoneToOffsetStr = (timezone?: string) => { return DEFAULT_OFFSET_STR return `UTC${tzItem.name.charAt(0)}${tzItem.name.charAt(2)}` } + +// Parse date with multiple format support +export const parseDateWithFormat = (dateString: string, format?: string): Dayjs | null => { + if (!dateString) return null + + // If format is specified, use it directly + if (format) { + const parsed = dayjs(dateString, format, true) + return parsed.isValid() ? parsed : null + } + + // Try common date formats + const formats = [ + 'YYYY-MM-DD', // Standard format + 'YYYY/MM/DD', // Slash format + 'DD-MM-YYYY', // European format + 'DD/MM/YYYY', // European slash format + 'MM-DD-YYYY', // US format + 'MM/DD/YYYY', // US slash format + 'YYYY-MM-DDTHH:mm:ss.SSSZ', // ISO format + 'YYYY-MM-DDTHH:mm:ssZ', // ISO format (no milliseconds) + 'YYYY-MM-DD HH:mm:ss', // Standard datetime format + ] + + for (const fmt of formats) { + const parsed = dayjs(dateString, fmt, true) + if (parsed.isValid()) + return parsed + } + + return null +} + +// Format date output with localization support +export const formatDateForOutput = (date: Dayjs, includeTime: boolean = false, locale: string = 'en-US'): string => { + if (!date || !date.isValid()) return '' + + if (includeTime) { + // Output format with time + return date.format('YYYY-MM-DDTHH:mm:ss.SSSZ') + } + else { + // Date-only output format without timezone + return date.format('YYYY-MM-DD') + } +} diff --git a/web/app/components/base/markdown-blocks/form.tsx b/web/app/components/base/markdown-blocks/form.tsx index b71193d8f..5e0b118d3 100644 --- a/web/app/components/base/markdown-blocks/form.tsx +++ b/web/app/components/base/markdown-blocks/form.tsx @@ -7,6 +7,7 @@ import TimePicker from '@/app/components/base/date-and-time-picker/time-picker' import Checkbox from '@/app/components/base/checkbox' import Select from '@/app/components/base/select' import { useChatContext } from '@/app/components/base/chat/chat/context' +import { formatDateForOutput } from '@/app/components/base/date-and-time-picker/utils/dayjs' enum DATA_FORMAT { TEXT = 'text', @@ -51,8 +52,20 @@ const MarkdownForm = ({ node }: any) => { const getFormValues = (children: any) => { const values: { [key: string]: any } = {} children.forEach((child: any) => { - if ([SUPPORTED_TAGS.INPUT, SUPPORTED_TAGS.TEXTAREA].includes(child.tagName)) - values[child.properties.name] = formValues[child.properties.name] + if ([SUPPORTED_TAGS.INPUT, SUPPORTED_TAGS.TEXTAREA].includes(child.tagName)) { + let value = formValues[child.properties.name] + + if (child.tagName === SUPPORTED_TAGS.INPUT + && (child.properties.type === SUPPORTED_TYPES.DATE || child.properties.type === SUPPORTED_TYPES.DATETIME)) { + if (value && typeof value.format === 'function') { + // Format date output consistently + const includeTime = child.properties.type === SUPPORTED_TYPES.DATETIME + value = formatDateForOutput(value, includeTime) + } + } + + values[child.properties.name] = value + } }) return values } diff --git a/web/i18n/en-US/time.ts b/web/i18n/en-US/time.ts index 40adad023..9d72637d8 100644 --- a/web/i18n/en-US/time.ts +++ b/web/i18n/en-US/time.ts @@ -32,6 +32,14 @@ const translation = { pickTime: 'Pick Time', }, defaultPlaceholder: 'Pick a time...', + // Date format configurations + dateFormats: { + display: 'MMMM D, YYYY', + displayWithTime: 'MMMM D, YYYY hh:mm A', + input: 'YYYY-MM-DD', + output: 'YYYY-MM-DD', + outputWithTime: 'YYYY-MM-DDTHH:mm:ss.SSSZ', + }, } export default translation diff --git a/web/i18n/ja-JP/time.ts b/web/i18n/ja-JP/time.ts index 6594533b2..5a5d61748 100644 --- a/web/i18n/ja-JP/time.ts +++ b/web/i18n/ja-JP/time.ts @@ -32,6 +32,14 @@ const translation = { pickTime: 'ピックタイム', }, defaultPlaceholder: '時間を選んでください...', + // Date format configurations + dateFormats: { + display: 'YYYY年MM月DD日', + displayWithTime: 'YYYY年MM月DD日 HH:mm', + input: 'YYYY-MM-DD', + output: 'YYYY-MM-DD', + outputWithTime: 'YYYY-MM-DDTHH:mm:ss.SSSZ', + }, } export default translation diff --git a/web/i18n/zh-Hans/time.ts b/web/i18n/zh-Hans/time.ts index a7a1c6e57..74b68da1b 100644 --- a/web/i18n/zh-Hans/time.ts +++ b/web/i18n/zh-Hans/time.ts @@ -32,6 +32,14 @@ const translation = { pickTime: '选择时间', }, defaultPlaceholder: '请选择时间...', + // Date format configurations + dateFormats: { + display: 'YYYY年MM月DD日', + displayWithTime: 'YYYY年MM月DD日 HH:mm', + input: 'YYYY-MM-DD', + output: 'YYYY-MM-DD', + outputWithTime: 'YYYY-MM-DDTHH:mm:ss.SSSZ', + }, } export default translation