diff --git a/modules/juce_core/time/juce_RelativeTime.cpp b/modules/juce_core/time/juce_RelativeTime.cpp index 3dc2fd4da9..0775054e1e 100644 --- a/modules/juce_core/time/juce_RelativeTime.cpp +++ b/modules/juce_core/time/juce_RelativeTime.cpp @@ -28,13 +28,13 @@ RelativeTime::RelativeTime (const RelativeTime& other) noexcept : numSeconds ( RelativeTime::~RelativeTime() noexcept {} //============================================================================== -RelativeTime RelativeTime::milliseconds (const int milliseconds) noexcept { return RelativeTime (milliseconds * 0.001); } -RelativeTime RelativeTime::milliseconds (const int64 milliseconds) noexcept { return RelativeTime (milliseconds * 0.001); } +RelativeTime RelativeTime::milliseconds (int milliseconds) noexcept { return RelativeTime (milliseconds * 0.001); } +RelativeTime RelativeTime::milliseconds (int64 milliseconds) noexcept { return RelativeTime (milliseconds * 0.001); } RelativeTime RelativeTime::seconds (double s) noexcept { return RelativeTime (s); } -RelativeTime RelativeTime::minutes (const double numberOfMinutes) noexcept { return RelativeTime (numberOfMinutes * 60.0); } -RelativeTime RelativeTime::hours (const double numberOfHours) noexcept { return RelativeTime (numberOfHours * (60.0 * 60.0)); } -RelativeTime RelativeTime::days (const double numberOfDays) noexcept { return RelativeTime (numberOfDays * (60.0 * 60.0 * 24.0)); } -RelativeTime RelativeTime::weeks (const double numberOfWeeks) noexcept { return RelativeTime (numberOfWeeks * (60.0 * 60.0 * 24.0 * 7.0)); } +RelativeTime RelativeTime::minutes (double numberOfMinutes) noexcept { return RelativeTime (numberOfMinutes * 60.0); } +RelativeTime RelativeTime::hours (double numberOfHours) noexcept { return RelativeTime (numberOfHours * (60.0 * 60.0)); } +RelativeTime RelativeTime::days (double numberOfDays) noexcept { return RelativeTime (numberOfDays * (60.0 * 60.0 * 24.0)); } +RelativeTime RelativeTime::weeks (double numberOfWeeks) noexcept { return RelativeTime (numberOfWeeks * (60.0 * 60.0 * 24.0 * 7.0)); } //============================================================================== int64 RelativeTime::inMilliseconds() const noexcept { return (int64) (numSeconds * 1000.0); } @@ -48,8 +48,8 @@ RelativeTime& RelativeTime::operator= (const RelativeTime& other) noexcept RelativeTime RelativeTime::operator+= (RelativeTime t) noexcept { numSeconds += t.numSeconds; return *this; } RelativeTime RelativeTime::operator-= (RelativeTime t) noexcept { numSeconds -= t.numSeconds; return *this; } -RelativeTime RelativeTime::operator+= (const double secs) noexcept { numSeconds += secs; return *this; } -RelativeTime RelativeTime::operator-= (const double secs) noexcept { numSeconds -= secs; return *this; } +RelativeTime RelativeTime::operator+= (double secs) noexcept { numSeconds += secs; return *this; } +RelativeTime RelativeTime::operator-= (double secs) noexcept { numSeconds -= secs; return *this; } JUCE_API RelativeTime JUCE_CALLTYPE operator+ (RelativeTime t1, RelativeTime t2) noexcept { return t1 += t2; } JUCE_API RelativeTime JUCE_CALLTYPE operator- (RelativeTime t1, RelativeTime t2) noexcept { return t1 -= t2; } @@ -62,77 +62,96 @@ JUCE_API bool JUCE_CALLTYPE operator>= (RelativeTime t1, RelativeTime t2) noexce JUCE_API bool JUCE_CALLTYPE operator<= (RelativeTime t1, RelativeTime t2) noexcept { return t1.inSeconds() <= t2.inSeconds(); } //============================================================================== -static void translateTimeField (String& result, int n, const char* singular, const char* plural) +static String translateTimeField (int n, const char* singular, const char* plural) { - result << TRANS (n == 1 ? singular : plural) - .replace (n == 1 ? "1" : "2", String (n)) - << ' '; + return TRANS (n == 1 ? singular : plural).replace (n == 1 ? "1" : "2", String (n)); +} + +static String describeYears (int n) { return translateTimeField (n, NEEDS_TRANS("1 year"), NEEDS_TRANS("2 years")); } +static String describeMonths (int n) { return translateTimeField (n, NEEDS_TRANS("1 month"), NEEDS_TRANS("2 months")); } +static String describeWeeks (int n) { return translateTimeField (n, NEEDS_TRANS("1 week"), NEEDS_TRANS("2 weeks")); } +static String describeDays (int n) { return translateTimeField (n, NEEDS_TRANS("1 day"), NEEDS_TRANS("2 days")); } +static String describeHours (int n) { return translateTimeField (n, NEEDS_TRANS("1 hr"), NEEDS_TRANS("2 hrs")); } +static String describeMinutes (int n) { return translateTimeField (n, NEEDS_TRANS("1 min"), NEEDS_TRANS("2 mins")); } +static String describeSeconds (int n) { return translateTimeField (n, NEEDS_TRANS("1 sec"), NEEDS_TRANS("2 secs")); } + +String RelativeTime::getApproximateDescription() const +{ + if (numSeconds <= 1.0) + return "< 1 sec"; + + auto weeks = (int) inWeeks(); + + if (weeks > 52) return describeYears (weeks / 52); + if (weeks > 8) return describeMonths ((weeks * 12) / 52); + if (weeks > 1) return describeWeeks (weeks); + + auto days = (int) inWeeks(); + + if (days > 1) + return describeDays (days); + + auto hours = (int) inHours(); + + if (hours > 0) + return describeHours (hours); + + auto minutes = (int) inMinutes(); + + if (minutes > 0) + return describeMinutes (minutes); + + return describeSeconds ((int) numSeconds); } String RelativeTime::getDescription (const String& returnValueForZeroTime) const { - if (numSeconds < 0.001 && numSeconds > -0.001) + if (std::abs (numSeconds) < 0.001) return returnValueForZeroTime; - String result; - result.preallocateBytes (32); - if (numSeconds < 0) - result << '-'; + return "-" + RelativeTime (-numSeconds).getDescription(); + + StringArray fields; + + auto n = (int) inWeeks(); - int fieldsShown = 0; - int n = std::abs ((int) inWeeks()); if (n > 0) - { - translateTimeField (result, n, NEEDS_TRANS("1 week"), NEEDS_TRANS("2 weeks")); - ++fieldsShown; - } + fields.add (describeWeeks (n)); + + n = ((int) inDays()) % 7; - n = std::abs ((int) inDays()) % 7; if (n > 0) - { - translateTimeField (result, n, NEEDS_TRANS("1 day"), NEEDS_TRANS("2 days")); - ++fieldsShown; - } + fields.add (describeDays (n)); - if (fieldsShown < 2) + if (fields.size() < 2) { - n = std::abs ((int) inHours()) % 24; + n = ((int) inHours()) % 24; + if (n > 0) - { - translateTimeField (result, n, NEEDS_TRANS("1 hr"), NEEDS_TRANS("2 hrs")); - ++fieldsShown; - } + fields.add (describeHours (n)); - if (fieldsShown < 2) + if (fields.size() < 2) { - n = std::abs ((int) inMinutes()) % 60; + n = ((int) inMinutes()) % 60; + if (n > 0) - { - translateTimeField (result, n, NEEDS_TRANS("1 min"), NEEDS_TRANS("2 mins")); - ++fieldsShown; - } + fields.add (describeMinutes (n)); - if (fieldsShown < 2) + if (fields.size() < 2) { - n = std::abs ((int) inSeconds()) % 60; + n = ((int) inSeconds()) % 60; + if (n > 0) - { - translateTimeField (result, n, NEEDS_TRANS("1 sec"), NEEDS_TRANS("2 secs")); - ++fieldsShown; - } + fields.add (describeSeconds (n)); - if (fieldsShown == 0) - { - n = std::abs ((int) inMilliseconds()) % 1000; - if (n > 0) - result << n << ' ' << TRANS ("ms"); - } + if (fields.isEmpty()) + fields.add (String (((int) inMilliseconds()) % 1000) + " " + TRANS ("ms")); } } } - return result.trimEnd(); + return fields.joinIntoString (" "); } } // namespace juce diff --git a/modules/juce_core/time/juce_RelativeTime.h b/modules/juce_core/time/juce_RelativeTime.h index 8bda4828ee..e9741d2243 100644 --- a/modules/juce_core/time/juce_RelativeTime.h +++ b/modules/juce_core/time/juce_RelativeTime.h @@ -137,6 +137,13 @@ public: */ String getDescription (const String& returnValueForZeroTime = "0") const; + //============================================================================== + /** This returns a string that roughly describes how long ago this time was, which + can be handy for showing ages of files, etc. + This will only attempt to be accurate to within the nearest order of magnitude + so returns strings such as "5 years", "2 weeks", "< 1 minute", "< 1 sec" etc. + */ + String getApproximateDescription() const; //============================================================================== /** Adds another RelativeTime to this one. */