Every Go developer eventually runs into the same problem:
Working with dates looks simple… until it isn’t.
You start with something small like:
date := time.Now()
nextWeek := date.Add(7 * 24 * time.Hour)
Then suddenly you're dealing with:
- month boundaries
- timezone conversions
- parsing multiple date formats
- start/end of week calculations
- repeated helper functions across projects
After doing this in several projects, I noticed something:
I kept rewriting the same date utility functions over and over again.
So I decided to build a small open-source library to solve that problem.
Introducing:
go-date-fns
👉 https://github.com/chmenegatti/go-date-fns
A functional date utility library for Go inspired by the JavaScript library date-fns.
The Problem With Dates in Go
The Go time package is fantastic.
It’s reliable, precise, and battle-tested.
But when it comes to common date operations, it can get verbose.
For example:
Add 7 days to a date.
nextWeek := date.Add(7 * 24 * time.Hour)
This works… but it forces you to think in hours instead of days.
Now imagine doing things like:
- start of month
- end of week
- date comparisons
- leap year checks
Most teams end up writing utilities like:
AddDays(date, 7)
StartOfMonth(date)
IsWeekend(date)
And these helpers keep appearing across different codebases.
The Idea
I wanted something simple:
A set of small, pure functions to manipulate dates.
Inspired by date-fns, the idea was to bring the same philosophy to Go:
- functional
- immutable
- composable
- predictable
No classes.
No mutation.
Just functions.
Example
Parsing a date:
date, err := dateutils.Parse("2024-01-15", time.UTC)
Adding days:
nextWeek := dateutils.AddDays(date, 7)
Formatting the result:
formatted, _ := dateutils.Format(nextWeek, dateutils.DateISO, nil)
Clean and expressive.
Functional and Immutable
Every function returns a new date value.
Example:
newDate := dateutils.AddDays(date, 10)
The original date stays untouched.
Why this matters:
- safer concurrent code
- easier testing
- predictable behavior
Common Date Utilities
The library includes utilities for things like:
Date Manipulation
AddDays(date, 7)
AddMonths(date, 2)
AddYears(date, 1)
Boundaries
StartOfMonth(date)
EndOfMonth(date)
StartOfWeek(date)
EndOfWeek(date)
Comparisons
IsBefore(a, b)
IsAfter(a, b)
IsSameDay(a, b)
Validation
IsWeekend(date)
IsLeapYear(year)
IsToday(date)
Built on Top of Go’s time
Important:
This library does not replace Go’s time package.
Instead it acts as a utility layer on top of it.
That means you still get:
- timezone correctness
- DST handling
- reliable parsing
All powered by the standard library.
Zero Dependencies
The entire library relies only on Go’s standard library.
This keeps things:
- lightweight
- safe
- easy to maintain
No dependency trees.
No surprises.
When This Is Useful
This kind of utility library becomes especially helpful in projects like:
- analytics platforms
- reporting systems
- scheduling tools
- billing systems
- APIs with date filters
Anywhere dates are part of the domain logic.
Open Source
The project is open source and still evolving.
If you're interested in improving date utilities in Go, contributions and feedback are welcome.
Repository:
👉 https://github.com/chmenegatti/go-date-fns
Final Thought
Dates look simple until you start working with them at scale.
Small utilities can make a huge difference in readability and maintainability.
My goal with go-date-fns is simple:
Make date manipulation in Go easier, safer, and more expressive.
If you work with dates in Go, I hope this project can save you a few hours of repetitive code.
Top comments (0)