From 954955794592b1ae6ac14f3a1c606d53c5b9db50 Mon Sep 17 00:00:00 2001 From: Carl de Billy Date: Thu, 3 Jun 2021 11:02:52 -0400 Subject: [PATCH] fix(calendar): Fixed a potential crash when `SetToMin()`/`SetToMax()` were used in multi-eras calendars --- .../CalendarViewIntegrationTests.cs | 2 - .../Windows_Globalization/When_Calendar.cs | 49 +++++++++++++++++++ src/Uno.UWP/Globalization/Calendar.cs | 20 ++++---- 3 files changed, 59 insertions(+), 12 deletions(-) diff --git a/src/Uno.UI.RuntimeTests/IntegrationTests/dxaml/controls/calendarview/CalendarViewIntegrationTests.cs b/src/Uno.UI.RuntimeTests/IntegrationTests/dxaml/controls/calendarview/CalendarViewIntegrationTests.cs index c62bdebdfb29..169e709360a9 100644 --- a/src/Uno.UI.RuntimeTests/IntegrationTests/dxaml/controls/calendarview/CalendarViewIntegrationTests.cs +++ b/src/Uno.UI.RuntimeTests/IntegrationTests/dxaml/controls/calendarview/CalendarViewIntegrationTests.cs @@ -282,8 +282,6 @@ public async Task CanSelectOutOfRangeDate() rootPanel = await CalendarHelper.CreateTestResources(); - - // load into visual tree await RunOnUIThread(() => { diff --git a/src/Uno.UI.Tests/Windows_Globalization/When_Calendar.cs b/src/Uno.UI.Tests/Windows_Globalization/When_Calendar.cs index 4b7b596577f4..7ec4070b3c47 100644 --- a/src/Uno.UI.Tests/Windows_Globalization/When_Calendar.cs +++ b/src/Uno.UI.Tests/Windows_Globalization/When_Calendar.cs @@ -695,5 +695,54 @@ string dayOfWeekAsString SUT.DayOfWeekAsString().Should().Be(dayOfWeekAsString, nameof(dayOfWeekAsString)); } } + + [TestMethod] + [DataRow(WG.CalendarIdentifiers.JulianValue)] + [DataRow(WG.CalendarIdentifiers.GregorianValue)] + [DataRow(WG.CalendarIdentifiers.HebrewValue)] + [DataRow(WG.CalendarIdentifiers.HijriValue)] + [DataRow(WG.CalendarIdentifiers.JapaneseValue)] + [DataRow(WG.CalendarIdentifiers.KoreanValue)] + [DataRow(WG.CalendarIdentifiers.TaiwanValue)] + [DataRow(WG.CalendarIdentifiers.ThaiValue)] + [DataRow(WG.CalendarIdentifiers.UmAlQuraValue)] + [DataRow(WG.CalendarIdentifiers.PersianValue)] + [DataRow(WG.CalendarIdentifiers.ChineseLunarValue)] + [DataRow(WG.CalendarIdentifiers.VietnameseLunarValue)] + [DataRow(WG.CalendarIdentifiers.TaiwanLunarValue)] + [DataRow(WG.CalendarIdentifiers.KoreanLunarValue)] + [DataRow(WG.CalendarIdentifiers.JapaneseLunarValue)] + public void TestCalendarLimits(string calendar) + { + using var _ = new AssertionScope(); + + var sut = new WG.Calendar(new [] {"en"}, WG.CalendarIdentifiers.Japanese, "24HourClock"); + + sut.SetToMin(); + CheckLimits($"Min"); + + sut.SetToMax(); + CheckLimits($"Max"); + + sut.SetToNow(); + CheckLimits($"Max"); + + void CheckLimits(string context) + { + // Following tests are just to ensure no exceptions are raised + // by asking those values + sut.NumberOfEras.Should().BePositive(context); + sut.Era.Should().BePositive(context); + sut.FirstMonthInThisYear.Should().BePositive(context); + sut.NumberOfDaysInThisMonth.Should().BePositive(context); + sut.DayOfWeek.Should().NotBeNull(context); + sut.NumberOfEras.Should().BePositive(context); + sut.FirstEra.Should().BePositive(context); + sut.LastEra.Should().BePositive(context); + sut.Period.Should().BePositive(context); + sut.ResolvedLanguage.Should().NotBeEmpty(context); + } + } } } + diff --git a/src/Uno.UWP/Globalization/Calendar.cs b/src/Uno.UWP/Globalization/Calendar.cs index 2da6e3e84a5d..e83477522363 100644 --- a/src/Uno.UWP/Globalization/Calendar.cs +++ b/src/Uno.UWP/Globalization/Calendar.cs @@ -188,27 +188,27 @@ public void ChangeTimeZone(string timeZoneId) #region Read / Write _time public int Era { - get => _calendar.GetEra(_time.DateTime); + get => _calendar.GetEra(_time.UtcDateTime); [NotImplemented] set => global::Windows.Foundation.Metadata.ApiInformation.TryRaiseNotImplemented("Windows.Globalization.Calendar", "int Calendar.Era"); } public int Year { - get => _calendar.GetYear(_time.DateTime); + get => _calendar.GetYear(_time.UtcDateTime); set => AddYears(value - Year); } public int Month { - get => _calendar.GetMonth(_time.DateTime); + get => _calendar.GetMonth(_time.UtcDateTime); set => AddMonths(value - Month); } - public global::Windows.Globalization.DayOfWeek DayOfWeek => (global::Windows.Globalization.DayOfWeek)_calendar.GetDayOfWeek(_time.DateTime); + public global::Windows.Globalization.DayOfWeek DayOfWeek => (global::Windows.Globalization.DayOfWeek)_calendar.GetDayOfWeek(_time.UtcDateTime); public int Day { - get => _calendar.GetDayOfMonth(_time.DateTime); + get => _calendar.GetDayOfMonth(_time.UtcDateTime); set => AddDays(value - Day); } @@ -216,7 +216,7 @@ public int Hour { get { - var hour = _calendar.GetHour(_time.DateTime); + var hour = _calendar.GetHour(_time.UtcDateTime); if(hour < 12 || _clock == ClockIdentifiers.TwentyFourHour) { @@ -233,13 +233,13 @@ public int Hour public int Minute { - get => _calendar.GetMinute(_time.DateTime); + get => _calendar.GetMinute(_time.UtcDateTime); set => AddMinutes(value - Minute); } public int Second { - get => _calendar.GetSecond(_time.DateTime); + get => _calendar.GetSecond(_time.UtcDateTime); set => AddSeconds(value - Second); } @@ -278,7 +278,7 @@ public int Period public int Nanosecond { - get => (int)(_calendar.GetMilliseconds(_time.DateTime) * 1000); + get => (int)(_calendar.GetMilliseconds(_time.UtcDateTime) * 1000); set => AddNanoseconds(value - Nanosecond); } @@ -286,7 +286,7 @@ public void SetDateTime(global::System.DateTimeOffset value) => _time = value; public void SetToNow() - => _time = DateTime.Now; + => _time = DateTimeOffset.Now; internal void SetToday() // Useful helper not part of UWP contract => _time = DateTime.Today;