Limit the Datepicker in MUI (v5) to only accept two-digit years

I am currently using the MUI (v5) Datepicker for capturing user birthday information. The Datepicker has been localized to German language, resulting in the input format DD.MM.YYYY.

However, many German users prefer using a shorter year format like DD.MM.YY. This causes incorrect values to be displayed:

Entering 05.01.20 displays

Sun Jan 05 0020 00:00:00 GMT+0053
. This presents two issues:

  1. How can I enforce four-digit year inputs? Entering two digits results in a valid but inaccurate date.
  2. Alternatively, is there a way to validate and process two-digit year inputs? For instance, entering 80 should translate to 1980, while 18 should represent 2018.

A potential solution could be adjusting the input format of the DatePicker to DD.MM.YY and handling such inputs accordingly. How can I modify the input format of the 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>
    )
}

Answer №1

When dealing with these types of issues, the key is finding a balance that works well for both the end-user and the developer.

As someone from France, I understand the concept of two-digit years, but personally, I don't think it's worth the trouble.

While asking the end-user to input 4 digits instead of 2 may take a fraction of a second more, it saves countless hours spent trying to handle all the different scenarios and avoiding invalid dates. For instance, what if a user inputs 60 - is it meant to be interpreted as 2060 or 1960?

To address this issue, you could potentially adjust the input format of a DatePicker component using the inputFormat prop. However, thorough testing would be necessary since the documentation on this aspect might not be very comprehensive.

If we consider solution 1, there are validators in the DatePicker that exclude years before 1900 as valid. These validators can likely be customized to suit your requirements.


In an attempt to find a solution, I have created a barebones setup to experiment with your code and devised a somewhat preliminary approach.

You can observe the implementation in this CodeSandBox, where we leverage the method getYear to determine whether the year is beyond 1900. This method calculates the difference between the input year and the year 1900. For instance, entering 199 would yield -1701, whereas inputting 2021 would produce 121 - serving as our initial validation.

Additional cases need to be addressed by supplying our custom onError function to the DatePicker component.

It should be noted that for dates falling within the range of > 1900 and <= 1911, there seems to be an anomaly in Greenwich Mean Time. (+9)

In conclusion, if there is a genuine requirement for a 2-digit date format solely for display purposes (or storage as a string), utilizing the format function from date-fns might prove beneficial.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Calculating the Distance Between Elements within a Flex Container Using JavaScript

I am looking to calculate the margin left and right for children of a flex item <div class="sec images" style="display:flex;justify-content:space-between"> <img src="images/en_mb-mega-01.png" alt=""> ...

Implementing collapsible features through Material-UI Drawer

I successfully implemented the Drawer feature in my application. However, I noticed that the default setup does not include a collapsible option for nested sections, such as Mail with sub-sections like Inbox, Sent, Outbox, etc. My desired layout would be: ...

Angular template driven forms fail to bind to model data

In an attempt to connect the model in angular template-driven forms, I have created a model class and utilized it to fill the input field. HTML: <div class="form-group col-md-2 col-12" [class.text-danger]="nameCode.invalid && nameCode.touched ...

Implementing html5mode in Express.js and Angular.js for cleaner URLs

I've been working on resolving the issue of avoiding # in my Angular app with an ExpressJS server-side setup. I found a solution to enable html5mode and it worked well. However, whenever there is another 'get' request to fetch data from a di ...

What is the Best Way to Enable Tooltips to Function from External Elements?

I am currently designing a map that features points with tooltips. When hovered over, the tooltips function correctly. I am interested in exploring the possibility of making the tooltips interact with an external navigation bar. My goal is to have specifi ...

Sending data using Ajax to the server-side code in ASP.NET

Struggling to successfully pass a series of values through Ajax to a code-behind method in order to insert the data into a database table. However, encountering issues where string variables are being received as empty strings and int variables as 0. The ...

Tips for incorporating a Forgot/Reset password option into your #Firebase platform

In the project I'm working on, I am utilizing #AngularFire2. My goal is to incorporate a Reset / Forgot password link into the login page. Does anyone have suggestions on how to accomplish this task? I'm looking to get some insights from #AskFi ...

Utilizing pseudo-selectors in customizing styleOverrides within MUI version 5 Theming

The documentation for MUI(v5) includes an example highlighting the use of global style overrides: const theme = createTheme({ components: { MuiButton: { styleOverrides: { root: { // How to use pseudo-class here? // I ...

Run code after all images have been rendered in vuejs

Is there a way to execute code after all images have loaded, specifically needing to set the scroll in a specific position? Using nextTick() processes the code before the images are loaded. The mounted and created methods can't be used since the code ...

Struggling with passing the decoded user ID from Node Express() middleware to a route can be problematic

I have encountered a similar issue to one previously asked on Stack Overflow (NodeJS Express Router, pass decoded object between middleware and route?). In my scenario, I am using the VerifyOrdinaryUser function as middleware in the favorites.js route. Th ...

Perform multiple function invocations on a single variable using JavaScript

Is there a way to execute multiple functions on a single object in JavaScript? Maybe something like this: element .setHtml('test'), .setColor('green'); Instead of: element.setHtml('test'); element.setColor('gre ...

managing nested JSON arrays in JavaScript

I have a straightforward task with handling a simple array that is divided into two parts: a group of vid_ids and a single element named page. Initially, I was iterating through the vid_id array using a for loop. However, upon adding the page element, I en ...

Having difficulty extracting data from FormData() object and encountering difficulty sending it through the frontend

Whenever I use Postman to send data, the Title, description, and image are successfully transmitted. This is how my post array looks like: router.post('/', uploadS3.array('meme',3),(req, res, next)=>{ // res.json(req.file.locatio ...

Determining the minimum and maximum values of a grid using props in a React component

I have created a code for a customizable grid screen that is functioning perfectly. However, I am facing an issue where I want the minimum and maximum size of the grid to be 16 x 100. Currently, when a button is clicked, a prompt window appears asking for ...

Maintaining Existing Filters and Incorporating Additional Filters in React/Next.js Data Filtering

I'm currently facing a challenge with filtering data in React/Next.js. The issue I'm encountering is that whenever I set a new filter, the previous filters get removed. For instance, if a user performs a search, it works fine but the tag filters ...

Interactive image sliders in a Netflix-inspired style with live previews on hover, fully compatible with Bootstrap framework

I'm looking for suggestions on Twitter Bootstrap compatible jquery plugins that can create a Netflix-style continuously scrolling image carousel with mouse-over functionality. I've tried the carousel included in the Bootstrap JS library, but it r ...

Having trouble with the downloadUrl function when trying to generate a Google map locator in Opencart?

Currently, I am working on the development of a website using opencart at Within the dealers.php file, there is a function named query() which searches postcodes in the database to retrieve store location results and outputs them in XML format. For exampl ...

Preview multiple images while uploading in a React JS application

In order to achieve multiple image upload with preview using React JS, I attempted the code below. However, I encountered an error in the console: Uncaught DOMException: Failed to set the 'value' property on 'HTMLInputElement': This ...

Angular 8 does not allow for the assignment of type '{}' to a parameter

I have a unique approach for managing errors: private handleErrors<T>(operation = 'operation', result?: T) { return (error: any): Observable<T> => { console.error(error); this.record(`${operation} failed: ${error.m ...

Tips on allowing the backend file (app.js) to handle any URL sent from the frontend

In my Express app, I have two files located in the root directory: index.js and index.html. Additionally, there is a folder named "server" which contains a file named app.js that listens on port 3000. When running index.html using Live Server on port 5500 ...