diff --git a/vlib/time/custom_format_test.v b/vlib/time/custom_format_test.v index de6bf26c84..3447030875 100644 --- a/vlib/time/custom_format_test.v +++ b/vlib/time/custom_format_test.v @@ -36,3 +36,9 @@ fn test_hours() { assert time.parse('2023-08-04 22:00:45')!.custom_format('ii A i a hh A h a') == '10 PM 10 pm 10 PM 10 pm' assert time.parse('2023-08-04 23:00:45')!.custom_format('ii A i a hh A h a') == '11 PM 11 pm 11 PM 11 pm' } + +fn test_zero_date() { + zero_date := time.Time{} + res := zero_date.custom_format('M MM Mo MMM MMMM |1| D DD DDD DDDD |2| d dd ddd dddd |3| YY YYYY a A |4| H HH h hh k kk i ii e |5| m mm s ss |6| Do DDDo Q Qo QQ |7| N NN |8| M/D/YYYY N-HH:mm:ss Qo?a') + assert res == '0 00 0th Jan January |1| 0 00 0 000 |2| -1 Mo Mon Monday |3| 0 am AM |4| 0 00 12 12 1 01 0 00 e |5| 0 00 0 00 |6| 0th 0th 1 1st 01 |7| AD Anno Domini |8| 0/0/0 AD-00:00:00 1st?am' +} diff --git a/vlib/time/format.v b/vlib/time/format.v index 8922d615e8..ec45b087e1 100644 --- a/vlib/time/format.v +++ b/vlib/time/format.v @@ -5,6 +5,16 @@ module time import strings +fn iclamp(x int, a int, b int) int { + if x < a { + return a + } + if x > b { + return b + } + return x +} + // int_to_byte_array_no_pad fulfill buffer by part // it doesn't pad with leading zeros for performance reasons @[direct_array_access] @@ -401,20 +411,10 @@ pub fn (t Time) custom_format(s string) string { sb.write_string(ordinal_suffix(t.month)) } 'MMM' { - m := if t.month >= 1 && t.month <= 12 { - long_months[t.month - 1][0..3] - } else { - long_months[0][0..3] - } - sb.write_string(m) + sb.write_string(long_months[iclamp(0, t.month - 1, 11)][0..3]) } 'MMMM' { - m := if t.month >= 1 && t.month <= 12 { - long_months[t.month - 1] - } else { - long_months[0] - } - sb.write_string(m) + sb.write_string(long_months[iclamp(0, t.month - 1, 11)]) } 'D' { sb.write_string(t.day.str()) @@ -438,16 +438,16 @@ pub fn (t Time) custom_format(s string) string { sb.write_string('${t.day_of_week() % 7}') } 'dd' { - sb.write_string(long_days[t.day_of_week() - 1][0..2]) + sb.write_string(long_days[iclamp(0, t.day_of_week() - 1, 6)][0..2]) } 'ddd' { - sb.write_string(long_days[t.day_of_week() - 1][0..3]) + sb.write_string(long_days[iclamp(0, t.day_of_week() - 1, 6)][0..3]) } 'dddd' { - sb.write_string(long_days[t.day_of_week() - 1]) + sb.write_string(long_days[iclamp(0, t.day_of_week() - 1, 6)]) } 'YY' { - sb.write_string(t.year.str()[2..4]) + sb.write_string(t.year.str()#[2..4]) } 'YYYY' { sb.write_string(t.year.str()) diff --git a/vlib/time/time.v b/vlib/time/time.v index 8b82041264..9e18c8ef52 100644 --- a/vlib/time/time.v +++ b/vlib/time/time.v @@ -288,7 +288,7 @@ pub fn day_of_week(y int, m int, d int) int { if m < 3 { sy = sy - 1 } - return (sy + sy / 4 - sy / 100 + sy / 400 + t[m - 1] + d - 1) % 7 + 1 + return (sy + sy / 4 - sy / 100 + sy / 400 + t[iclamp(0, m - 1, 11)] + d - 1) % 7 + 1 } // day_of_week returns the current day as an integer. @@ -330,7 +330,7 @@ pub fn (t Time) week_of_year() int { // year_day returns the current day of the year as an integer. // See also #Time.custom_format . pub fn (t Time) year_day() int { - yday := t.day + days_before[t.month - 1] + yday := t.day + days_before[iclamp(0, t.month - 1, 12)] if is_leap_year(t.year) && t.month > 2 { return yday + 1 } @@ -340,13 +340,13 @@ pub fn (t Time) year_day() int { // weekday_str returns the current day as a string 3 letter abbreviation. pub fn (t Time) weekday_str() string { i := t.day_of_week() - 1 - return long_days[i][0..3] + return long_days[iclamp(0, i, 6)][0..3] } // long_weekday_str returns the current day as a string. pub fn (t Time) long_weekday_str() string { i := t.day_of_week() - 1 - return long_days[i] + return long_days[iclamp(0, i, 6)] } // is_leap_year checks if a given a year is a leap year.