Skip to content

Fix for DatePicker doesnot updates the Format on Windows #30204

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions src/Core/src/Platform/Windows/CalendarDatePickerExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ public static string ToDateFormat(this string dateFormat)
if (string.IsNullOrEmpty(dateFormat) || CheckDateFormat(dateFormat))
return string.Empty;

// Handle standard .NET DateTime format strings (single characters)
if (dateFormat.Length == 1)
{
return ConvertStandardFormat(dateFormat);
}

string result = string.Empty;
string separator = GetSeparator(dateFormat);

Expand All @@ -33,6 +39,48 @@ public static string ToDateFormat(this string dateFormat)
return result;
}

internal static string ConvertStandardFormat(string format)
{
switch (format)
{
case "D": // Long date pattern
return "{dayofweek.full} {month.full} {day.integer} {year.full}";
case "m":
case "M": // Month day pattern
return "{month.full} {day.integer}";
case "y":
case "Y": // Year month pattern - .NET shows "2023 December"
return "{year.full} {month.full}";
case "f": // Full date/time pattern (short time) - use long date since time is not applicable
return "{dayofweek.full} {month.full} {day.integer}, {year.full} {hour.integer}:{minute.integer(2)} {period.abbreviated}";
case "F": // Full date/time pattern (long time) - include seconds as per .NET standard
return "{dayofweek.full} {month.full} {day.integer}, {year.full} {hour.integer}:{minute.integer(2)}:{second.integer(2)} {period.abbreviated}";
case "g": // General date/time pattern (short time) - use short date since time is not applicable
return "{month.integer}/{day.integer}/{year.abbreviated} {hour.integer}:{minute.integer(2)} {period.abbreviated}"; // Let it fall back to default short date
case "G": // General date/time pattern (long time) - use short date since time is not applicable
return "{month.integer}/{day.integer}/{year.abbreviated} {hour.integer}:{minute.integer(2)}:{second.integer(2)} {period.abbreviated}"; // Let it fall back to default short date
case "u":
return "{year.full}-{month.integer(2)}-{day.integer(2)} {hour.integer(2)}:{minute.integer(2)}:{second.integer(2)}Z";
case "U": // Universal full date/time pattern - use long date since time is not applicable
return "{dayofweek.full} {month.full} {day.integer} {year.full} {hour.integer(2)}:{minute.integer(2)}:{second.integer(2)}";
case "o":
case "O": // Round-trip date/time pattern - use ISO 8601 format
return "{year.full}-{month.integer(2)}-{day.integer(2)}T{hour.integer(2)}:{minute.integer(2)}:{second.integer(7)}"; // Let it fall back to default short date
case "r":
case "R": // RFC1123 pattern - use abbreviated format as close approximation
return "{dayofweek.abbreviated}, {day.integer(2)} {month.abbreviated} {year.full} {hour.integer(2)}:{minute.integer(2)}:{second.integer(2)} GMT";
case "s": // Sortable date/time pattern - use numeric format
return "{year.full}-{month.integer(2)}-{day.integer(2)}T{hour.integer(2)}:{minute.integer(2)}:{second.integer(2)}";
default:

// For other standard formats (o, O, u) that can't be reasonably mapped to date-only patterns,
// return empty string so that they use the default format
return string.Empty;

}

}

internal static string GetSeparator(string format)
{
string separator;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,46 @@ public async Task FormatInitializesCorrectly(string format, string nativeFormat)

await ValidatePropertyInitValue(datePicker, () => datePicker.Format, GetNativeFormat, format, nativeFormat);
}
[Theory(DisplayName = "Standard Format Strings Initialize Correctly")]
[InlineData("D", "{dayofweek.full} {month.full} {day.integer} {year.full}")]
[InlineData("f", "{dayofweek.full} {month.full} {day.integer}, {year.full} {hour.integer}:{minute.integer(2)} {period.abbreviated}")]
[InlineData("F", "{dayofweek.full} {month.full} {day.integer}, {year.full} {hour.integer}:{minute.integer(2)}:{second.integer(2)} {period.abbreviated}")]
[InlineData("m", "{month.full} {day.integer}")]
[InlineData("M", "{month.full} {day.integer}")]
[InlineData("r", "{dayofweek.abbreviated}, {day.integer(2)} {month.abbreviated} {year.full} {hour.integer(2)}:{minute.integer(2)}:{second.integer(2)} GMT")]
[InlineData("R", "{dayofweek.abbreviated}, {day.integer(2)} {month.abbreviated} {year.full} {hour.integer(2)}:{minute.integer(2)}:{second.integer(2)} GMT")]
[InlineData("s", "{year.full}-{month.integer(2)}-{day.integer(2)}T{hour.integer(2)}:{minute.integer(2)}:{second.integer(2)}")]
[InlineData("U", "{dayofweek.full} {month.full} {day.integer} {year.full} {hour.integer(2)}:{minute.integer(2)}:{second.integer(2)}")]
[InlineData("y", "{year.full} {month.full}")]
[InlineData("Y", "{year.full} {month.full}")]
[InlineData("g", "{month.integer}/{day.integer}/{year.abbreviated} {hour.integer}:{minute.integer(2)} {period.abbreviated}")]
[InlineData("G", "{month.integer}/{day.integer}/{year.abbreviated} {hour.integer}:{minute.integer(2)}:{second.integer(2)} {period.abbreviated}")]
public async Task StandardFormatInitializesCorrectly(string format, string nativeFormat)
Copy link
Contributor

Choose a reason for hiding this comment

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

The test is failing in this case: Standard Format Strings Initialize Correctly(format: "F", nativeFormat: "{dayofweek.full} {month.full} {day.integer}, {year"···)

Assert.Equal() Failure: Values differ\r\nExpected: {dayofweek.full} {month.full} {day.integer}, {year.full} {hour.integer}:{minute.integer(2)} {period.abbreviated}\r\nActual: {dayofweek.full} {month.full} {day.integer}, {year.full} {hour.integer}:{minute.integer(2)}:{second.integer(2)} {period.abbreviated}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jsuarezruiz ,I have addressed the testcase failure. Let me know if anything else needs adjustment.

{
var datePicker = new DatePickerStub();

datePicker.Date = new DateTime(2025, 12, 25);
datePicker.MinimumDate = DateTime.Today.AddDays(-1);
datePicker.MaximumDate = DateTime.Today.AddDays(1);
// Use a specific date to ensure consistent results
datePicker.Format = format;

await ValidatePropertyInitValue(datePicker, () => datePicker.Format, GetNativeFormat, format, nativeFormat);
}

[Theory(DisplayName = "Standard Format Strings That Use Default Initialize Correctly")]
[InlineData("d", "")]
public async Task StandardFormatDefaultInitializesCorrectly(string format, string nativeFormat)
{
var datePicker = new DatePickerStub();

datePicker.Date = DateTime.Today;
datePicker.MinimumDate = DateTime.Today.AddDays(-1);
datePicker.MaximumDate = DateTime.Today.AddDays(1);
datePicker.Format = format;

await ValidatePropertyInitValue(datePicker, () => datePicker.Format, GetNativeFormat, format, nativeFormat);
}
CalendarDatePicker GetNativeDatePicker(DatePickerHandler datePickerHandler) =>
datePickerHandler.PlatformView;

Expand Down
Loading