From c0ff74a47b5ff943545d4495dd6c85dc3d76a271 Mon Sep 17 00:00:00 2001 From: "Ryan M. Moore" Date: Thu, 9 Jan 2025 13:43:12 -0500 Subject: [PATCH] Fix year padding in `to_rfc3339` See https://github.com/gleam-lang/time/issues/7 --- src/gleam/time/timestamp.gleam | 15 ++++++++++----- test/gleam/time/timestamp_test.gleam | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/gleam/time/timestamp.gleam b/src/gleam/time/timestamp.gleam index a940bac..36fe984 100644 --- a/src/gleam/time/timestamp.gleam +++ b/src/gleam/time/timestamp.gleam @@ -170,18 +170,23 @@ pub fn to_rfc3339(timestamp: Timestamp, offset_minutes offset: Int) -> String { let offset_minutes = modulo(offset, 60) let offset_hours = int.absolute_value(floored_div(offset, 60.0)) - let n = fn(n) { int.to_string(n) |> string.pad_start(2, "0") } + let n2 = pad_digit(_, to: 2) + let n4 = pad_digit(_, to: 4) let out = "" - let out = out <> n(years) <> "-" <> n(months) <> "-" <> n(days) + let out = out <> n4(years) <> "-" <> n2(months) <> "-" <> n2(days) let out = out <> "T" - let out = out <> n(hours) <> ":" <> n(minutes) <> ":" <> n(seconds) + let out = out <> n2(hours) <> ":" <> n2(minutes) <> ":" <> n2(seconds) case int.compare(offset, 0) { order.Eq -> out <> "Z" - order.Gt -> out <> "+" <> n(offset_hours) <> ":" <> n(offset_minutes) - order.Lt -> out <> "-" <> n(offset_hours) <> ":" <> n(offset_minutes) + order.Gt -> out <> "+" <> n2(offset_hours) <> ":" <> n2(offset_minutes) + order.Lt -> out <> "-" <> n2(offset_hours) <> ":" <> n2(offset_minutes) } } +fn pad_digit(digit: Int, to desired_length: Int) -> String { + int.to_string(digit) |> string.pad_start(desired_length, "0") +} + fn modulo(n: Int, m: Int) -> Int { case int.modulo(n, m) { Ok(n) -> n diff --git a/test/gleam/time/timestamp_test.gleam b/test/gleam/time/timestamp_test.gleam index c49ceb8..5a0836d 100644 --- a/test/gleam/time/timestamp_test.gleam +++ b/test/gleam/time/timestamp_test.gleam @@ -207,3 +207,27 @@ pub fn to_rfc3339_8_test() { |> timestamp.to_rfc3339(-120) |> should.equal("1970-01-01T02:00:00-02:00") } + +pub fn to_rfc3339_9_test() { + timestamp.from_unix_seconds(-62_167_219_200) + |> timestamp.to_rfc3339(0) + |> should.equal("0000-01-01T00:00:00Z") +} + +pub fn to_rfc3339_10_test() { + timestamp.from_unix_seconds(-62_135_596_800) + |> timestamp.to_rfc3339(0) + |> should.equal("0001-01-01T00:00:00Z") +} + +pub fn to_rfc3339_11_test() { + timestamp.from_unix_seconds(-61_851_600_000) + |> timestamp.to_rfc3339(0) + |> should.equal("0010-01-01T00:00:00Z") +} + +pub fn to_rfc3339_12_test() { + timestamp.from_unix_seconds(-59_011_459_200) + |> timestamp.to_rfc3339(0) + |> should.equal("0100-01-01T00:00:00Z") +}