diff --git a/CHANGELOG.md b/CHANGELOG.md index d1f878a9..c8ba0a61 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## Changelog +### 12.74.0 + +* `[timeutil]` Added method `PrettyDurationSimple` for printing duration in simple format + ### 12.73.2 * `[fmtutil]` Fixed handling negative numbers in `PrettySize` diff --git a/ek.go b/ek.go index 8b75b28c..8dc5a8d6 100644 --- a/ek.go +++ b/ek.go @@ -20,7 +20,7 @@ import ( // ////////////////////////////////////////////////////////////////////////////////// // // VERSION is current ek package version -const VERSION = "12.73.2" +const VERSION = "12.74.0" // ////////////////////////////////////////////////////////////////////////////////// // diff --git a/timeutil/example_test.go b/timeutil/example_test.go index 70bb9ef0..c5836279 100644 --- a/timeutil/example_test.go +++ b/timeutil/example_test.go @@ -15,10 +15,10 @@ import ( // ////////////////////////////////////////////////////////////////////////////////// // func ExamplePrettyDuration() { - // you can use int ... + // you can use int/int64/uint as seconds... fmt.Println(PrettyDuration(300)) - // ... and time.Duration types + // ...or time.Duration types fmt.Println(PrettyDuration(123456 * time.Second)) // Output: @@ -26,11 +26,20 @@ func ExamplePrettyDuration() { // 1 day 10 hours 17 minutes and 36 seconds } +func ExamplePrettyDurationSimple() { + // you can use int/int64/uint as seconds... + fmt.Println(PrettyDurationSimple(300)) + + // ...or time.Duration types + fmt.Println(PrettyDurationSimple(50400 * time.Second)) + + // Output: + // 5 minutes + // 14 hours +} + func ExamplePrettyDurationInDays() { - // you can use int ... fmt.Println(PrettyDurationInDays(2 * time.Hour)) - - // ... and time.Duration types fmt.Println(PrettyDurationInDays(168 * time.Hour)) // Output: diff --git a/timeutil/timeutil.go b/timeutil/timeutil.go index 28d52fc3..f88018b5 100644 --- a/timeutil/timeutil.go +++ b/timeutil/timeutil.go @@ -47,6 +47,17 @@ func PrettyDuration(d any) string { return getPrettyLongDuration(dur) } +// PrettyDurationSimple returns simple pretty duration (seconds → minutes → hours → days) +func PrettyDurationSimple(d any) string { + dur, ok := convertDuration(d) + + if !ok { + return "" + } + + return getPrettySimpleDuration(dur) +} + // PrettyDurationInDays returns pretty duration in days (e.g. 15 days) func PrettyDurationInDays(d any) string { dur, ok := convertDuration(d) @@ -92,50 +103,50 @@ func MiniDuration(d time.Duration) string { // // Interpreted sequences: // -// '%%' a literal % -// '%a' locale's abbreviated weekday name (e.g., Sun) -// '%A' locale's full weekday name (e.g., Sunday) -// '%b' locale's abbreviated month name (e.g., Jan) -// '%B' locale's full month name (e.g., January) -// '%c' locale's date and time (e.g., Thu Mar 3 23:05:25 2005) -// '%C' century; like %Y, except omit last two digits (e.g., 20) -// '%d' day of month (e.g, 01) -// '%D' date; same as %m/%d/%y -// '%e' day of month, space padded -// '%F' full date; same as %Y-%m-%d -// '%g' last two digits of year of ISO week number (see %G) -// '%G' year of ISO week number (see %V); normally useful only with %V -// '%h' same as %b -// '%H' hour (00..23) -// '%I' hour (01..12) -// '%j' day of year (001..366) -// '%k' hour ( 0..23) -// '%K' milliseconds (000..999) -// '%l' hour ( 1..12) -// '%m' month (01..12) -// '%M' minute (00..59) -// '%n' a newline -// '%N' nanoseconds (000000000..999999999) -// '%p' AM or PM -// '%P' like %p, but lower case -// '%r' locale's 12-hour clock time (e.g., 11:11:04 PM) -// '%R' 24-hour hour and minute; same as %H:%M -// '%s' seconds since 1970-01-01 00:00:00 UTC -// '%S' second (00..60) -// '%t' a tab -// '%T' time; same as %H:%M:%S -// '%u' day of week (1..7); 1 is Monday -// '%U' week number of year, with Sunday as first day of week (00..53) -// '%V' ISO week number, with Monday as first day of week (01..53) -// '%w' day of week (0..6); 0 is Sunday -// '%W' week number of year, with Monday as first day of week (00..53) -// '%x' locale's date representation (e.g., 12/31/99) -// '%X' locale's time representation (e.g., 23:13:48) -// '%y' last two digits of year (00..99) -// '%Y' year -// '%z' +hhmm numeric timezone (e.g., -0400) -// '%:z' +hh:mm numeric timezone (e.g., -04:00) -// '%Z' alphabetic time zone abbreviation (e.g., EDT) +// '%%' a literal % +// '%a' locale's abbreviated weekday name (e.g., Sun) +// '%A' locale's full weekday name (e.g., Sunday) +// '%b' locale's abbreviated month name (e.g., Jan) +// '%B' locale's full month name (e.g., January) +// '%c' locale's date and time (e.g., Thu Mar 3 23:05:25 2005) +// '%C' century; like %Y, except omit last two digits (e.g., 20) +// '%d' day of month (e.g, 01) +// '%D' date; same as %m/%d/%y +// '%e' day of month, space padded +// '%F' full date; same as %Y-%m-%d +// '%g' last two digits of year of ISO week number (see %G) +// '%G' year of ISO week number (see %V); normally useful only with %V +// '%h' same as %b +// '%H' hour (00..23) +// '%I' hour (01..12) +// '%j' day of year (001..366) +// '%k' hour ( 0..23) +// '%K' milliseconds (000..999) +// '%l' hour ( 1..12) +// '%m' month (01..12) +// '%M' minute (00..59) +// '%n' a newline +// '%N' nanoseconds (000000000..999999999) +// '%p' AM or PM +// '%P' like %p, but lower case +// '%r' locale's 12-hour clock time (e.g., 11:11:04 PM) +// '%R' 24-hour hour and minute; same as %H:%M +// '%s' seconds since 1970-01-01 00:00:00 UTC +// '%S' second (00..60) +// '%t' a tab +// '%T' time; same as %H:%M:%S +// '%u' day of week (1..7); 1 is Monday +// '%U' week number of year, with Sunday as first day of week (00..53) +// '%V' ISO week number, with Monday as first day of week (01..53) +// '%w' day of week (0..6); 0 is Sunday +// '%W' week number of year, with Monday as first day of week (00..53) +// '%x' locale's date representation (e.g., 12/31/99) +// '%X' locale's time representation (e.g., 23:13:48) +// '%y' last two digits of year (00..99) +// '%Y' year +// '%z' +hhmm numeric timezone (e.g., -0400) +// '%:z' +hh:mm numeric timezone (e.g., -04:00) +// '%Z' alphabetic time zone abbreviation (e.g., EDT) func Format(d time.Time, f string) string { input := bytes.NewBufferString(f) output := bytes.NewBufferString("") @@ -722,6 +733,23 @@ MAINLOOP: return result[0] } +func getPrettySimpleDuration(dur time.Duration) string { + d := int64(dur.Seconds()) + + switch { + case d >= _DAY: + return pluralize.PS(pluralize.En, "%d %s", d/_DAY, "day", "days") + case d >= _HOUR: + return pluralize.PS(pluralize.En, "%d %s", d/_HOUR, "hour", "hours") + case d >= _MINUTE: + return pluralize.PS(pluralize.En, "%d %s", d/_MINUTE, "minute", "minutes") + case d >= 1: + return pluralize.PS(pluralize.En, "%d %s", d, "second", "seconds") + } + + return "< 1 second" +} + // codebeat:enable[BLOCK_NESTING] func getPrettyShortDuration(d time.Duration) string { diff --git a/timeutil/timeutil_test.go b/timeutil/timeutil_test.go index f4caa55e..ba8c43c7 100644 --- a/timeutil/timeutil_test.go +++ b/timeutil/timeutil_test.go @@ -51,6 +51,16 @@ func (s *TimeUtilSuite) TestPretyDuration(c *C) { c.Assert(PrettyDuration(time.Second/36698888), Equals, "27 ns") } +func (s *TimeUtilSuite) TestPrettyDurationSimple(c *C) { + c.Assert(PrettyDurationSimple(true), Equals, "") + c.Assert(PrettyDurationSimple(0), Equals, "< 1 second") + c.Assert(PrettyDurationSimple(1), Equals, "1 second") + c.Assert(PrettyDurationSimple(123), Equals, "2 minutes") + c.Assert(PrettyDurationSimple(12134), Equals, "3 hours") + c.Assert(PrettyDurationSimple(112345), Equals, "1 day") + c.Assert(PrettyDurationSimple(4523412), Equals, "52 days") +} + func (s *TimeUtilSuite) TestPretyDurationInDays(c *C) { c.Assert(PrettyDurationInDays("ABC"), Equals, "") c.Assert(PrettyDurationInDays(120), Equals, "1 day")