Skip to content

[iOS] Fix DatePicker to consistently display 4-digit years#32451

Merged
PureWeen merged 12 commits intoinflight/currentfrom
copilot/sub-pr-31464
Nov 11, 2025
Merged

[iOS] Fix DatePicker to consistently display 4-digit years#32451
PureWeen merged 12 commits intoinflight/currentfrom
copilot/sub-pr-31464

Conversation

Copy link
Contributor

Copilot AI commented Nov 7, 2025

  • Analyze existing PR changes and feedback
  • Fix test assertions to correctly validate 4-digit year format
  • Apply @mattleibow's fix for format inconsistency
  • Rename test files from Issue31117 to Issue31167
  • Run code review
  • Run CodeQL security scan (no issues)
  • Complete takeover of PR

Summary of Changes

1. Test Assertion Fix (commit 9d07ee8)

  • Removed incorrect /24 pattern checks that failed on valid dates like 12/24/2024
  • Tests now verify presence of 4-digit years only

2. Format Inconsistency Fix (commit fdd3ade)

Root Cause: The picker is not null condition caused different formatting paths:

  • Initial display → C# DateTime.ToString() → format like 6/15/2024
  • After interaction → iOS NSDateFormatter → format like 2023/06/15

Solution Applied (per @mattleibow's analysis):

  • Removed picker is not null check to always use iOS formatting
  • Changed from picker.Date to datePicker.Date.Value.ToNSDate() for consistent date source
  • Both initial and post-interaction now use same iOS NSDateFormatter with yMd template
  • Maintains 4-digit years while ensuring format consistency

3. Test File Naming Fix (commit 9843652)

Result

  • ✅ Fixes 2-digit year bug (4-digit years always displayed)
  • ✅ Fixes format inconsistency bug (format stays consistent across interactions)
  • ✅ Respects iOS locale settings consistently
  • ✅ Custom formats preserved (bypass this code path)
  • ✅ Test files correctly named to match issue number

Testing

The fix ensures format consistency across different locale settings while maintaining 4-digit year display. All tests build successfully.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix DatePicker to display 4-digit years consistently [iOS] Fix DatePicker to consistently display 4-digit years Nov 7, 2025
Copilot AI requested a review from PureWeen November 7, 2025 21:27
@PureWeen PureWeen closed this Nov 7, 2025
@PureWeen PureWeen reopened this Nov 7, 2025
@PureWeen PureWeen changed the base branch from fix-31167-II to main November 7, 2025 21:30
@PureWeen PureWeen added this to the .NET 10.0 SR1 milestone Nov 7, 2025
@PureWeen PureWeen added the p/0 Current heighest priority issues that we are targeting for a release. label Nov 7, 2025
@PureWeen PureWeen marked this pull request as ready for review November 7, 2025 21:36
Copilot AI review requested due to automatic review settings November 7, 2025 21:36
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@mattleibow
Copy link
Member

mattleibow commented Nov 8, 2025

My machine shows wildly different dates when default/empty pickers change.

Before picking After picking
image image

My region:
image

For me, this PR does nothing. I am not sure why the initial dates are different. But this PR does not change as a result.

@mattleibow
Copy link
Member

✅ Root Cause Identified and Fix Proposed

After thorough investigation and testing, I've identified the root cause of the format inconsistency issue and implemented a fix.


🔍 Root Cause Analysis

The format inconsistency happens because of a conditional check on line 83 of DatePickerExtensions.cs:

else if (picker is not null && (string.IsNullOrWhiteSpace(format) || format.Equals("d", StringComparison.OrdinalIgnoreCase)))

This condition means the iOS native formatting path only executes when picker is not null.

The Problem:

  1. During initial setup (when picker might be null during handler initialization):

    • Condition fails because picker is null
    • Falls through to line 109: platformDatePicker.Text = datePicker.Date?.ToString(format)
    • Uses C# DateTime.ToString() which follows CultureInfo.CurrentCulture
  2. After user interaction (when picker is fully initialized):

    • Condition passes because picker is not null
    • Uses iOS NSDateFormatter with yMd template
    • Follows iOS's interpretation of the locale
  3. Result: C# and iOS interpret the same locale differently, causing format changes like:

    • 6/15/2024 (C# M/d/yyyy) → 2023/06/15 (iOS yyyy/MM/dd)

✅ The Fix

Remove the picker is not null check and always use iOS formatting for consistency.

Code Change

-else if (picker is not null && (string.IsNullOrWhiteSpace(format) || format.Equals("d", StringComparison.OrdinalIgnoreCase)))
+else if (string.IsNullOrWhiteSpace(format) || format.Equals("d", StringComparison.OrdinalIgnoreCase))
 {
     NSDateFormatter dateFormatter = new NSDateFormatter
     {
         TimeZone = NSTimeZone.FromGMT(0)
     };
 
+    // Use datePicker.Date (the source date) for formatting
+    // This ensures consistent formatting whether picker is initialized or not
+    var nsDate = datePicker.Date.Value.ToNSDate();
+
     if (format.Equals("D", StringComparison.Ordinal) == true)
     {
         dateFormatter.DateStyle = NSDateFormatterStyle.Long;
-        var strDate = dateFormatter.StringFor(picker.Date);
+        var strDate = dateFormatter.StringFor(nsDate);
         platformDatePicker.Text = strDate;
     }
     else
     {
         dateFormatter.SetLocalizedDateFormatFromTemplate("yMd");
-        var strDate = dateFormatter.StringFor(picker.Date);
+        var strDate = dateFormatter.StringFor(nsDate);
         platformDatePicker.Text = strDate;
     }
 }

Key Changes:

  1. Removed picker is not null check → iOS formatting now runs regardless of picker state
  2. Added var nsDate = datePicker.Date.Value.ToNSDate() → Use the source date instead of picker.Date
  3. Changed picker.DatensDate in both formatting paths

🎯 Why This Works

Before Fix:

  • Initial: C# formats 6/15/2024 (C# culture interpretation)
  • After interaction: iOS formats 2023/06/15 (iOS locale interpretation)
  • Result: Format changes ❌

After Fix:

  • Initial: iOS formats using yMd template
  • After interaction: iOS formats using yMd template
  • Result: Format stays consistent ✅

Both initial and post-interaction now use the same formatting system (iOS NSDateFormatter with yMd template), ensuring consistency.


✅ Benefits

  1. Fixes format inconsistency: Initial and post-interaction formats now match
  2. Maintains 4-digit years: The yMd template still forces 4-digit years
  3. Respects iOS locale: Users see dates formatted according to their iOS settings consistently
  4. No breaking changes: Custom formats still work exactly as before (they bypass this code path)

🧪 Testing

I've built and tested this fix with the Sandbox app on iOS 26.0. The fix ensures:

  • ✅ Initial display uses iOS formatter
  • ✅ Post-interaction uses iOS formatter
  • ✅ Format stays consistent throughout
  • ✅ 4-digit years are maintained
  • ✅ Custom formats (MM/dd/yyyy, yyyy-MM-dd) continue to work

📝 Recommendation

This fix should be applied on top of the existing PR to resolve the format inconsistency issue while maintaining the 4-digit year fix.

Next Steps:

  1. Apply this fix to the PR
  2. Test on multiple locales (US, UK, Arabic, Japanese)
  3. Verify format consistency across all scenarios
  4. Update tests to verify format consistency (not just 4-digit years)

@mattleibow
Copy link
Member

@copilot please look ath the fix propsed and apply it. Look at the comments and reviews on this PR

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 8, 2025

@copilot please look ath the fix propsed and apply it. Look at the comments and reviews on this PR

Applied your fix in commit fdd3ade. The changes remove the picker is not null condition and use datePicker.Date.Value.ToNSDate() for consistent formatting. This ensures both initial display and post-interaction use the same iOS NSDateFormatter, preventing format changes like 6/15/20242023/06/15.

@mattleibow
Copy link
Member

mattleibow commented Nov 8, 2025

Quick Follow-up on Minor Suggestions

The two remaining suggestions from my review are optional improvements and don't block merge:

1. Test File Naming (Issue31117 → Issue31167)

Current state: Test files are named Issue31117.* but the linked issue is #31167.

Impact: Minor - Tests function correctly, but the naming mismatch could confuse future maintainers looking for tests related to issue #31167.

If you choose to fix: Rename these 3 files:

  • src/Controls/tests/TestCases.HostApp/Issues/Issues31117.xamlIssue31167.xaml (also change "Issues" to "Issue")
  • src/Controls/tests/TestCases.HostApp/Issues/Issues31117.xaml.csIssue31167.xaml.cs
  • src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31117.csIssue31167.cs

And update all references to the class name from Issue31117 to Issue31167.

If you choose not to fix: The tests work fine as-is, so this is purely a naming consistency concern.

2. Remove #if IOS Wrapper from UI Test

Current state: The UI test class Issue31117.cs (line 1) has #if IOS wrapping the entire class.

Why it might be unnecessary:

  • The [Issue] attribute in the HostApp already specifies PlatformAffected.iOS
  • The test infrastructure handles platform targeting automatically
  • Per UI testing guidelines, #if directives should only be used when there's a technical limitation (e.g., platform-specific compilation issues)

Impact: Very minor - The test compiles and runs correctly on iOS. The #if IOS just prevents it from compiling on other platforms, which may or may not be necessary.

If you choose to remove it: Delete line 1 (#if IOS) and the corresponding #endif at the end of the file. The test will compile on all platforms but still only run on iOS due to the PlatformAffected attribute.

If you choose to keep it: There may be a valid reason for the compilation restriction that I'm not aware of, so it's fine to leave as-is.


Bottom line: Both suggestions are cosmetic/organizational improvements. The PR is functionally correct and ready to merge regardless of whether you address them. 🎉

@mattleibow
Copy link
Member

@copilot 1. Test File Naming (Issue31117 → Issue31167)
Current state: Test files are named Issue31117.* but the linked issue is #31167.

Impact: Minor - Tests function correctly, but the naming mismatch could confuse future maintainers looking for tests related to issue #31167.

If you choose to fix: Rename these 3 files:

src/Controls/tests/TestCases.HostApp/Issues/Issues31117.xaml → Issue31167.xaml (also change "Issues" to "Issue")
src/Controls/tests/TestCases.HostApp/Issues/Issues31117.xaml.cs → Issue31167.xaml.cs
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31117.cs → Issue31167.cs
And update all references to the class name from Issue31117 to Issue31167.

If you choose not to fix: The tests work fine as-is, so this is purely a naming consistency concern.

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 8, 2025

@copilot 1. Test File Naming (Issue31117 → Issue31167)
Current state: Test files are named Issue31117.* but the linked issue is #31167.
...

Renamed test files in commit 9843652. Changes:

  • Issues31117.xamlIssue31167.xaml (also fixed "Issues" to "Issue")
  • Issues31117.xaml.csIssue31167.xaml.cs
  • Issue31117.csIssue31167.cs
  • Updated all class names from Issue31117 to Issue31167
  • Updated [Issue] attribute from 31117 to 31167

Tests build successfully with the new naming.

@mattleibow
Copy link
Member

/azp run MAUI-UITests-public

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@PureWeen PureWeen changed the base branch from main to inflight/current November 11, 2025 17:21
@PureWeen PureWeen merged commit 122a872 into inflight/current Nov 11, 2025
99 of 102 checks passed
@github-project-automation github-project-automation bot moved this from Changes Requested to Done in MAUI SDK Ongoing Nov 11, 2025
@PureWeen PureWeen deleted the copilot/sub-pr-31464 branch November 11, 2025 17:22
github-actions bot pushed a commit that referenced this pull request Nov 11, 2025
* More device tests

* Fix the issue

* Added UITests

* Avoid Regex

* Updated comment

* Updated snapshots

* Updated tests

* Initial plan

* Fix test assertions to correctly validate 4-digit year format

Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>

* Fix format inconsistency by always using iOS formatting

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

* Rename test files from Issue31117 to Issue31167 to match issue number

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

---------

Co-authored-by: Javier Suárez <javiersuarezruiz@hotmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
github-actions bot pushed a commit that referenced this pull request Nov 14, 2025
* More device tests

* Fix the issue

* Added UITests

* Avoid Regex

* Updated comment

* Updated snapshots

* Updated tests

* Initial plan

* Fix test assertions to correctly validate 4-digit year format

Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>

* Fix format inconsistency by always using iOS formatting

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

* Rename test files from Issue31117 to Issue31167 to match issue number

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

---------

Co-authored-by: Javier Suárez <javiersuarezruiz@hotmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
github-actions bot pushed a commit that referenced this pull request Nov 15, 2025
* More device tests

* Fix the issue

* Added UITests

* Avoid Regex

* Updated comment

* Updated snapshots

* Updated tests

* Initial plan

* Fix test assertions to correctly validate 4-digit year format

Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>

* Fix format inconsistency by always using iOS formatting

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

* Rename test files from Issue31117 to Issue31167 to match issue number

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

---------

Co-authored-by: Javier Suárez <javiersuarezruiz@hotmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
github-actions bot pushed a commit that referenced this pull request Nov 15, 2025
* More device tests

* Fix the issue

* Added UITests

* Avoid Regex

* Updated comment

* Updated snapshots

* Updated tests

* Initial plan

* Fix test assertions to correctly validate 4-digit year format

Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>

* Fix format inconsistency by always using iOS formatting

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

* Rename test files from Issue31117 to Issue31167 to match issue number

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

---------

Co-authored-by: Javier Suárez <javiersuarezruiz@hotmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
github-actions bot pushed a commit that referenced this pull request Nov 18, 2025
* More device tests

* Fix the issue

* Added UITests

* Avoid Regex

* Updated comment

* Updated snapshots

* Updated tests

* Initial plan

* Fix test assertions to correctly validate 4-digit year format

Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>

* Fix format inconsistency by always using iOS formatting

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

* Rename test files from Issue31117 to Issue31167 to match issue number

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

---------

Co-authored-by: Javier Suárez <javiersuarezruiz@hotmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
github-actions bot pushed a commit that referenced this pull request Nov 18, 2025
* More device tests

* Fix the issue

* Added UITests

* Avoid Regex

* Updated comment

* Updated snapshots

* Updated tests

* Initial plan

* Fix test assertions to correctly validate 4-digit year format

Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>

* Fix format inconsistency by always using iOS formatting

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

* Rename test files from Issue31117 to Issue31167 to match issue number

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

---------

Co-authored-by: Javier Suárez <javiersuarezruiz@hotmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
github-actions bot pushed a commit that referenced this pull request Nov 18, 2025
* More device tests

* Fix the issue

* Added UITests

* Avoid Regex

* Updated comment

* Updated snapshots

* Updated tests

* Initial plan

* Fix test assertions to correctly validate 4-digit year format

Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>

* Fix format inconsistency by always using iOS formatting

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

* Rename test files from Issue31117 to Issue31167 to match issue number

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

---------

Co-authored-by: Javier Suárez <javiersuarezruiz@hotmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
github-actions bot pushed a commit that referenced this pull request Nov 20, 2025
* More device tests

* Fix the issue

* Added UITests

* Avoid Regex

* Updated comment

* Updated snapshots

* Updated tests

* Initial plan

* Fix test assertions to correctly validate 4-digit year format

Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>

* Fix format inconsistency by always using iOS formatting

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

* Rename test files from Issue31117 to Issue31167 to match issue number

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

---------

Co-authored-by: Javier Suárez <javiersuarezruiz@hotmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
github-actions bot pushed a commit that referenced this pull request Nov 20, 2025
* More device tests

* Fix the issue

* Added UITests

* Avoid Regex

* Updated comment

* Updated snapshots

* Updated tests

* Initial plan

* Fix test assertions to correctly validate 4-digit year format

Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>

* Fix format inconsistency by always using iOS formatting

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

* Rename test files from Issue31117 to Issue31167 to match issue number

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>

---------

Co-authored-by: Javier Suárez <javiersuarezruiz@hotmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: PureWeen <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
@github-actions github-actions bot locked and limited conversation to collaborators Dec 12, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-controls-datetimepicker DatePicker, TimePicker p/0 Current heighest priority issues that we are targeting for a release. platform/ios

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants