Skip to content

Conversation

@vasu1303
Copy link

@vasu1303 vasu1303 commented Jan 3, 2026

Fixes: #16872

Summary

Fixes the DateTimePicker to respect user's 12H/24H time format preference. Previously, the time display at the top of the DateTimePicker always showed 24-hour format (e.g., "14:30") regardless of the user's time format setting.

Screenshots

After: Time respects user preference, showing 12H with AM/PM (e.g., "03:28 PM") or 24H format
image

Implementation Details

Changes Made:

  1. TimeMask.ts - Added getTimeMask() to return appropriate mask pattern based on time format
  2. TimeBlocks.ts - Restored as constant file per linting requirements
  3. getTimeBlocks.ts (new) - Dynamic block generator supporting 12H (1-12 + AM/PM) and 24H (0-23)
  4. DateTimeBlocks.ts - Simplified to static constant
  5. getDateTimeMask.ts - Updated to accept and use timeFormat parameter
  6. DateTimePickerInput.tsx - Dynamically generates mask and blocks based on user's time format preference, increased input width to accommodate AM/PM
  7. useParseJSDateToIMaskDateTimeInputString.ts - Formats dates with correct time pattern
  8. useParseDateTimeInputStringToJSDate.ts - Parses dates with correct time pattern
  9. date-utils.ts - Added getTimePattern() helper (returns 'hh:mm a' for 12H, 'HH:mm' for 24H)
  10. parseDateTimeToString.ts - Added optional timeFormat parameter for consistency

Technical Approach:

  • Leverages existing useDateTimeFormat() hook to get user's timeFormat preference
  • Supports TimeFormat.SYSTEM, TimeFormat.HOUR_12, and TimeFormat.HOUR_24
  • Uses IMask blocks with appropriate ranges: 1-12 for 12H, 0-23 for 24H
  • Adds 'aa' (AM/PM) block for 12-hour format with enum validation

@github-actions
Copy link
Contributor

github-actions bot commented Jan 3, 2026

Welcome!

Hello there, congrats on your first PR! We're excited to have you contributing to this project.
By submitting your Pull Request, you acknowledge that you agree with the terms of our Contributor License Agreement.

Generated by 🚫 dangerJS against 18e42ee

@charlesBochet
Copy link
Member

charlesBochet commented Jan 6, 2026

@vasu1303 Thanks for opening this PR—much appreciated.

We only accept PRs with passing (green) tests. Since the overall direction looks good, I’ve added a few comments to help guide you.

I’m going to close this PR for now because the tests are failing, but feel free to reopen it if you have the bandwidth to continue working on it. We’ll be happy to keep reviewing it.

To reopen the PR, you can comment:
"/twenty pr open"

@vasu1303
Copy link
Author

/twenty pr open

@twenty-eng-sync twenty-eng-sync bot reopened this Jan 14, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 14, 2026

🚀 Preview Environment Ready!

Your preview environment is available at: http://bore.pub:56153

This environment will automatically shut down when the PR is closed or after 5 hours.

@vasu1303
Copy link
Author

vasu1303 commented Jan 14, 2026

Hi @charlesBochet, sorry for the delay in getting back to this! I have now addressed all the feedback: I unified the date and time resolution using utilities and refactored the components to pass { dateFormat, timeFormat } as an object to improve the DevXP. I've also made sure the tests are passing.

Let me know if this looks good!

@prastoin prastoin marked this pull request as ready for review January 14, 2026 10:19
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 10 files

@lucasbordeau lucasbordeau self-requested a review January 21, 2026 09:11
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 1930 files

Note: This PR contains a large number of files. cubic only reviews up to 75 files per PR, so some files may not have been reviewed.

@lucasbordeau
Copy link
Contributor

lucasbordeau commented Jan 21, 2026

@vasu1303 Nice work.

After testing this, there's a small UX problem.

The AM or PM shouldn't reset until we delete it, right now it is deleted if we change the time part, which forces a user to put back AM or PM each time he changes the time part.

The input has been developed to not destroy any other part when modifying only a part of the date time input text.

You can find the right lifecycle with the mask and the input to avoid this annoying effect.

@lucasbordeau
Copy link
Contributor

Enregistrement.de.l.ecran.2026-01-21.a.10.58.06.mov

@lucasbordeau lucasbordeau force-pushed the vasu/fix/time-format-issue-datepicker branch from f697442 to 18e42ee Compare January 21, 2026 10:11
const parseJSDateToDateTimeInputString = (date: Date) => {
const parsingFormat =
getDateTimeFormatStringFoDatePickerInputMask(dateFormat);
if (!date || !isValid(date)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I wouldn't bring validation with the Date object, as we're trying to avoid its usage. Prefer using Temporal.

from: isHour12 ? 1 : 0,
to: isHour12 ? 12 : 23,
maxLength: 2,
},
Copy link

Choose a reason for hiding this comment

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

Bug: The time input's AM/PM validation is case-sensitive, expecting AM/PM. However, date-fns formats time with lowercase am/pm, causing a mismatch and validation failure.
Severity: MEDIUM

Suggested Fix

To fix the case-sensitivity issue, either update the IMask.MaskedEnum to include lowercase variants ['AM', 'PM', 'am', 'pm'], or add a prepare hook to the 'aa' block definition in getTimeBlocks.ts to convert the input value to uppercase before validation, like prepare: (str) => str.toUpperCase().

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location:
packages/twenty-front/src/modules/ui/input/components/internal/date/utils/getTimeBlocks.ts#L13

Potential issue: In 12-hour time format, the `IMask.MaskedEnum` for the AM/PM selector
is configured with `['AM', 'PM']`, making it case-sensitive. However, the `date-fns`
formatting pattern `'hh:mm a'` produces lowercase "am" and "pm". When a date is
programmatically set, the formatted value (e.g., "03:30 pm") will not match the mask's
enum, causing validation to fail. This also affects users who manually type "am" or "pm"
in lowercase. The component lacks a `prepare` hook or other normalization to handle case
differences.

Did we get this right? 👍 / 👎 to inform future reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Due date time format not following set format

4 participants