[pickers] Time picker does not support 24:00 (or beyond) in 24hr format.
Duplicates
- [X] I have searched the existing issues
Latest version
- [X] I have tested the latest version
Steps to reproduce đš
Link to live example: https://mui.com/x/react-date-pickers/time-field/
Steps:
- try to enter a time that is 24:00 or greater.
Current behavior đ¯
Field response with 04:00 and puts the cursor onto the minutes
Expected behavior đ¤
The system allows users to enter a time of 24:00 or potentially greater.
It would be nice to have a prop that would allow for the Maximum allowable time that can be entered, such that I could specify 24:00 as the maximum allowable instead of 23:59. Leave it up to the developer or whoever is implementing the feature, to appropriately calculate time once they receive what is submitted in the form.
Context đĻ
I have military subject matter experts in the field of law enforcement that will frequently use 24:00 to represent midnight or the end of the current day and will use 00:00 to represent midnight or the start of the day. This representation of time is used in their log books and for recording incidents that occurred at the start or the end of a day; they also use this format with duty rosters and time blocking.
A simple question will put this in context. If today is March 21, 2023, and I ask you to meet me at midnight tonight, with the current time picker, I would need to enter March 22, 2023, at 00:00, which seems counter to meeting you at midnight tonight. Whereas March 21, 2023, at 24:00 is much more logical.
Here is more information about 24 times and, in some rare cases, having time that goes PAST the 24:00 time block. https://en.wikipedia.org/wiki/24-hour_clock
Your environment đ
npx @mui/envinfo
Don't forget to mention which browser you used.
Output from `npx @mui/envinfo` goes here.
Order ID or Support key đŗ (optional)
No response
I think one major problem in reaching such customization will be library support
From what I understand, dayJs and date-fns do not support parsing the 24:00
Moreover, it would raise questions about handling the minutes in such a case, because they all agree to say that 24:35 is not valid time.
https://codesandbox.io/s/awesome-tdd-yvc5qm?file=/demo.tsx
Interestingly, the last two libraries support it, which does lend some credence to my argument. Agreed that there might need to be some restriction on the minutes when you hit 24:00, but there could also be a validation error thrown when someone enters an invalid time.
We need to run that error checking regardless because a user might skip over the minutes and not enter anything.

Any updates?
There are no updates for now. This is a complex topic because it's not ISO standard and the implementation could be exceedingly difficult depending on the capabilities of the different date libraries we support. đ¤
@LukasTy 24:00:00 is mentioned in ISO-8601 as a special case of valid end time since the recent amendments to ISO-8601 (see e.g. https://en.wikipedia.org/wiki/ISO_8601). Also date-fns should support it as well, see https://github.com/date-fns/date-fns/issues/1228, though the problem has reappeared in date-fns-tz, https://github.com/marnusw/date-fns-tz/issues/255. I would assume the problem will soon be fixed in date-fns-tz, too.
We also need 24:00 (but not beyond) in our software and specifically for end times. It would be vital to get support to this in order to use the different MUI time related pickers.
@laurisvan thank you for your comment and exploration. đ
I've explored this topic a bit more.
It looks like date libraries have the notion of 0-based or 1-based hour formats. It might be relatively "easy" to support these different concepts, if that's what would make sense to the user, but as Alex has pointed, that also means we lose the "00" hour. 35 minutes after midnight would be "24:35" and I'm not 100% sold that such behavior is what users need/expect. đ¤
If the aim would be to have "24:00" displayed as the start of the next day, then it's a different story that will require tinkering/hacking it in and might not be trivial to do on the Field. đ
P.S. I'm moving this issue to the grooming board, given the requests and amount of "đ".
@LukasTy Thanks for evaluating the issue. I would like to pinpoint that if, however, you want to stay compliant to ISO-8601 values in input widgets, AFAIK you do not need to support 24:35, and only support 24:00 as the special case of end times (that you could usage-wise add as a field in the widget, defaulting to false. This way you would remain backwards compatible with the current API.
We actually took this route and implemented our own date time range widget. However, you have fine accessibility features in the input that our own widget does not support, and we would very much take the real widgets in use as soon as they are available.
We've discussed and agreed not to prioritize this problem for now. We are keeping it on the radar. đ Any exploration from the community is very welcome, but given that practically no components support this, there could be very good reasons for going this route. đ
Understandable (yet a bit undesirable to us). I wonder what could be the next best route so that we would not need to maintain our own components on this one.
Is there a possibility to adding a hook into parsing the values and validating the input, so that we could wrap the interval picker and have custom behavior? I checked that there's a possibility of custom date lib adapter - https://mui.com/x/react-date-pickers/adapters-locale/ - could writing of our own adapter perhaps help overcome the problem?
Is there a possibility to adding a hook into parsing the values and validating the input, so that we could wrap the interval picker and have custom behavior?
You can check the custom field documentation page for examples of creating a custom input.
Most of the examples are using the useDateField to use the internals, maybe you could reuse something on your implementation. đ¤
However, keep in mind, that we are currently completely reworking the internals for v8, and those custom usage examples will become way easier to use on v8. đ
I checked that there's a possibility of custom date lib adapter - https://mui.com/x/react-date-pickers/adapters-locale/ - could writing of our own adapter perhaps help overcome the problem?
Sadly, no, I don't think an adapter would be enough because the internal code relies on certain things that you will hardly be able to change with an adapter, like resolving the maximum allowed hour: https://github.com/mui/mui-x/blob/3ed991b325e7215a5fbe39e29d893a34fe3e065d/packages/x-date-pickers/src/internals/hooks/useField/useField.utils.ts#L588-L591
Hi,
Ok, we'll see if we could patch the component ourselves, because it is way too big to write from scratch and to achieve the same good functionality you have elsewhere.
Just in case the patch turns clean and would not conflict badly with what you have, would you accept a contribution?
Just in case the patch turns clean and would not conflict badly with what you have, would you accept a contribution?
Of course, we'd check and review it. đ
@LukasTy I think I got quite far with my POC but need a few pointers foward.
Input-wise, I can get the end dates inputted and printed by patching the date function adapter (in our case AdapterDateFns) for field validation and endOfDay functions, and a tiny change at @mui/x-date-pickers/internals/hooks/useField/useField.utils.js (enforcing the values of lastHourInDay and hasMeridiem - I will figure out on how to make these right when I do the actual patch).
There still is one caveat - somewhere - most likely in MUI internals the inputted date is converted into an Invalid date. I checked that the invalid date is not created by the adapter - at least when tracing AdapterDateFns.parse, AdapterDateFns.formatByString, and AdapterDateFnsBase.date. For some reason I cannot through the stack trace with my debugger, so I could not check where the invalid date is created.
I know this already goes beyond good service, but may I still ask a quick walkthrough on how the interplay between date widgets and the adapters goes (what is called at what state)? Or do you have a good hint where date conversion might go wrong?
@laurisvan I would assume that the problem lies in here: https://github.com/mui/mui-x/blob/4e7aaeb828d666d3671f45ab4b336b6c84e4cd40/packages/x-date-pickers/src/AdapterDateFns/AdapterDateFns.ts#L110 Because:
console.info(parse('2024-10-11 24:00:00', 'yyyy-MM-dd HH:mm:ss', new Date()));
// Invalid Date
whereas:
console.info(parse('2024-10-11 24:00:00', 'yyyy-MM-dd kk:mm:ss', new Date()));
// 2024-10-10T21:00:00.000Z (on UTC+3 timezone)
Thanks, I think I got it.
It looks like there are only a few places within MUI and/or adapters would need changes. The challenge is that the resulting APIs would be less than elegant and information would need to be passed all the way from pickers to the adapters.
Part of my challenge is that I would wish to have both 24:00 and 00:30 as valid end times, e.g. leaving 24:00 as a valid special case. I found one implementation where the input mask 'HHH' denotes unconstrained time input. In ideal world, if the adapter would give the time ranges based on user-defined input masks, the solution would be rather simple.
In addition, small changes to transferDateSectionValue would be needed so that these overflowing dates (e.g. 24:00 is technically 00:00 the next day) could properly overflow to the higher value. As the values are currently fetched using set
// Before
utils.setHours(dateToTransferTo, utils.getHours(dateToTransferFrom));
// After (here the 'HHH' is just given as a sample - I believe we can get it from section attributes).
utils.setHours(dateToTransferTo, utils.getHours(dateToTransferFrom, 'HHH'), 'HHH');
Does this kind of change proposal sound even remotely acceptable?
Hi there, are there any updates on this functionality? My company works with endurance athletes who occasionally complete activities longer than 24 hours and the lack of support for 24+ hr elevation is a nonstarter for us to be able to use MUI time pickers âšī¸
@nhaebigkerber For now, there has been no progress on this feature, but there clearly is a need for this behavior. đ Have you discovered alternative components that support your use case?