From f9d6a456e1504fcfc7de0a77461a9ae3ae9b8913 Mon Sep 17 00:00:00 2001 From: John Bytheway Date: Fri, 1 May 2020 21:56:19 -0400 Subject: [PATCH] Fix time_duration formatting For time_durations in excess of 1 week, the formatting code would do the wrong thing. It tried to format two units worth of time (e.g. 1 week and 2 days) but the second unit could never be larger than hours. Now it can be anything up to seasons. --- src/calendar.cpp | 8 +++++++- src/calendar.h | 8 ++++++++ tests/calendar_test.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/calendar.cpp b/src/calendar.cpp index aec69d6235200..2a3e119bb5500 100644 --- a/src/calendar.cpp +++ b/src/calendar.cpp @@ -332,8 +332,14 @@ std::string to_string( const time_duration &d ) divider = 1_minutes; } else if( d < 1_days ) { divider = 1_hours; + } else if( d < 1_weeks ) { + divider = 1_days; + } else if( d < calendar::season_length() || calendar::eternal_season() ) { + divider = 1_weeks; + } else if( d < calendar::year_length() ) { + divider = calendar::season_length(); } else { - divider = 24_hours; + divider = calendar::year_length(); } if( d % divider != 0_turns ) { diff --git a/src/calendar.h b/src/calendar.h index 4d6df98ab316c..3918fb0498c03 100644 --- a/src/calendar.h +++ b/src/calendar.h @@ -218,6 +218,10 @@ class time_duration static constexpr time_duration from_days( const T d ) { return from_hours( d * 24 ); } + template + static constexpr time_duration from_weeks( const T d ) { + return from_days( d * 7 ); + } /**@}*/ /** @@ -357,6 +361,10 @@ constexpr time_duration operator"" _days( const unsigned long long int v ) { return time_duration::from_days( v ); } +constexpr time_duration operator"" _weeks( const unsigned long long int v ) +{ + return time_duration::from_weeks( v ); +} /**@}*/ /** diff --git a/tests/calendar_test.cpp b/tests/calendar_test.cpp index 15d71ba0580a9..b0f589e4b5f22 100644 --- a/tests/calendar_test.cpp +++ b/tests/calendar_test.cpp @@ -1,5 +1,6 @@ #include "calendar.h" #include "catch/catch.hpp" +#include "options_helpers.h" TEST_CASE( "moon_phases_take_28_days", "[calendar]" ) { @@ -33,3 +34,40 @@ TEST_CASE( "moon_phase_changes_at_noon", "[calendar]" ) CAPTURE( num_days ); CHECK( get_moon_phase( earlier_11_hours ) == get_moon_phase( later_11_hours ) ); } + +TEST_CASE( "time_duration_to_string", "[calendar]" ) +{ + CHECK( to_string( 10_seconds ) == "10 seconds" ); + CHECK( to_string( 60_seconds ) == "1 minute" ); + CHECK( to_string( 70_seconds ) == "1 minute and 10 seconds" ); + CHECK( to_string( 60_minutes ) == "1 hour" ); + CHECK( to_string( 70_minutes ) == "1 hour and 10 minutes" ); + CHECK( to_string( 24_hours ) == "1 day" ); + CHECK( to_string( 24_hours + 1_seconds ) == "1 day and 1 second" ); + CHECK( to_string( 25_hours ) == "1 day and 1 hour" ); + CHECK( to_string( 25_hours + 1_seconds ) == "1 day and 1 hour" ); + CHECK( to_string( 7_days ) == "1 week" ); + CHECK( to_string( 8_days ) == "1 week and 1 day" ); + CHECK( to_string( 91_days ) == "1 season" ); + CHECK( to_string( 92_days ) == "1 season and 1 day" ); + CHECK( to_string( 99_days ) == "1 season and 1 week" ); + CHECK( to_string( 364_days ) == "1 year" ); + CHECK( to_string( 365_days ) == "1 year and 1 day" ); + CHECK( to_string( 465_days ) == "1 year and 1 season" ); + CHECK( to_string( 3650_days ) == "10 years and 1 week" ); +} + +TEST_CASE( "time_duration_to_string_eternal_season", "[calendar]" ) +{ + calendar::set_eternal_season( true ); + CHECK( to_string( 7_days ) == "1 week" ); + CHECK( to_string( 8_days ) == "1 week and 1 day" ); + CHECK( to_string( 91_days ) == "13 weeks" ); + CHECK( to_string( 92_days ) == "13 weeks and 1 day" ); + CHECK( to_string( 99_days ) == "14 weeks and 1 day" ); + CHECK( to_string( 364_days ) == "52 weeks" ); + CHECK( to_string( 365_days ) == "52 weeks and 1 day" ); + CHECK( to_string( 465_days ) == "66 weeks and 3 days" ); + CHECK( to_string( 3650_days ) == "521 weeks and 3 days" ); + calendar::set_eternal_season( false ); +}