<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Cesar Menegatti</title>
    <description>The latest articles on Forem by Cesar Menegatti (@chmenegatti).</description>
    <link>https://forem.com/chmenegatti</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3799047%2Faa589d68-21b9-45f9-9f68-d1fbf05ae19b.jpeg</url>
      <title>Forem: Cesar Menegatti</title>
      <link>https://forem.com/chmenegatti</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/chmenegatti"/>
    <language>en</language>
    <item>
      <title>Stop Writing Date Helpers in Go: Introducing go-date-fns</title>
      <dc:creator>Cesar Menegatti</dc:creator>
      <pubDate>Sun, 01 Mar 2026 00:19:04 +0000</pubDate>
      <link>https://forem.com/chmenegatti/stop-writing-date-helpers-in-go-introducing-go-date-fns-36p3</link>
      <guid>https://forem.com/chmenegatti/stop-writing-date-helpers-in-go-introducing-go-date-fns-36p3</guid>
      <description>&lt;p&gt;Every Go developer eventually runs into the same problem:&lt;/p&gt;

&lt;p&gt;Working with dates &lt;strong&gt;looks simple… until it isn’t.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You start with something small like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;nextWeek&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;7&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Hour&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then suddenly you're dealing with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;month boundaries&lt;/li&gt;
&lt;li&gt;timezone conversions&lt;/li&gt;
&lt;li&gt;parsing multiple date formats&lt;/li&gt;
&lt;li&gt;start/end of week calculations&lt;/li&gt;
&lt;li&gt;repeated helper functions across projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After doing this in several projects, I noticed something:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I kept rewriting the same date utility functions over and over again.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So I decided to build a small open-source library to solve that problem.&lt;/p&gt;

&lt;p&gt;Introducing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;go-date-fns&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/chmenegatti/go-date-fns" rel="noopener noreferrer"&gt;https://github.com/chmenegatti/go-date-fns&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A functional date utility library for Go inspired by the JavaScript library &lt;strong&gt;date-fns&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem With Dates in Go
&lt;/h2&gt;

&lt;p&gt;The Go &lt;code&gt;time&lt;/code&gt; package is fantastic.&lt;/p&gt;

&lt;p&gt;It’s reliable, precise, and battle-tested.&lt;/p&gt;

&lt;p&gt;But when it comes to &lt;strong&gt;common date operations&lt;/strong&gt;, it can get verbose.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;Add 7 days to a date.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;nextWeek&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;7&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Hour&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works… but it forces you to think in &lt;strong&gt;hours instead of days&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now imagine doing things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;start of month&lt;/li&gt;
&lt;li&gt;end of week&lt;/li&gt;
&lt;li&gt;date comparisons&lt;/li&gt;
&lt;li&gt;leap year checks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most teams end up writing utilities like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;AddDays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;StartOfMonth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;IsWeekend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And these helpers keep appearing across different codebases.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Idea
&lt;/h2&gt;

&lt;p&gt;I wanted something simple:&lt;/p&gt;

&lt;p&gt;A set of &lt;strong&gt;small, pure functions&lt;/strong&gt; to manipulate dates.&lt;/p&gt;

&lt;p&gt;Inspired by &lt;strong&gt;date-fns&lt;/strong&gt;, the idea was to bring the same philosophy to Go:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;functional&lt;/li&gt;
&lt;li&gt;immutable&lt;/li&gt;
&lt;li&gt;composable&lt;/li&gt;
&lt;li&gt;predictable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No classes.&lt;/p&gt;

&lt;p&gt;No mutation.&lt;/p&gt;

&lt;p&gt;Just functions.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;

&lt;p&gt;Parsing a date:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;dateutils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"2024-01-15"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UTC&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding days:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;nextWeek&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;dateutils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddDays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Formatting the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;formatted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;dateutils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nextWeek&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dateutils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateISO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clean and expressive.&lt;/p&gt;




&lt;h2&gt;
  
  
  Functional and Immutable
&lt;/h2&gt;

&lt;p&gt;Every function returns a &lt;strong&gt;new date value&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;newDate&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;dateutils&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddDays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The original date stays untouched.&lt;/p&gt;

&lt;p&gt;Why this matters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;safer concurrent code&lt;/li&gt;
&lt;li&gt;easier testing&lt;/li&gt;
&lt;li&gt;predictable behavior&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Common Date Utilities
&lt;/h2&gt;

&lt;p&gt;The library includes utilities for things like:&lt;/p&gt;

&lt;h3&gt;
  
  
  Date Manipulation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;AddDays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;AddMonths&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;AddYears&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Boundaries
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;StartOfMonth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;EndOfMonth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;StartOfWeek&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;EndOfWeek&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Comparisons
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;IsBefore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;IsAfter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;IsSameDay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Validation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;IsWeekend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;IsLeapYear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;IsToday&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Built on Top of Go’s &lt;code&gt;time&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Important:&lt;/p&gt;

&lt;p&gt;This library &lt;strong&gt;does not replace Go’s &lt;code&gt;time&lt;/code&gt; package&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead it acts as a &lt;strong&gt;utility layer on top of it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That means you still get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;timezone correctness&lt;/li&gt;
&lt;li&gt;DST handling&lt;/li&gt;
&lt;li&gt;reliable parsing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All powered by the standard library.&lt;/p&gt;




&lt;h2&gt;
  
  
  Zero Dependencies
&lt;/h2&gt;

&lt;p&gt;The entire library relies only on Go’s standard library.&lt;/p&gt;

&lt;p&gt;This keeps things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lightweight&lt;/li&gt;
&lt;li&gt;safe&lt;/li&gt;
&lt;li&gt;easy to maintain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No dependency trees.&lt;/p&gt;

&lt;p&gt;No surprises.&lt;/p&gt;




&lt;h2&gt;
  
  
  When This Is Useful
&lt;/h2&gt;

&lt;p&gt;This kind of utility library becomes especially helpful in projects like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;analytics platforms&lt;/li&gt;
&lt;li&gt;reporting systems&lt;/li&gt;
&lt;li&gt;scheduling tools&lt;/li&gt;
&lt;li&gt;billing systems&lt;/li&gt;
&lt;li&gt;APIs with date filters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anywhere dates are part of the domain logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  Open Source
&lt;/h2&gt;

&lt;p&gt;The project is open source and still evolving.&lt;/p&gt;

&lt;p&gt;If you're interested in improving date utilities in Go, contributions and feedback are welcome.&lt;/p&gt;

&lt;p&gt;Repository:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/chmenegatti/go-date-fns" rel="noopener noreferrer"&gt;https://github.com/chmenegatti/go-date-fns&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Dates look simple until you start working with them at scale.&lt;/p&gt;

&lt;p&gt;Small utilities can make a huge difference in readability and maintainability.&lt;/p&gt;

&lt;p&gt;My goal with &lt;strong&gt;go-date-fns&lt;/strong&gt; is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Make date manipulation in Go easier, safer, and more expressive.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you work with dates in Go, I hope this project can save you a few hours of repetitive code.&lt;/p&gt;

</description>
      <category>go</category>
      <category>opensource</category>
      <category>programming</category>
      <category>development</category>
    </item>
  </channel>
</rss>
