From c9e8c8002857c4247d607bd04746adedbd7084aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Sua=CC=81rez?= Date: Mon, 1 Sep 2025 14:16:40 +0200 Subject: [PATCH 01/11] More device tests --- .../DatePicker/DatePickerHandlerTests.iOS.cs | 168 +++++++++++++++++- 1 file changed, 167 insertions(+), 1 deletion(-) diff --git a/src/Core/tests/DeviceTests/Handlers/DatePicker/DatePickerHandlerTests.iOS.cs b/src/Core/tests/DeviceTests/Handlers/DatePicker/DatePickerHandlerTests.iOS.cs index a90fd528c2dd..c843b1fe9683 100644 --- a/src/Core/tests/DeviceTests/Handlers/DatePicker/DatePickerHandlerTests.iOS.cs +++ b/src/Core/tests/DeviceTests/Handlers/DatePicker/DatePickerHandlerTests.iOS.cs @@ -85,12 +85,178 @@ public async Task CharacterSpacingInitializesCorrectly() Assert.Equal(xplatCharacterSpacing, values.PlatformViewValue); } + [Fact(DisplayName = "Date Format Shows Four Digit Year")] + public async Task DateFormatShowsFourDigitYear() + { + var datePicker = new DatePickerStub() + { + Date = new DateTime(2024, 6, 15), + Format = "d" // Short date format + }; + + await ValidatePropertyInitValue(datePicker, () => datePicker.Date, (handler) => + { + var text = GetNativeDatePicker(handler).Text ?? string.Empty; + // The text should contain "2024" not "24" + Assert.Contains("2024", text, StringComparison.OrdinalIgnoreCase); + return datePicker.Date; + }, datePicker.Date); + } + + [Fact(DisplayName = "Date Format With Empty Format Shows Four Digit Year")] + public async Task DateFormatWithEmptyFormatShowsFourDigitYear() + { + var datePicker = new DatePickerStub() + { + Date = new DateTime(2024, 6, 15), + Format = string.Empty // Empty format (default) + }; + + await ValidatePropertyInitValue(datePicker, () => datePicker.Date, (handler) => + { + var text = GetNativeDatePicker(handler).Text ?? string.Empty; + // The text should contain "2024" not "24" + Assert.Contains("2024", text, StringComparison.OrdinalIgnoreCase); + return datePicker.Date; + }, datePicker.Date); + } + + [Fact(DisplayName = "Date Format With Null Format Shows Four Digit Year")] + public async Task DateFormatWithNullFormatShowsFourDigitYear() + { + var datePicker = new DatePickerStub() + { + Date = new DateTime(2024, 6, 15), + Format = null // Null format (default) + }; + + await ValidatePropertyInitValue(datePicker, () => datePicker.Date, (handler) => + { + var text = GetNativeDatePicker(handler).Text ?? string.Empty; + // The text should contain "2024" not "24" + Assert.Contains("2024", text, StringComparison.OrdinalIgnoreCase); + return datePicker.Date; + }, datePicker.Date); + } + + [Fact(DisplayName = "Long Date Format Uses Full Format")] + public async Task LongDateFormatUsesFullFormat() + { + var datePicker = new DatePickerStub() + { + Date = new DateTime(2024, 6, 15), + Format = "D" // Long date format + }; + + await ValidatePropertyInitValue(datePicker, () => datePicker.Date, (handler) => + { + var text = GetNativeDatePicker(handler).Text ?? string.Empty; + // Long format should contain the full year + Assert.Contains("2024", text, StringComparison.OrdinalIgnoreCase); + // And should be a longer format (contains month name) + Assert.True(text.Length > 10, $"Long date format should be longer than short format, got: {text}"); + return datePicker.Date; + }, datePicker.Date); + } + + [Fact(DisplayName = "Custom Format With Slash Shows Four Digit Year")] + public async Task CustomFormatWithSlashShowsFourDigitYear() + { + var datePicker = new DatePickerStub() + { + Date = new DateTime(2024, 6, 15), + Format = "MM/dd/yyyy" // Custom format with slash + }; + + await ValidatePropertyInitValue(datePicker, () => datePicker.Date, (handler) => + { + var text = GetNativeDatePicker(handler).Text ?? string.Empty; + // Should show the exact format specified + Assert.Equal("06/15/2024", text); + return datePicker.Date; + }, datePicker.Date); + } + + [Fact(DisplayName = "Custom Format Without Slash Shows Four Digit Year")] + public async Task CustomFormatWithoutSlashShowsFourDigitYear() + { + var datePicker = new DatePickerStub() + { + Date = new DateTime(2024, 6, 15), + Format = "yyyy-MM-dd" // Custom format without slash + }; + + await ValidatePropertyInitValue(datePicker, () => datePicker.Date, (handler) => + { + var text = GetNativeDatePicker(handler).Text ?? string.Empty; + // Should show the exact format specified + Assert.Equal("2024-06-15", text); + return datePicker.Date; + }, datePicker.Date); + } + + [Fact(DisplayName = "Null Date Shows Empty Text")] + public async Task NullDateShowsEmptyText() + { + var datePicker = new DatePickerStub() + { + Date = null, + Format = "d" + }; + + await ValidatePropertyInitValue(datePicker, () => datePicker.Date, (handler) => + { + var text = GetNativeDatePicker(handler).Text; + // Should show empty text for null date + Assert.Equal(string.Empty, text, StringComparer.OrdinalIgnoreCase); + return datePicker.Date; + }, datePicker.Date); + } + + [Fact(DisplayName = "Case Insensitive Short Format Shows Four Digit Year")] + public async Task CaseInsensitiveShortFormatShowsFourDigitYear() + { + var datePicker = new DatePickerStub() + { + Date = new DateTime(2024, 6, 15), + Format = "D" // Uppercase D should use long format, not short format with year fix + }; + + await ValidatePropertyInitValue(datePicker, () => datePicker.Date, (handler) => + { + var text = GetNativeDatePicker(handler).Text ?? string.Empty; + // Should use long date format, not short format + Assert.Contains("2024", text, StringComparison.OrdinalIgnoreCase); + // Should be longer than a typical short format + Assert.True(text.Length > 15, $"Expected long format to be longer, got: {text}"); + return datePicker.Date; + }, datePicker.Date); + } + + [Fact(DisplayName = "Custom Format With Existing Four Digit Year Works")] + public async Task CustomFormatWithExistingFourDigitYearWorks() + { + var datePicker = new DatePickerStub() + { + Date = new DateTime(2024, 6, 15), + Format = "dd/MM/yyyy" // Already has yyyy + }; + + await ValidatePropertyInitValue(datePicker, () => datePicker.Date, (handler) => + { + var text = GetNativeDatePicker(handler).Text ?? string.Empty; + // Should maintain the 4-digit year + Assert.Equal("15/06/2024", text); + return datePicker.Date; + }, datePicker.Date); + } + MauiDatePicker GetNativeDatePicker(DatePickerHandler datePickerHandler) => datePickerHandler.PlatformView; DateTime? GetNativeDate(DatePickerHandler datePickerHandler) { - var dateString = GetNativeDatePicker(datePickerHandler).Text; + var dateString = GetNativeDatePicker(datePickerHandler).Text ?? string.Empty; DateTime.TryParse(dateString, out DateTime result); return result; From 6badc38473152bd3148a61127f9705d5fa0b6f59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Sua=CC=81rez?= Date: Mon, 1 Sep 2025 14:16:48 +0200 Subject: [PATCH 02/11] Fix the issue --- src/Core/src/Platform/iOS/DatePickerExtensions.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Core/src/Platform/iOS/DatePickerExtensions.cs b/src/Core/src/Platform/iOS/DatePickerExtensions.cs index 1b01f1f0b456..e858456797ca 100644 --- a/src/Core/src/Platform/iOS/DatePickerExtensions.cs +++ b/src/Core/src/Platform/iOS/DatePickerExtensions.cs @@ -1,5 +1,6 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using Foundation; using UIKit; @@ -94,7 +95,16 @@ public static void UpdateDate(this MauiDatePicker platformDatePicker, IDatePicke } else { + // Use a custom date format dateFormatter.DateStyle = NSDateFormatterStyle.Short; + var templateFormat = dateFormatter.DateFormat; + + if (!string.IsNullOrEmpty(templateFormat)) + { + templateFormat = Regex.Replace(templateFormat, @"(? Date: Tue, 2 Sep 2025 11:24:59 +0200 Subject: [PATCH 03/11] Added UITests --- .../TestCases.HostApp/Issues/Issues31117.xaml | 45 ++++++ .../Issues/Issues31117.xaml.cs | 29 ++++ .../Tests/Issues/Issue31117.cs | 132 ++++++++++++++++++ 3 files changed, 206 insertions(+) create mode 100644 src/Controls/tests/TestCases.HostApp/Issues/Issues31117.xaml create mode 100644 src/Controls/tests/TestCases.HostApp/Issues/Issues31117.xaml.cs create mode 100644 src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31117.cs diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issues31117.xaml b/src/Controls/tests/TestCases.HostApp/Issues/Issues31117.xaml new file mode 100644 index 000000000000..9d005e7b2f5c --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issues31117.xaml @@ -0,0 +1,45 @@ + + + + +