From d582a144361e8d2bfa888e7ba7dc17beec86b3a4 Mon Sep 17 00:00:00 2001 From: coyaSONG <66289470+coyaSONG@users.noreply.github.com> Date: Sat, 18 Jul 2026 01:38:55 +0900 Subject: [PATCH] Add DateTime.toEpochSeconds --- .changeset/add-datetime-epoch-seconds.md | 5 +++++ packages/effect/src/DateTime.ts | 8 ++++++++ packages/effect/src/internal/dateTime.ts | 3 +++ packages/effect/test/DateTime.test.ts | 10 ++++++++++ 4 files changed, 26 insertions(+) create mode 100644 .changeset/add-datetime-epoch-seconds.md diff --git a/.changeset/add-datetime-epoch-seconds.md b/.changeset/add-datetime-epoch-seconds.md new file mode 100644 index 00000000000..1e9efbd633f --- /dev/null +++ b/.changeset/add-datetime-epoch-seconds.md @@ -0,0 +1,5 @@ +--- +"effect": patch +--- + +Add `DateTime.toEpochSeconds` for whole Unix timestamps. diff --git a/packages/effect/src/DateTime.ts b/packages/effect/src/DateTime.ts index 5f11606c891..738e7188738 100644 --- a/packages/effect/src/DateTime.ts +++ b/packages/effect/src/DateTime.ts @@ -938,6 +938,14 @@ export const zonedOffsetIso: (self: Zoned) => string = Internal.zonedOffsetIso */ export const toEpochMillis: (self: DateTime) => number = Internal.toEpochMillis +/** + * Get the whole seconds since the Unix epoch of a `DateTime`. + * + * @since 3.22.0 + * @category conversions + */ +export const toEpochSeconds: (self: DateTime) => number = Internal.toEpochSeconds + /** * Remove the time aspect of a `DateTime`, first adjusting for the time * zone. It will return a `DateTime.Utc` only containing the date. diff --git a/packages/effect/src/internal/dateTime.ts b/packages/effect/src/internal/dateTime.ts index 544ecd86efa..a20b3942e1b 100644 --- a/packages/effect/src/internal/dateTime.ts +++ b/packages/effect/src/internal/dateTime.ts @@ -613,6 +613,9 @@ export const zonedOffsetIso = (self: DateTime.Zoned): string => offsetToString(z /** @internal */ export const toEpochMillis = (self: DateTime.DateTime): number => self.epochMillis +/** @internal */ +export const toEpochSeconds = (self: DateTime.DateTime): number => Math.floor(self.epochMillis / 1000) + /** @internal */ export const removeTime = (self: DateTime.DateTime): DateTime.Utc => withDate(self, (date) => { diff --git a/packages/effect/test/DateTime.test.ts b/packages/effect/test/DateTime.test.ts index 6c9aa7ade46..fb692450fef 100644 --- a/packages/effect/test/DateTime.test.ts +++ b/packages/effect/test/DateTime.test.ts @@ -368,6 +368,16 @@ describe("DateTime", () => { )) }) + describe("toEpochSeconds", () => { + it("converts milliseconds to whole seconds", () => { + strictEqual(DateTime.toEpochSeconds(DateTime.unsafeMake(1_999)), 1) + }) + + it("floors timestamps before the Unix epoch", () => { + strictEqual(DateTime.toEpochSeconds(DateTime.unsafeMake(-1)), -1) + }) + }) + describe("removeTime", () => { it("removes time", () => { const dt = DateTime.unsafeMakeZoned("2024-01-01T01:00:00Z", {