diff --git a/src/CalcViewModel/Common/DateCalculator.cpp b/src/CalcViewModel/Common/DateCalculator.cpp index 19d3c49..35df723 100644 --- a/src/CalcViewModel/Common/DateCalculator.cpp +++ b/src/CalcViewModel/Common/DateCalculator.cpp @@ -9,6 +9,11 @@ using namespace Windows::Foundation; using namespace Windows::Globalization; using namespace CalculatorApp::Common::DateCalculation; +bool operator==(const DateDifference& l, const DateDifference& r) +{ + return l.year == r.year && l.month == r.month && l.week == r.week && l.day == r.day; +} + DateCalculationEngine::DateCalculationEngine(_In_ String ^ calendarIdentifier) { m_calendar = ref new Calendar(); @@ -18,10 +23,9 @@ DateCalculationEngine::DateCalculationEngine(_In_ String ^ calendarIdentifier) // Adding Duration to a Date // Returns: True if function succeeds to calculate the date else returns False -bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime* endDate) +IBox ^ DateCalculationEngine::AddDuration(DateTime startDate, DateDifference duration) { auto currentCalendarSystem = m_calendar->GetCalendarSystem(); - try { m_calendar->SetDateTime(startDate); @@ -50,7 +54,8 @@ bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const Date m_calendar->AddDays(duration.day); } - *endDate = m_calendar->GetDateTime(); + m_calendar->ChangeCalendarSystem(currentCalendarSystem); + return m_calendar->GetDateTime(); } catch (Platform::InvalidArgumentException ^ ex) { @@ -58,17 +63,13 @@ bool DateCalculationEngine::AddDuration(_In_ DateTime startDate, _In_ const Date m_calendar->ChangeCalendarSystem(currentCalendarSystem); // Do nothing - return false; + return nullptr; } - - m_calendar->ChangeCalendarSystem(currentCalendarSystem); - - return true; } // Subtracting Duration from a Date // Returns: True if function succeeds to calculate the date else returns False -bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const DateDifference& duration, _Out_ DateTime* endDate) +IBox ^ DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ DateDifference duration) { auto currentCalendarSystem = m_calendar->GetCalendarSystem(); @@ -101,7 +102,18 @@ bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const { m_calendar->AddYears(-duration.year); } - *endDate = m_calendar->GetDateTime(); + m_calendar->ChangeCalendarSystem(currentCalendarSystem); + + auto dateTime = m_calendar->GetDateTime(); + // Check that the UniversalTime value is not negative + if (dateTime.UniversalTime >= 0) + { + return dateTime; + } + else + { + return nullptr; + } } catch (Platform::InvalidArgumentException ^ ex) { @@ -109,17 +121,12 @@ bool DateCalculationEngine::SubtractDuration(_In_ DateTime startDate, _In_ const m_calendar->ChangeCalendarSystem(currentCalendarSystem); // Do nothing - return false; + return nullptr; } - - m_calendar->ChangeCalendarSystem(currentCalendarSystem); - - // Check that the UniversalTime value is not negative - return (endDate->UniversalTime >= 0); } // Calculate the difference between two dates -bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateTime date2, _In_ DateUnit outputFormat, _Out_ DateDifference* difference) +IBox ^ DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateTime date2, _In_ DateUnit outputFormat) { DateTime startDate; DateTime endDate; @@ -177,8 +184,7 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT { // Operation failed due to out of bound result // For example: 31st Dec, 9999 - last valid date - *difference = DateDifferenceUnknown; - return false; + return nullptr; } } @@ -194,8 +200,7 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT if (differenceInDates[unitIndex] == 0) { // differenceInDates[unitIndex] is unsigned, the value can't be negative - *difference = DateDifferenceUnknown; - return false; + return nullptr; } differenceInDates[unitIndex] -= 1; pivotDate = tempPivotDate; @@ -220,8 +225,7 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT { // Operation failed due to out of bound result // For example: 31st Dec, 9999 - last valid date - *difference = DateDifferenceUnknown; - return false; + return nullptr; } } } while (tempDaysDiff != 0); // dates are the same - exit the loop @@ -232,8 +236,7 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT if (signedDaysDiff < 0) { // daysDiff is unsigned, the value can't be negative - *difference = DateDifferenceUnknown; - return false; + return nullptr; } daysDiff = signedDaysDiff; @@ -244,11 +247,12 @@ bool DateCalculationEngine::TryGetDateDifference(_In_ DateTime date1, _In_ DateT differenceInDates[3] = daysDiff; - difference->year = differenceInDates[0]; - difference->month = differenceInDates[1]; - difference->week = differenceInDates[2]; - difference->day = differenceInDates[3]; - return true; + DateDifference result; + result.year = differenceInDates[0]; + result.month = differenceInDates[1]; + result.week = differenceInDates[2]; + result.day = differenceInDates[3]; + return result; } // Private Methods diff --git a/src/CalcViewModel/Common/DateCalculator.h b/src/CalcViewModel/Common/DateCalculator.h index 549846f..7c9b6c4 100644 --- a/src/CalcViewModel/Common/DateCalculator.h +++ b/src/CalcViewModel/Common/DateCalculator.h @@ -29,39 +29,30 @@ namespace CalculatorApp }; // Struct to store the difference between two Dates in the form of Years, Months , Weeks - struct DateDifference + public + value struct DateDifference { - int year = 0; - int month = 0; - int week = 0; - int day = 0; - - bool operator==(const DateDifference& dd) const - { - return year == dd.year && month == dd.month && week == dd.week && day == dd.day; - } + int year; + int month; + int week; + int day; }; const DateDifference DateDifferenceUnknown{ INT_MIN, INT_MIN, INT_MIN, INT_MIN }; - class DateCalculationEngine + public + ref class DateCalculationEngine sealed { public: // Constructor DateCalculationEngine(_In_ Platform::String ^ calendarIdentifier); // Public Methods - 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 TryGetDateDifference( - _In_ Windows::Foundation::DateTime date1, - _In_ Windows::Foundation::DateTime date2, - _In_ DateUnit outputFormat, - _Out_ DateDifference* difference); + + Platform::IBox ^ AddDuration(_In_ Windows::Foundation::DateTime startDate, _In_ DateDifference duration); + Platform::IBox ^ SubtractDuration(_In_ Windows::Foundation::DateTime startDate, _In_ DateDifference duration); + Platform::IBox< + DateDifference> ^ TryGetDateDifference(_In_ Windows::Foundation::DateTime date1, _In_ Windows::Foundation::DateTime date2, _In_ DateUnit outputFormat); private: // Private Variables @@ -76,3 +67,5 @@ namespace CalculatorApp } } } + +bool operator==(const CalculatorApp::Common::DateCalculation::DateDifference& l, const CalculatorApp::Common::DateCalculation::DateDifference& r); diff --git a/src/CalcViewModel/DateCalculatorViewModel.cpp b/src/CalcViewModel/DateCalculatorViewModel.cpp index 3fcfe05..942d2b3 100644 --- a/src/CalcViewModel/DateCalculatorViewModel.cpp +++ b/src/CalcViewModel/DateCalculatorViewModel.cpp @@ -45,13 +45,13 @@ DateCalculatorViewModel::DateCalculatorViewModel() , m_StrDateResult(L"") , m_StrDateResultAutomationName(L"") { - const auto& localizationSettings = LocalizationSettings::GetInstance(); + const auto & localizationSettings = LocalizationSettings::GetInstance(); // Initialize Date Output format instances InitializeDateOutputFormats(localizationSettings.GetCalendarIdentifier()); // Initialize Date Calc engine - m_dateCalcEngine = make_shared(localizationSettings.GetCalendarIdentifier()); + m_dateCalcEngine = ref new DateCalculationEngine(localizationSettings.GetCalendarIdentifier()); // Initialize dates of DatePicker controls to today's date auto calendar = ref new Calendar(); // We force the timezone to UTC, in order to avoid being affected by Daylight Saving Time @@ -111,20 +111,20 @@ void DateCalculatorViewModel::OnPropertyChanged(_In_ String ^ prop) void DateCalculatorViewModel::OnInputsChanged() { - DateDifference dateDiff; - if (m_IsDateDiffMode) { DateTime clippedFromDate = ClipTime(FromDate, true); DateTime clippedToDate = ClipTime(ToDate, true); // Calculate difference between two dates - if (m_dateCalcEngine->TryGetDateDifference(clippedFromDate, clippedToDate, m_daysOutputFormat, &dateDiff)) + auto dateDiff = m_dateCalcEngine->TryGetDateDifference(clippedFromDate, clippedToDate, m_daysOutputFormat); + if (dateDiff != nullptr) { - DateDiffResultInDays = dateDiff; - if (m_dateCalcEngine->TryGetDateDifference(clippedFromDate, clippedToDate, m_allDateUnitsOutputFormat, &dateDiff)) + DateDiffResultInDays = dateDiff->Value; + dateDiff = m_dateCalcEngine->TryGetDateDifference(clippedFromDate, clippedToDate, m_allDateUnitsOutputFormat); + if (dateDiff != nullptr) { - DateDiffResult = dateDiff; + DateDiffResult = dateDiff->Value; } else { @@ -140,26 +140,28 @@ void DateCalculatorViewModel::OnInputsChanged() } else { + DateDifference dateDiff; dateDiff.day = DaysOffset; dateDiff.month = MonthsOffset; dateDiff.year = YearsOffset; - DateTime dateTimeResult; + IBox ^ dateTimeResult; if (m_IsAddMode) { // Add number of Days, Months and Years to a Date - IsOutOfBound = !m_dateCalcEngine->AddDuration(StartDate, dateDiff, &dateTimeResult); + dateTimeResult = m_dateCalcEngine->AddDuration(StartDate, dateDiff); } else { // Subtract number of Days, Months and Years from a Date - IsOutOfBound = !m_dateCalcEngine->SubtractDuration(StartDate, dateDiff, &dateTimeResult); + dateTimeResult = m_dateCalcEngine->SubtractDuration(StartDate, dateDiff); } + IsOutOfBound = dateTimeResult == nullptr; if (!m_isOutOfBound) { - DateResult = dateTimeResult; + DateResult = dateTimeResult->Value; } } } @@ -181,8 +183,7 @@ void DateCalculatorViewModel::UpdateDisplayResult() StrDateDiffResultInDays = L""; StrDateDiffResult = AppResourceProvider::GetInstance()->GetResourceString(L"Date_SameDates"); } - else if (m_dateDiffResult == DateDifferenceUnknown || - (m_dateDiffResult.year == 0 && m_dateDiffResult.month == 0 && m_dateDiffResult.week == 0)) + else if (m_dateDiffResult == DateDifferenceUnknown || (m_dateDiffResult.year == 0 && m_dateDiffResult.month == 0 && m_dateDiffResult.week == 0)) { IsDiffInDays = true; StrDateDiffResultInDays = L""; diff --git a/src/CalcViewModel/DateCalculatorViewModel.h b/src/CalcViewModel/DateCalculatorViewModel.h index c1cce24..d9e73f4 100644 --- a/src/CalcViewModel/DateCalculatorViewModel.h +++ b/src/CalcViewModel/DateCalculatorViewModel.h @@ -176,7 +176,7 @@ namespace CalculatorApp CalculatorApp::Common::DateCalculation::DateDifference m_dateDiffResultInDays; // Private members - std::shared_ptr m_dateCalcEngine; + CalculatorApp::Common::DateCalculation::DateCalculationEngine ^ m_dateCalcEngine; CalculatorApp::Common::DateCalculation::DateUnit m_daysOutputFormat; CalculatorApp::Common::DateCalculation::DateUnit m_allDateUnitsOutputFormat; Windows::Globalization::DateTimeFormatting::DateTimeFormatter ^ m_dateTimeFormatter; diff --git a/src/CalculatorUnitTests/DateCalculatorUnitTests.cpp b/src/CalculatorUnitTests/DateCalculatorUnitTests.cpp index 9d10074..a6a7ea0 100644 --- a/src/CalculatorUnitTests/DateCalculatorUnitTests.cpp +++ b/src/CalculatorUnitTests/DateCalculatorUnitTests.cpp @@ -27,8 +27,6 @@ namespace DateCalculationUnitTests const int c_subtractCases = 3; const int c_dateDiff = 14; - DateCalculationEngine m_DateCalcEngine(CalendarIdentifiers::Gregorian); - typedef struct { SYSTEMTIME startDate; @@ -45,10 +43,20 @@ namespace DateCalculationUnitTests DateTimeTestCase datetimeSubtractCase[c_subtractCases]; // Test Class - TEST_CLASS(DateCalculatorUnitTests){ public: TEST_CLASS_INITIALIZE(TestClassSetup){ /* Test Case Data */ + TEST_CLASS(DateCalculatorUnitTests) + { + static DateCalculationEngine ^ m_DateCalcEngine; - // Dates - DD.MM.YYYY - /*31.12.9999*/ date[0].wYear = 9999; + public: + TEST_CLASS_INITIALIZE(TestClassSetup) + { + m_DateCalcEngine = ref new DateCalculationEngine(CalendarIdentifiers::Gregorian); + + /* Test Case Data */ + + // Dates - DD.MM.YYYY + /*31.12.9999*/ + date[0].wYear = 9999; date[0].wMonth = 12; date[0].wDayOfWeek = 5; date[0].wDay = 31; @@ -300,7 +308,7 @@ TEST_METHOD(TestDateDiff) // } // // Calculate the difference - // m_DateCalcEngine.TryGetDateDifference(DateUtils::SystemTimeToDateTime(datetimeDifftest[testIndex].startDate), + // m_DateCalcEngine->TryGetDateDifference(DateUtils::SystemTimeToDateTime(datetimeDifftest[testIndex].startDate), // DateUtils::SystemTimeToDateTime(datetimeDifftest[testIndex].endDate), dateOutputFormat, &diff); // // Assert for the result @@ -327,7 +335,7 @@ TEST_METHOD(TestAddOob) // DateTime endDate; // // Add Duration - // bool isValid = m_DateCalcEngine.AddDuration(DateUtils::SystemTimeToDateTime(datetimeBoundAdd[testIndex].startDate), + // bool isValid = m_DateCalcEngine->AddDuration(DateUtils::SystemTimeToDateTime(datetimeBoundAdd[testIndex].startDate), // datetimeBoundAdd[testIndex].dateDiff, &endDate); // // Assert for the result @@ -340,14 +348,12 @@ TEST_METHOD(TestSubtractOob) { for (int testIndex = 0; testIndex < c_numSubtractOobDate; testIndex++) { - DateTime endDate; - // Subtract Duration - bool isValid = m_DateCalcEngine.SubtractDuration( - DateUtils::SystemTimeToDateTime(datetimeBoundSubtract[testIndex].startDate), datetimeBoundSubtract[testIndex].dateDiff, &endDate); + auto endDate = m_DateCalcEngine->SubtractDuration( + DateUtils::SystemTimeToDateTime(datetimeBoundSubtract[testIndex].startDate), datetimeBoundSubtract[testIndex].dateDiff); // Assert for the result - VERIFY_IS_FALSE(isValid); + VERIFY_IS_NULL(endDate); } } @@ -361,7 +367,7 @@ TEST_METHOD(TestAddition) // DateTime endDate; // // Add Duration - // bool isValid = m_DateCalcEngine.AddDuration(DateUtils::SystemTimeToDateTime(datetimeAddCase[testIndex].startDate), + // bool isValid = m_DateCalcEngine->AddDuration(DateUtils::SystemTimeToDateTime(datetimeAddCase[testIndex].startDate), // datetimeAddCase[testIndex].dateDiff, &endDate); // // Assert for the result @@ -390,7 +396,7 @@ TEST_METHOD(TestSubtraction) // DateTime endDate; // // Subtract Duration - // bool isValid = m_DateCalcEngine.SubtractDuration(DateUtils::SystemTimeToDateTime(datetimeSubtractCase[testIndex].startDate), + // bool isValid = m_DateCalcEngine->SubtractDuration(DateUtils::SystemTimeToDateTime(datetimeSubtractCase[testIndex].startDate), // datetimeSubtractCase[testIndex].dateDiff, &endDate); // // assert for the result @@ -408,13 +414,9 @@ TEST_METHOD(TestSubtraction) // VERIFY_IS_TRUE(isValid); //} } - -private: -} -; +}; TEST_CLASS(DateCalculatorViewModelTests){ public: TEST_CLASS_INITIALIZE(TestClassSetup){ /* Test Case Data */ - // Dates - DD.MM.YYYY /*31.12.9999*/ date[0].wYear = 9999; date[0].wMonth = 12; @@ -683,7 +685,6 @@ TEST_METHOD(DateCalcViewModelAddSubtractInitTest) TEST_METHOD(DateCalcViewModelDateDiffDaylightSavingTimeTest) { auto viewModel = ref new DateCalculatorViewModel(); - viewModel->IsDateDiffMode = true; VERIFY_IS_TRUE(viewModel->IsDateDiffMode); @@ -922,8 +923,6 @@ TEST_METHOD(DateCalcViewModelDateDiffFromDateHigherThanToDate) // contains the DayOfWeek, Day, Month, and Year TEST_METHOD(DateCalcViewModelAddSubtractResultAutomationNameTest) { - auto viewModel = ref new DateCalculatorViewModel(); - auto cal = ref new Calendar(); cal->Year = 2007; cal->Month = 5; @@ -934,6 +933,8 @@ TEST_METHOD(DateCalcViewModelAddSubtractResultAutomationNameTest) cal->Second = 0; DateTime startDate = cal->GetDateTime(); + auto viewModel = ref new DateCalculatorViewModel(); + viewModel->StartDate = startDate; viewModel->IsDateDiffMode = false; @@ -955,7 +956,7 @@ TEST_METHOD(DateCalcViewModelAddSubtractResultAutomationNameTest) TEST_METHOD(JaEraTransitionAddition) { - auto viewModel = make_unique(CalendarIdentifiers::Japanese); + auto engine = ref new DateCalculationEngine(CalendarIdentifiers::Japanese); auto cal = ref new Calendar(); // The Showa period ended in Jan 1989. @@ -973,10 +974,9 @@ TEST_METHOD(JaEraTransitionAddition) DateDifference yearDuration; yearDuration.year = 1; - DateTime actualYearResult; - viewModel->AddDuration(startTime, yearDuration, &actualYearResult); + auto actualYearResult = engine->AddDuration(startTime, yearDuration); - VERIFY_ARE_EQUAL(expectedYearResult.UniversalTime, actualYearResult.UniversalTime); + VERIFY_ARE_EQUAL(expectedYearResult.UniversalTime, actualYearResult->Value.UniversalTime); cal->Year = 1989; cal->Month = 2; @@ -987,15 +987,14 @@ TEST_METHOD(JaEraTransitionAddition) DateDifference monthDuration; monthDuration.month = 1; - DateTime actualMonthResult; - viewModel->AddDuration(startTime, monthDuration, &actualMonthResult); + auto actualMonthResult = engine->AddDuration(startTime, monthDuration); - VERIFY_ARE_EQUAL(expectedMonthResult.UniversalTime, actualMonthResult.UniversalTime); + VERIFY_ARE_EQUAL(expectedMonthResult.UniversalTime, actualMonthResult->Value.UniversalTime); } TEST_METHOD(JaEraTransitionSubtraction) { - auto viewModel = make_unique(CalendarIdentifiers::Japanese); + auto engine = ref new DateCalculationEngine(CalendarIdentifiers::Japanese); auto cal = ref new Calendar(); // The Showa period ended in Jan 1989. @@ -1013,10 +1012,9 @@ TEST_METHOD(JaEraTransitionSubtraction) DateDifference yearDuration; yearDuration.year = 1; - DateTime actualYearResult; - viewModel->SubtractDuration(startTime, yearDuration, &actualYearResult); + auto actualYearResult = engine->SubtractDuration(startTime, yearDuration); - VERIFY_ARE_EQUAL(expectedYearResult.UniversalTime, actualYearResult.UniversalTime); + VERIFY_ARE_EQUAL(expectedYearResult.UniversalTime, actualYearResult->Value.UniversalTime); cal->Year = 1989; cal->Month = 1; @@ -1027,15 +1025,14 @@ TEST_METHOD(JaEraTransitionSubtraction) DateDifference monthDuration; monthDuration.month = 1; - DateTime actualMonthResult; - viewModel->SubtractDuration(startTime, monthDuration, &actualMonthResult); + auto actualMonthResult = engine->SubtractDuration(startTime, monthDuration); - VERIFY_ARE_EQUAL(expectedMonthResult.UniversalTime, actualMonthResult.UniversalTime); + VERIFY_ARE_EQUAL(expectedMonthResult.UniversalTime, actualMonthResult->Value.UniversalTime); } TEST_METHOD(JaEraTransitionDifference) { - auto viewModel = make_unique(CalendarIdentifiers::Japanese); + auto engine = ref new DateCalculationEngine(CalendarIdentifiers::Japanese); auto cal = ref new Calendar(); // The Showa period ended in Jan 8, 1989. Pick 2 days across that boundary @@ -1049,10 +1046,12 @@ TEST_METHOD(JaEraTransitionDifference) cal->Day = 20; auto endTime = cal->GetDateTime(); - DateDifference diff; - VERIFY_IS_TRUE(viewModel->TryGetDateDifference(startTime, endTime, DateUnit::Day, &diff)); - VERIFY_ARE_EQUAL(diff.day, 19); + auto diff = engine->TryGetDateDifference(startTime, endTime, DateUnit::Day); + VERIFY_IS_NOT_NULL(diff); + VERIFY_ARE_EQUAL(diff->Value.day, 19); } } ; + +DateCalculationEngine ^ DateCalculatorUnitTests::m_DateCalcEngine; }