diff --git a/CHANGELOG.md b/CHANGELOG.md index 5364a70..800b7ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- Switched to using `gleam_time` instead of `birl`. + - All `birl.Time` usages have been replaced with `gleam/time/timestamp.Timestamp`. + - All `birl.Duration` usages have been replaced with `gleam/time/duration.Duration`. + ## [1.0.1] - 2025-07-26 ### Changed diff --git a/gleam.toml b/gleam.toml index 485694f..cb6012c 100644 --- a/gleam.toml +++ b/gleam.toml @@ -5,10 +5,10 @@ licenses = ["MIT"] repository = { type = "github", user = "maxdeviant", repo = "bigben" } [dependencies] -birl = ">= 1.8.0 and < 2.0.0" gleam_erlang = ">= 1.2.0 and < 2.0.0" gleam_otp = ">= 1.0.0 and < 2.0.0" gleam_stdlib = ">= 0.62.0 and < 1.0.0" +gleam_time = ">= 1.4.0 and < 2.0.0" [dev-dependencies] gleeunit = ">= 1.6.1 and < 2.0.0" diff --git a/manifest.toml b/manifest.toml index 6a68872..76ce8c1 100644 --- a/manifest.toml +++ b/manifest.toml @@ -2,19 +2,16 @@ # You typically do not need to edit this file packages = [ - { name = "birl", version = "1.8.0", build_tools = ["gleam"], requirements = ["gleam_regexp", "gleam_stdlib", "ranger"], otp_app = "birl", source = "hex", outer_checksum = "2AC7BA26F998E3DFADDB657148BD5DDFE966958AD4D6D6957DD0D22E5B56C400" }, { name = "gleam_erlang", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "F91CE62A2D011FA13341F3723DB7DB118541AAA5FE7311BD2716D018F01EF9E3" }, { name = "gleam_otp", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "7020E652D18F9ABAC9C877270B14160519FA0856EE80126231C505D719AD68DA" }, - { name = "gleam_regexp", version = "1.1.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_regexp", source = "hex", outer_checksum = "9C215C6CA84A5B35BB934A9B61A9A306EC743153BE2B0425A0D032E477B062A9" }, { name = "gleam_stdlib", version = "0.62.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "DC8872BC0B8550F6E22F0F698CFE7F1E4BDA7312FDEB40D6C3F44C5B706C8310" }, - { name = "gleam_yielder", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_yielder", source = "hex", outer_checksum = "8E4E4ECFA7982859F430C57F549200C7749823C106759F4A19A78AEA6687717A" }, + { name = "gleam_time", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_time", source = "hex", outer_checksum = "DCDDC040CE97DA3D2A925CDBBA08D8A78681139745754A83998641C8A3F6587E" }, { name = "gleeunit", version = "1.6.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "FDC68A8C492B1E9B429249062CD9BAC9B5538C6FBF584817205D0998C42E1DAC" }, - { name = "ranger", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_yielder"], otp_app = "ranger", source = "hex", outer_checksum = "C8988E8F8CDBD3E7F4D8F2E663EF76490390899C2B2885A6432E942495B3E854" }, ] [requirements] -birl = { version = ">= 1.8.0 and < 2.0.0" } gleam_erlang = { version = ">= 1.2.0 and < 2.0.0" } gleam_otp = { version = ">= 1.0.0 and < 2.0.0" } gleam_stdlib = { version = ">= 0.62.0 and < 1.0.0" } +gleam_time = { version = ">= 1.4.0 and < 2.0.0" } gleeunit = { version = ">= 1.6.1 and < 2.0.0" } diff --git a/src/bigben/clock.gleam b/src/bigben/clock.gleam index 5defe92..5412480 100644 --- a/src/bigben/clock.gleam +++ b/src/bigben/clock.gleam @@ -1,20 +1,20 @@ //// A clock. import bigben/fake_clock.{type FakeClock} -import birl.{type Time} +import gleam/time/timestamp.{type Timestamp} /// A clock. pub opaque type Clock { - Clock(utc_now: fn() -> Time) + Clock(utc_now: fn() -> Timestamp) } /// Returns a new `Clock`. pub fn new() -> Clock { - Clock(birl.utc_now) + Clock(timestamp.system_time) } -/// Returns the current time on the given `Clock`, in UTC. -pub fn now(clock: Clock) -> Time { +/// Returns the current time on the given `Clock`. +pub fn now(clock: Clock) -> Timestamp { clock.utc_now() } diff --git a/src/bigben/fake_clock.gleam b/src/bigben/fake_clock.gleam index cfeee94..45478d2 100644 --- a/src/bigben/fake_clock.gleam +++ b/src/bigben/fake_clock.gleam @@ -1,9 +1,9 @@ //// A fake clock for manipulating the flow of time. -import birl.{type Time} -import birl/duration.{type Duration} import gleam/erlang/process.{type Subject} import gleam/otp/actor +import gleam/time/duration.{type Duration} +import gleam/time/timestamp.{type Timestamp} /// A fake clock. pub opaque type FakeClock { @@ -12,25 +12,25 @@ pub opaque type FakeClock { /// Returns a new `FakeClock`. /// -/// The current time will be now in UTC. +/// The current time will be the instant the clock was created. pub fn new() -> FakeClock { - new_at(birl.utc_now()) + new_at(timestamp.system_time()) } /// Returns a new `FakeClock` at the given time. -pub fn new_at(now: Time) -> FakeClock { +pub fn new_at(now: Timestamp) -> FakeClock { let assert Ok(actor) = actor.new(now) |> actor.on_message(handle_message) |> actor.start FakeClock(actor.data) } /// Returns the current time on the given `FakeClock`. -pub fn now(clock: FakeClock) -> Time { +pub fn now(clock: FakeClock) -> Timestamp { process.call(clock.subject, 10, Get) } /// Sets the current time on the given `FakeClock` to the specified value. -pub fn set_now(clock: FakeClock, now: Time) -> Nil { +pub fn set_now(clock: FakeClock, now: Timestamp) -> Nil { process.send(clock.subject, Set(now)) } @@ -40,18 +40,18 @@ pub fn advance(clock: FakeClock, duration: Duration) -> Nil { } type Message { - Get(reply_with: Subject(Time)) - Set(Time) + Get(reply_with: Subject(Timestamp)) + Set(Timestamp) Advance(Duration) } -fn handle_message(state: Time, message: Message) { +fn handle_message(state: Timestamp, message: Message) { case message { Get(client) -> { process.send(client, state) actor.continue(state) } Set(now) -> actor.continue(now) - Advance(duration) -> actor.continue(birl.add(state, duration)) + Advance(duration) -> actor.continue(timestamp.add(state, duration)) } } diff --git a/test/bigben/clock_test.gleam b/test/bigben/clock_test.gleam index ba118ee..7fe9cb8 100644 --- a/test/bigben/clock_test.gleam +++ b/test/bigben/clock_test.gleam @@ -1,32 +1,32 @@ import bigben/clock.{type Clock} import bigben/fake_clock -import birl.{Day} -import birl/duration import gleam/int +import gleam/time/calendar +import gleam/time/duration +import gleam/time/timestamp import gleeunit/should pub fn clock_can_be_faked_test() { - let assert Ok(now) = birl.parse("2024-04-12T01:33:46.382Z") + let assert Ok(now) = timestamp.parse_rfc3339("2024-04-12T01:33:46.382Z") let fake_clock = fake_clock.new_at(now) let clock = clock.from_fake(fake_clock) what_day_is_it(clock) - |> should.equal("Today is Friday, April 12, 2024") + |> should.equal("Today is April 12, 2024") - fake_clock.advance(fake_clock, duration.days(5)) + fake_clock.advance(fake_clock, duration.hours(5 * 24)) what_day_is_it(clock) - |> should.equal("Today is Wednesday, April 17, 2024") + |> should.equal("Today is April 17, 2024") } fn what_day_is_it(clock: Clock) -> String { let now = clock.now(clock) + let #(date, _time) = now |> timestamp.to_calendar(calendar.utc_offset) - let weekday = birl.string_weekday(now) - let month = birl.string_month(now) - let Day(year, _, day) = birl.get_day(now) - let day = int.to_string(day) - let year = int.to_string(year) + let month = date.month |> calendar.month_to_string + let day = int.to_string(date.day) + let year = int.to_string(date.year) - "Today is " <> weekday <> ", " <> month <> " " <> day <> ", " <> year + "Today is " <> month <> " " <> day <> ", " <> year } diff --git a/test/bigben/fake_clock_test.gleam b/test/bigben/fake_clock_test.gleam index 0f9030a..93df8a7 100644 --- a/test/bigben/fake_clock_test.gleam +++ b/test/bigben/fake_clock_test.gleam @@ -1,40 +1,41 @@ import bigben/fake_clock -import birl -import birl/duration +import gleam/time/calendar +import gleam/time/duration +import gleam/time/timestamp import gleeunit/should pub fn fake_clock_set_now_test() { - let assert Ok(now) = birl.parse("2024-04-13T01:33:46.382Z") + let assert Ok(now) = timestamp.parse_rfc3339("2024-04-13T01:33:46.382Z") let clock = fake_clock.new_at(now) fake_clock.now(clock) - |> birl.to_iso8601 - |> should.equal(birl.to_iso8601(now)) + |> timestamp.to_rfc3339(calendar.utc_offset) + |> should.equal(timestamp.to_rfc3339(now, calendar.utc_offset)) - let assert Ok(new_now) = birl.parse("2025-04-13T01:33:46.382Z") + let assert Ok(new_now) = timestamp.parse_rfc3339("2025-04-13T01:33:46.382Z") fake_clock.set_now(clock, new_now) fake_clock.now(clock) - |> birl.to_iso8601 - |> should.equal(birl.to_iso8601(new_now)) + |> timestamp.to_rfc3339(calendar.utc_offset) + |> should.equal(timestamp.to_rfc3339(new_now, calendar.utc_offset)) } pub fn fake_clock_advance_test() { - let assert Ok(now) = birl.parse("2024-04-13T01:33:46.382Z") + let assert Ok(now) = timestamp.parse_rfc3339("2024-04-13T01:33:46.382Z") let clock = fake_clock.new_at(now) - fake_clock.advance(clock, duration.days(3)) + fake_clock.advance(clock, duration.hours(3 * 24)) fake_clock.now(clock) - |> birl.to_iso8601 + |> timestamp.to_rfc3339(calendar.utc_offset) |> should.equal("2024-04-16T01:33:46.382Z") - fake_clock.advance(clock, duration.weeks(6)) + fake_clock.advance(clock, duration.hours(6 * 7 * 24)) fake_clock.now(clock) - |> birl.to_iso8601 + |> timestamp.to_rfc3339(calendar.utc_offset) |> should.equal("2024-05-28T01:33:46.382Z") - fake_clock.advance(clock, duration.months(9)) + fake_clock.advance(clock, duration.hours(9 * 30 * 24)) fake_clock.now(clock) - |> birl.to_iso8601 + |> timestamp.to_rfc3339(calendar.utc_offset) |> should.equal("2025-02-22T01:33:46.382Z") }