Skip to content
45 changes: 45 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue31167.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Maui.Controls.Sample.Issues.Issue31167">
<VerticalStackLayout
Spacing="20"
Padding="20">

<Label
Text="DatePicker Format Test"
FontSize="18"
FontAttributes="Bold"
HorizontalOptions="Center" />

<Label
Text="This sample tests the 4-digit year format consistency on iOS DatePicker controls."
HorizontalOptions="Center" />

<DatePicker
x:Name="MyDatePicker"
AutomationId="MyDatePicker"
HorizontalOptions="Center"
Format="d" />

<Entry
x:Name="DateEntry"
AutomationId="DateEntry"
Placeholder="Enter date (e.g., 12/24/2024)"
HorizontalOptions="FillAndExpand" />

<Button
Text="Set Date"
AutomationId="SetDateButton"
Clicked="OnSetDateClicked"
HorizontalOptions="Center" />

<Label
x:Name="DisplayLabel"
AutomationId="DisplayLabel"
Text=""
HorizontalOptions="Center"
FontAttributes="Bold" />

</VerticalStackLayout>
</ContentPage>
29 changes: 29 additions & 0 deletions src/Controls/tests/TestCases.HostApp/Issues/Issue31167.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace Maui.Controls.Sample.Issues
{
[Issue(IssueTracker.Github, 31167,
"DatePicker initially shows year in 4 digits, but after changing the year it displays only 2 digits in net 10.0",
PlatformAffected.iOS)]
public partial class Issue31167 : ContentPage
{
public Issue31167()
{
InitializeComponent();
MyDatePicker.Date = new DateTime(2024, 12, 23);
UpdateDisplayLabel();
}

void OnSetDateClicked(object sender, EventArgs e)
{
if (DateTime.TryParse(DateEntry.Text, out DateTime newDate))
{
MyDatePicker.Date = newDate;
UpdateDisplayLabel();
}
}

void UpdateDisplayLabel()
{
DisplayLabel.Text = $"Current Date: {MyDatePicker.Date:d}";
}
}
}
126 changes: 126 additions & 0 deletions src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue31167.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#if IOS
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;

namespace Microsoft.Maui.TestCases.Tests.Issues;

public class Issue31167 : _IssuesUITest
{
public Issue31167(TestDevice testDevice) : base(testDevice)
{
}

public override string Issue => "DatePicker initially shows year in 4 digits, but after changing the year it displays only 2 digits in net 10.0";

[Test, Order(1)]
[Category(UITestCategories.DatePicker)]
public void DatePickerYearFormat_InitialState_DisplaysFourDigitYear()
{
// Verify initial display shows 4-digit year for 2024-12-23
var datePickerText = App.WaitForElement("MyDatePicker").GetText();
Assert.That(datePickerText, Does.Contain("2024"), "DatePicker should display 4-digit year initially");

var displayLabelText = App.WaitForElement("DisplayLabel").GetText();
Assert.That(displayLabelText, Does.Contain("2024"), "Display label should show 4-digit year");
}

[Test, Order(2)]
[Category(UITestCategories.DatePicker)]
public void DatePickerYearFormat_UserInteraction_MaintainsFourDigitYear()
{
// Get initial text
var initialText = App.WaitForElement("MyDatePicker").GetText();
Assert.That(initialText, Does.Contain("2024"), "Initial display should show 4-digit year");

// Simulate user interaction by opening and closing the DatePicker
App.Tap("MyDatePicker");

// On iOS, tap Done to close the picker
App.WaitForElement("Done");
App.Tap("Done");

// Verify text still shows 4-digit year after interaction
var afterInteractionText = App.WaitForElement("MyDatePicker").GetText();
Assert.That(afterInteractionText, Does.Contain("2024"), "After interaction should still show 4-digit year");

// Ensure format consistency
Assert.That(afterInteractionText, Is.EqualTo(initialText),
"Date format should remain consistent after user interaction");
}

[Test, Order(3)]
[Category(UITestCategories.DatePicker)]
public void DatePickerYearFormat_SetDateViaEntry_DisplaysFourDigitYear()
{
// Set a different date using the Entry field
App.WaitForElement("DateEntry");
App.ClearText("DateEntry");
App.EnterText("DateEntry", "1/1/2025");
App.Tap("SetDateButton");

// Verify DatePicker shows 4-digit year for the new date
var datePickerText = App.WaitForElement("MyDatePicker").GetText();
Assert.That(datePickerText, Does.Contain("2025"), "DatePicker should display 4-digit year for set date");

var displayLabelText = App.WaitForElement("DisplayLabel").GetText();
Assert.That(displayLabelText, Does.Contain("2025"), "Display label should show 4-digit year for set date");
}

[Test, Order(4)]
[Category(UITestCategories.DatePicker)]
public void DatePickerYearFormat_MultipleYearValues_AllShowFourDigits()
{
var testYears = new[] { "2020", "2023", "2026", "2030" };
var testDates = new[] { "1/1/2020", "2/2/2023", "3/3/2026", "4/4/2030" };

for (int i = 0; i < testDates.Length; i++)
{
// Set the test date
App.WaitForElement("DateEntry");
App.ClearText("DateEntry");
App.EnterText("DateEntry", testDates[i]);
App.Tap("SetDateButton");

// Verify 4-digit year display
var datePickerText = App.WaitForElement("MyDatePicker").GetText();
Assert.That(datePickerText, Does.Contain(testYears[i]),
$"DatePicker should display 4-digit year {testYears[i]} for date {testDates[i]}");
}
}

[Test, Order(5)]
[Category(UITestCategories.DatePicker)]
public void DatePickerYearFormat_iOS_ConsistentAfterMultipleInteractions()
{
// This test specifically validates the iOS year format fix through multiple interactions

// Set initial date
App.WaitForElement("DateEntry");
App.ClearText("DateEntry");
App.EnterText("DateEntry", "3/3/2024");
App.Tap("SetDateButton");

var initialText = App.WaitForElement("MyDatePicker").GetText();
Assert.That(initialText, Does.Contain("2024"), "Initial state should show 4-digit year");

// Perform multiple open/close cycles to test consistency
for (int i = 0; i < 3; i++)
{
// Open picker
App.Tap("MyDatePicker");
App.WaitForElement("Done");

// Close picker
App.Tap("Done");

// Verify format is still consistent
var currentText = App.WaitForElement("MyDatePicker").GetText();
Assert.That(currentText, Does.Contain("2024"),
$"After interaction #{i + 1}, should still show 4-digit year");
Assert.That(currentText, Is.EqualTo(initialText),
$"After interaction #{i + 1}, format should remain consistent");
}
}
}
#endif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 9 additions & 4 deletions src/Core/src/Platform/iOS/DatePickerExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Globalization;
using System.Text.RegularExpressions;
using Foundation;
using UIKit;

Expand Down Expand Up @@ -79,23 +80,27 @@ public static void UpdateDate(this MauiDatePicker platformDatePicker, IDatePicke
{
platformDatePicker.Text = string.Empty;
}
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.DateStyle = NSDateFormatterStyle.Short;
var strDate = dateFormatter.StringFor(picker.Date);
dateFormatter.SetLocalizedDateFormatFromTemplate("yMd"); // Forces 4-digit year
var strDate = dateFormatter.StringFor(nsDate);
platformDatePicker.Text = strDate;
}
}
Expand Down
Loading
Loading