MUI (v5) Datepicker 中只能输入两位数的年份

Only two digit year input in MUI (v5) Datepicker

我正在使用 MUI (v5) 日期选择器输入用户生日。我已将其本地化为德语。所以输入是DD.MM.YYYY.

现在许多德国用户都在使用 DD.MM.YY 这样的短年份值。但是这个输入会导致错误的值:

输入05.01.20给我Sun Jan 05 0020 00:00:00 GMT+0053。这导致我遇到两个问题:

  1. 我如何'force' 用户输入四位数的年份值?输入两位数字会得到一个有效(但无用)的日期。
  2. 或者(这会更好)我如何检查和处理两位数的年份值?我认为未来值 (80) 应该用作 1980 并且 18 应该导致 2018.

对我来说,第二点是更好的解决方案,因此我必须将输入设置为 DD.MM.YY 格式,并按照描述处理这些输入。但是如何更改DatePicker的输入格式呢?

import React from 'react'
import AdapterDateFns from '@mui/lab/AdapterDateFns'
import LocalizationProvider from '@mui/lab/LocalizationProvider'
import DatePicker from '@mui/lab/DatePicker'
import deLocale from 'date-fns/locale/de'
import { toDate, isValid } from 'date-fns'

const Component = () => {
    const [birthday, setBirthday] = React.useState<Date>(null)
    const handleDateChange = (value: any) => {
        console.log(isValid(value))
        setBirthday(toDate(value))
    }
    
    return (
        <LocalizationProvider dateAdapter={AdapterDateFns} locale={deLocale}>
            <DatePicker
                disableFuture
                mask="__.__.____"
                value={birthday}
                onChange={handleDateChange}
                renderInput={(params) => (
                <TextField {...params} />
                )}
            />
        </LocalizationProvider>
    )
}

这类问题总是一个平衡的问题。对于最终用户和开发人员来说,什么更有效和实用?

作为法国人,我理解两位数的年份,但在我看来不值得这么麻烦。

是的,最终用户将不得不输入 4 位数字而不是 2 位(也就是说,无论如何,他的时间是 0.5 秒),但是你不必花费 2 或 3 小时(或更多)来尝试处理所有具体情况,并冒险保存无效日期。例如,如果用户输入 60(可以是“未来”值 2060,也可以是旧值 1960)会发生什么情况?

也就是说,我相信您可以通过 inputFormat 道具修改 DatePicker 的输入格式来实现您想要的效果。你必须测试一下,因为 the docs 关于这个道具不是很......广泛。

对于方案1,DatePicker中有验证器,例如1900年之前的所有年份都无效。我相信您也可以更改验证器以满足您的需要。


编辑:我已经为您的代码设置了一个 fiddle 的最小环境,并提出了一个(有点半生不熟的)解决方案。

正如你在这个 CodeSandBox 中看到的,我们可以利用方法 getYear 来告诉我们年份是否在 1900 年之后。它 return 是 1900 年与输入之间的差异。例如,如果我们输入 199,它将 return -1701。相反,如果我们输入 2021,它将 return 121。这就是我们的第一次验证。

我们还需要通过向 DatePicker 提供我们自己的 onError 函数来处理其他情况。

请注意 对于年份 > 1900 且 <= 1911 的日期,格林威治标准时间似乎已损坏。 (+9)

最后,如果我们真的想要一个 2 位数格式的日期并且 用于显示目的(或存储字符串类型的日期) ), 我们可以利用 date-fns.

中的函数 format