dromara/carbon: a Go time package with a PHP Carbon style API
A simple, semantic and developer-friendly time package for golang
At a glance
- What is it?
- The dromara/carbon library wraps Go's time handling in a fluent, semantic API with locale aware human diffs and calendar conversions. Here is what it does, how to install it, and where it stops being the right choice.
- Who is it for?
- Adopt dromara/carbon when you need readable relative time strings, multi locale output, or calendar conversions in a Go service and you want to keep the dependency graph empty. Skip it when you need sub microsecond arithmetic, monotonic clock semantics, or you are unwilling to accept a mutable package level test clock.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What dromara/carbon solves for Go developers
Go's standard time package is precise but terse. Formatting a date means memorising the reference layout 2006-01-02 15:04:05, and producing a phrase like "1 month before" requires arithmetic you write yourself. dromara/carbon targets that gap. The README describes it as "a lightweight, semantic, and developer-friendly golang time package that doesn't depend on any third-party package", and the go.mod confirms the only direct requirement is stretchr/testify, which is a test dependency rather than a runtime one.
The audience is Go developers building applications that surface dates to people: dashboards, admin panels, notification systems, and anything that needs to render a timestamp in a user's language. The library also covers a set of calendar systems that the standard library ignores entirely, including lunar, Persian, Hebrew, Jalaali and Julian, which the repository topics list. If your product shows a Chinese lunar date or a Persian calendar date next to a Gregorian one, that work is already done here.
The project was donated to the dromara organisation, and the README notes the repository moved. Code that still imports golang-module/carbon needs a module path change, and the README supplies the exact command for it.
How the carbon package is put together
The repository layout is unusually flat and self-describing. Each capability sits in its own file plus a matching bench test, example test and unit test: boundary.go, calendar.go, comparer.go, constellation.go, creator.go, difference.go, extremum.go, frozen.go, getter.go and helper.go, with carbon.go and default.go holding the core type and package level defaults. The README claims 100% unit test coverage, and the presence of a unit test file beside every feature file is consistent with that claim, though coverage is a statement about test execution rather than about correctness on your inputs.
The API style is borrowed from PHP Carbon. You call package level constructors such as carbon.Parse or carbon.CreateFromTimestamp, get back a value, and chain methods. The README's example chains SetLocale onto a parsed value and then calls DiffForHumans, which returns "1 month before" in English and "1 月前" after switching to zh-CN. That method name and its output shape come directly from the PHP library the README lists first under References.
Defaults are set at package level: timezone UTC, locale English, week starting Monday, weekend on Saturday and Sunday. There is also a test clock. carbon.SetTestNow fixes the value that carbon.Now returns, carbon.IsTestNow reports whether it is set, and carbon.ClearTestNow resets it. The README example pins the clock to 2020-08-05 13:14:15.999999999 and shows Yesterday and Tomorrow resolving relative to that fixed instant. This is a global, mutable piece of state, which is the main architectural trade-off in the design.
Installing dromara/carbon and a first real use
The README states the requirement plainly: go version >= 1.18, matching the go directive in go.mod. Installation is a single module fetch from GitHub, with gitee and gitcode mirrors documented as alternatives. Run this inside your module:
go get -u github.com/dromara/carbon/v2Then import the package. Note the /v2 suffix, which is part of the module path and not optional:
import "github.com/dromara/carbon/v2"If your go.mod still points at the old golang-module path, the README gives a replace directive instead of a manual edit:
go mod edit -replace github.com/golang-module/carbon/v2 = github.com/dromara/carbon/v2A first useful program is a locale aware relative timestamp. The README's own example, trimmed to the parts that matter, parses a fixed instant, formats it, and then asks for a human diff in two languages:
carbon.Parse("2020-08-05 13:14:15").ToString() // 2020-08-05 13:14:15 +0000 UTC
carbon.Parse("2022-03-08T03:01:14-07:00").ToString() // 2022-03-08 10:01:14 +0000 UTC
carbon.Parse("2020-07-05 13:14:15").DiffForHumans() // 1 month before
carbon.Parse("2020-07-05 13:14:15").SetLocale("zh-CN").DiffForHumans() // 1 月前What you should see is the offset normalised to UTC in the ToString output, because UTC is the default timezone, and the diff rendered in the active locale. When a layout does not match a known format, the README shows two escape hatches: ParseByLayout takes a Go reference layout, and ParseByFormat takes a PHP style format string such as \\I\\t \\i\\s Y-m-d H:i:s. The second one exists specifically so that code ported from PHP keeps working.
The test clock is global state, and that is a real constraint
carbon.SetTestNow changes what carbon.Now returns for the entire process. In a test binary that runs cases in parallel, one test setting the clock affects every other goroutine calling carbon.Now, and the README does not document any per instance alternative or scoping mechanism. The example pairs SetTestNow with ClearTestNow, which suggests the intended pattern is set, assert, clear, but nothing in the README describes what happens if a test panics between the two calls. Treat the frozen clock as a tool for single threaded tests, or serialise the tests that use it.
A second boundary is precision and clock semantics. The README's example carries nanoseconds through ToString, so parsing preserves them, but the library is built on Go's time type and offers no monotonic clock guarantees of its own. If you are measuring elapsed durations for scheduling or rate limiting, the standard library's time.Since is the correct tool and carbon adds nothing there. The package is aimed at calendar and presentation problems, not at interval measurement.
There is also the question of what DiffForHumans means. It returns a phrase, so it is inherently lossy. The README shows "1 month before" for a date roughly a month earlier. If your application needs an exact day count, use the difference methods rather than the human string, because the human string is designed for display and its wording is locale dependent.
How carbon compares with the standard library and with gtime
The honest alternative for most Go services is the standard library alone. time.Time plus time.Parse and a small formatting helper covers parsing, arithmetic and timezone conversion with zero dependencies, and it is what every Go developer already knows. The difference in approach is the API surface: the standard library exposes one canonical layout string and makes you write the relative time logic, while carbon exposes many named constructors and a fluent chain. If your date handling is a handful of calls in one package, the standard library wins on familiarity. Carbon starts paying off when the same formatting and localisation logic would otherwise be duplicated across services.
The README also lists goframe/gtime among its references, which is the closest comparable in the Go ecosystem. Both offer a richer than standard date API. The distinction visible in the README is the calendar and locale coverage: the repository topics name hebrew, jalaali, julian, lunar and persian, and the README demonstrates locale switching in DiffForHumans. gtime is part of the GoFrame framework, so choosing it tends to pull you toward that framework's conventions. Carbon is standalone, with a go.mod that requires nothing at runtime, which matters if you want the behaviour without the surrounding ecosystem.
The PHP Carbon, moment, dayjs, arrow, Joda-Time and Noda Time projects in the References list are the conceptual ancestors. If your team already thinks in those terms, the method names here will feel familiar rather than novel.
Maintenance, licensing and the cost of upgrading
The repository is not archived. The last push was on 2026-09-21, two days before this writing, and the most recent release is v2.6.17 from 2026-08-09. The release cadence visible in the three most recent tags is roughly one release every few months, with v2.6.16 in January 2026 and v2.6.15 in November 2025. That is a maintained project by any reasonable reading, though the README does not describe a support policy, a deprecation window, or a long term support branch.
Upgrade cost is low by construction. The module path carries a major version, /v2, so a future v3 would be a separate import path rather than a breaking change to this one. Within v2, a go get -u followed by go test is the whole procedure, and the flat file layout means you can read the diff for any file whose behaviour you depend on. The one migration that has already happened is the move from golang-module to dromara, which the README addresses with a replace directive. If you are starting fresh, use the dromara path and you will never need it.
Licensing is MIT, per the README and the LICENSE file at the repository root. MIT is permissive and places essentially no conditions beyond retaining the copyright notice and licence text. That is a statement about the licence text, not legal advice; if your organisation has a policy review for dependencies, run it against the LICENSE file rather than this summary.
Editorial conclusion
Adopt dromara/carbon when you need readable relative time strings, multi locale output, or calendar conversions in a Go service and you want to keep the dependency graph empty. Skip it when you need sub microsecond arithmetic, monotonic clock semantics, or you are unwilling to accept a mutable package level test clock. Before committing, check that your Go toolchain is at least 1.18, run go get -u github.com/dromara/carbon/v2 in a scratch module, and confirm the timezone and locale defaults that your application actually needs.
Frequently asked questions
What Go version does dromara/carbon require?
The README states go version >= 1.18, and the go.mod file declares go 1.18. Anything older will not build the module as published.
How do I install dromara/carbon?
Run go get -u github.com/dromara/carbon/v2 inside your module and import github.com/dromara/carbon/v2. The README also documents gitee and gitcode mirrors as alternative sources.
Does dromara/carbon pull in third-party dependencies?
The README says it does not depend on any third-party package, and go.mod lists only stretchr/testify as a direct requirement, which is used for tests. The yaml entry is marked indirect.
How do I get a relative time string like '1 month before' in dromara/carbon?
Call DiffForHumans on a parsed value. The README shows carbon.Parse("2020-07-05 13:14:15").DiffForHumans() returning "1 month before", and the same call returning "1 月前" after SetLocale("zh-CN").
What are the default timezone and locale in dromara/carbon?
The README states the default timezone is UTC and the default language locale is English, with the week starting Monday and the weekend on Saturday and Sunday. These are package level defaults you can change.
I used golang-module/carbon. How do I move to dromara/carbon?
The README says to replace the original repository in go.mod, or run go mod edit -replace github.com/golang-module/carbon/v2 = github.com/dromara/carbon/v2. The import path becomes github.com/dromara/carbon/v2.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/dromara-carbon)