Fix issue with Date diff when it includes a daylight time change

This commit is contained in:
Rudy Huyn 2019-03-07 18:09:57 -08:00
commit f076d34d00
5 changed files with 25 additions and 34 deletions

View file

@ -12,6 +12,7 @@ using namespace CalculatorApp::Common::DateCalculation;
DateCalculationEngine::DateCalculationEngine(_In_ String^ calendarIdentifier) DateCalculationEngine::DateCalculationEngine(_In_ String^ calendarIdentifier)
{ {
m_calendar = ref new Calendar(); m_calendar = ref new Calendar();
m_calendar->ChangeTimeZone("UTC");
m_calendar->ChangeCalendarSystem(calendarIdentifier); m_calendar->ChangeCalendarSystem(calendarIdentifier);
} }

View file

@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved. // Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. // Licensed under the MIT License.
#pragma once #pragma once
@ -46,7 +46,6 @@ namespace CalculatorApp
bool __nothrow AddDuration(_In_ Windows::Foundation::DateTime startDate, _In_ const DateDifference& duration, _Out_ Windows::Foundation::DateTime *endDate); bool __nothrow AddDuration(_In_ Windows::Foundation::DateTime startDate, _In_ const DateDifference& duration, _Out_ Windows::Foundation::DateTime *endDate);
bool __nothrow SubtractDuration(_In_ Windows::Foundation::DateTime startDate, _In_ const DateDifference& duration, _Out_ Windows::Foundation::DateTime *endDate); bool __nothrow SubtractDuration(_In_ Windows::Foundation::DateTime startDate, _In_ const DateDifference& duration, _Out_ Windows::Foundation::DateTime *endDate);
void __nothrow GetDateDifference(_In_ Windows::Foundation::DateTime date1, _In_ Windows::Foundation::DateTime date2, _In_ DateUnit outputFormat, _Out_ DateDifference *difference); void __nothrow GetDateDifference(_In_ Windows::Foundation::DateTime date1, _In_ Windows::Foundation::DateTime date2, _In_ DateUnit outputFormat, _Out_ DateDifference *difference);
private: private:
// Private Variables // Private Variables
Windows::Globalization::Calendar^ m_calendar; Windows::Globalization::Calendar^ m_calendar;

View file

@ -43,11 +43,7 @@ DateCalculatorViewModel::DateCalculatorViewModel() :
m_StrDateDiffResultAutomationName(L""), m_StrDateDiffResultAutomationName(L""),
m_StrDateDiffResultInDays(L""), m_StrDateDiffResultInDays(L""),
m_StrDateResult(L""), m_StrDateResult(L""),
m_StrDateResultAutomationName(L""), m_StrDateResultAutomationName(L"")
m_fromDate({ 0 }),
m_toDate({ 0 }),
m_startDate({ 0 }),
m_dateResult({ 0 })
{ {
const auto& localizationSettings = LocalizationSettings::GetInstance(); const auto& localizationSettings = LocalizationSettings::GetInstance();
@ -56,19 +52,17 @@ DateCalculatorViewModel::DateCalculatorViewModel() :
// Initialize Date Calc engine // Initialize Date Calc engine
m_dateCalcEngine = make_shared<DateCalculationEngine>(localizationSettings.GetCalendarIdentifier()); m_dateCalcEngine = make_shared<DateCalculationEngine>(localizationSettings.GetCalendarIdentifier());
// Initialize dates of DatePicker controls to today's date // Initialize dates of DatePicker controls to today's date
auto calendar = ref new Calendar(); auto calendar = ref new Calendar();
calendar->ChangeTimeZone("UTC");
auto today = calendar->GetDateTime(); auto today = calendar->GetDateTime();
// FromDate and ToDate should be clipped (adjusted to a consistent hour in UTC) // FromDate and ToDate should be clipped (adjusted to a consistent hour in UTC)
m_fromDate = today; m_fromDate = ClipTime(today);
m_toDate = today; m_toDate = ClipTime(today);
FromDate = ClipTime(today);
ToDate = ClipTime(today);
// StartDate should not be clipped // StartDate should not be clipped
StartDate = today; m_startDate = today;
m_dateResult = today; m_dateResult = today;
// Initialize the list separator delimiter appended with a space at the end, e.g. ", " // Initialize the list separator delimiter appended with a space at the end, e.g. ", "
@ -87,14 +81,14 @@ DateCalculatorViewModel::DateCalculatorViewModel() :
} }
/* In the ClipTime function, we used to change timezone to UTC before clipping the time. /* In the ClipTime function, we used to change timezone to UTC before clipping the time.
The comment from the previous delopers said this was done to eliminate the effects of The comment from the previous delopers said this was done to eliminate the effects of
Daylight Savings Time. We can't think of a good reason why this change in timezone is Daylight Savings Time. We can't think of a good reason why this change in timezone is
necessary and did find bugs related to the change, therefore, we have removed the necessary and did find bugs related to the change, therefore, we have removed the
change. Just in case, we will see if the clipped time is ever a different day from the change. Just in case, we will see if the clipped time is ever a different day from the
original day, which would hopefully indicate the change in timezone was actually original day, which would hopefully indicate the change in timezone was actually
necessary. We will collect telemetry if we find this case. If we don't see any necessary. We will collect telemetry if we find this case. If we don't see any
telemetry events after the application has been used for some time, we will feel safe telemetry events after the application has been used for some time, we will feel safe
and can remove this function. */ and can remove this function. */
DayOfWeek trueDayOfWeek = calendar->DayOfWeek; DayOfWeek trueDayOfWeek = calendar->DayOfWeek;
DateTime clippedTime = ClipTime(today); DateTime clippedTime = ClipTime(today);
@ -378,13 +372,14 @@ String^ DateCalculatorViewModel::GetLocalizedNumberString(int value) const
return ref new String(numberStr.c_str()); return ref new String(numberStr.c_str());
} }
// Adjusts the given DateTime to 12AM of the same day // Adjusts the given DateTime to 12AM (UTC) of the same day
DateTime DateCalculatorViewModel::ClipTime(DateTime dateTime) DateTime DateCalculatorViewModel::ClipTime(DateTime dateTime)
{ {
auto calendar = ref new Calendar(); auto calendar = ref new Calendar();
calendar->ChangeTimeZone("UTC");
calendar->SetDateTime(dateTime); calendar->SetDateTime(dateTime);
calendar->Period = 1; calendar->Period = calendar->FirstPeriodInThisDay;
calendar->Hour = 12; calendar->Hour = calendar->FirstHourInThisPeriod;
calendar->Minute = 0; calendar->Minute = 0;
calendar->Second = 0; calendar->Second = 0;
calendar->Nanosecond = 0; calendar->Nanosecond = 0;

View file

@ -23,7 +23,7 @@ namespace CalculatorApp
// Input Properties // Input Properties
OBSERVABLE_PROPERTY_RW(bool, IsDateDiffMode); OBSERVABLE_PROPERTY_RW(bool, IsDateDiffMode);
OBSERVABLE_PROPERTY_RW(bool, IsAddMode); OBSERVABLE_PROPERTY_RW(bool, IsAddMode);
OBSERVABLE_PROPERTY_RW(bool, IsDiffInDays); // If diff is only in days or the dates are the same, OBSERVABLE_PROPERTY_R(bool, IsDiffInDays); // If diff is only in days or the dates are the same,
// then show only one result and avoid redundancy // then show only one result and avoid redundancy
OBSERVABLE_PROPERTY_RW(int, DaysOffset); OBSERVABLE_PROPERTY_RW(int, DaysOffset);
@ -82,11 +82,11 @@ namespace CalculatorApp
} }
// Output Properties // Output Properties
OBSERVABLE_PROPERTY_RW(Platform::String^, StrDateDiffResult); OBSERVABLE_PROPERTY_R(Platform::String^, StrDateDiffResult);
OBSERVABLE_PROPERTY_RW(Platform::String^, StrDateDiffResultAutomationName); OBSERVABLE_PROPERTY_R(Platform::String^, StrDateDiffResultAutomationName);
OBSERVABLE_PROPERTY_RW(Platform::String^, StrDateDiffResultInDays); OBSERVABLE_PROPERTY_R(Platform::String^, StrDateDiffResultInDays);
OBSERVABLE_PROPERTY_RW(Platform::String^, StrDateResult); OBSERVABLE_PROPERTY_R(Platform::String^, StrDateResult);
OBSERVABLE_PROPERTY_RW(Platform::String^, StrDateResultAutomationName); OBSERVABLE_PROPERTY_R(Platform::String^, StrDateResultAutomationName);
COMMAND_FOR_METHOD(CopyCommand, DateCalculatorViewModel::OnCopyCommand); COMMAND_FOR_METHOD(CopyCommand, DateCalculatorViewModel::OnCopyCommand);
@ -104,8 +104,6 @@ namespace CalculatorApp
Platform::String^ GetLocalizedNumberString(int value) const; Platform::String^ GetLocalizedNumberString(int value) const;
static Windows::Foundation::DateTime ClipTime(Windows::Foundation::DateTime dateTime); static Windows::Foundation::DateTime ClipTime(Windows::Foundation::DateTime dateTime);
static void CheckClipTimeSameDay(Windows::Globalization::Calendar^ reference);
property bool IsOutOfBound property bool IsOutOfBound
{ {
bool get() { return m_isOutOfBound; } bool get() { return m_isOutOfBound; }

View file

@ -36,8 +36,6 @@ using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media; using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation; using namespace Windows::UI::Xaml::Navigation;
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
DateCalculator::DateCalculator() DateCalculator::DateCalculator()
{ {
InitializeComponent(); InitializeComponent();