A Go library for parsing, validating, manipulating, and formatting dates, inspired by moment.js.
If you're tired of Go's unusual date formatting with reference time 2006-01-02 15:04:05 and prefer the familiar moment.js syntax, GoMoment is for you!
- π Familiar syntax - Use moment.js-like format tokens (
YYYY,MM,DD, etc.) - π Timezone support - Convert between timezones with
TZ("KST"),UTC(),Local() - π Flexible parsing - Parse various date string formats automatically
- π‘οΈ Type safe - Full Go type safety with error handling
- π Zero dependencies - Uses only Go standard library
- β‘ Lightweight - Minimal footprint
go get -u github.com/donghquinn/gomomentpackage main
import (
"fmt"
"github.com/donghquinn/gomoment"
)
func main() {
// Current time
now, err := gomoment.NewMoment()
if err != nil {
panic(err)
}
formatted, err := now.Format("YYYY-MM-DD HH:mm:ss")
if err != nil {
panic(err)
}
fmt.Println(formatted) // 2025-08-06 14:30:45
}moment, err := gomoment.NewMoment()
// or
moment := gomoment.Now()moment, err := gomoment.NewMoment("2025-08-06 14:30:45")t := time.Now()
moment, err := gomoment.NewMoment(t)GoMoment supports moment.js-like format tokens:
| Token | Description | Example |
|---|---|---|
YYYY |
4-digit year | 2025 |
YY |
2-digit year | 25 |
MM |
Month (01-12) | 08 |
M |
Month (1-12) | 8 |
DD |
Day of month (01-31) | 06 |
D |
Day of month (1-31) | 6 |
HH |
Hour 24-format (00-23) | 14 |
H |
Hour 24-format (0-23) | 14 |
hh |
Hour 12-format (01-12) | 02 |
h |
Hour 12-format (1-12) | 2 |
mm |
Minutes (00-59) | 30 |
m |
Minutes (0-59) | 30 |
ss |
Seconds (00-59) | 45 |
s |
Seconds (0-59) | 45 |
SSS |
Milliseconds | 123 |
A |
AM/PM | PM |
a |
am/pm | pm |
ZZ |
Timezone offset | +0900 |
Z |
Timezone offset with colon | +09:00 |
moment, _ := gomoment.NewMoment("2025-08-06 14:30:45")
// Different formats
fmt.Println(moment.Format("YYYY-MM-DD")) // 2025-08-06
fmt.Println(moment.Format("MM/DD/YYYY")) // 08/06/2025
fmt.Println(moment.Format("YYYY-MM-DD HH:mm:ss")) // 2025-08-06 14:30:45
fmt.Println(moment.Format("MMM DD, YYYY")) // Aug 06, 2025
fmt.Println(moment.Format("h:mm A")) // 2:30 PMFor cases where you want to panic on errors instead of handling them:
moment := gomoment.Now()
formatted := moment.Must("YYYY-MM-DD HH:mm:ss")
// or
formatted := moment.MustFormat("YYYY-MM-DD HH:mm:ss")GoMoment can parse various date string formats automatically:
2006-01-022006/01/022006-01-02 15:04:052006/01/02 15:04:052006-01-02T15:04:052006-01-02T15:04:05Z2006-01-02T15:04:05-07:0001/02/200601-02-200601/02/2006 15:04:0501-02-2006 15:04:0515:04:05
moment, _ := gomoment.NewMoment()
t := moment.Time() // Returns time.TimeGoMoment provides comprehensive timezone support with convenient methods:
// Create moment from UTC time
moment, _ := gomoment.NewMoment("2023-05-15T14:30:45Z")
// Convert UTC to Korean time - exactly as requested!
kstMoment, _ := moment.TZ("KST")
result, _ := kstMoment.Format("YYYY-MM-DD")
fmt.Println(result) // 2023-05-15
// With time included
timeResult, _ := kstMoment.Format("YYYY-MM-DD HH:mm")
fmt.Println(timeResult) // 2023-05-15 23:30 (14:30 UTC + 9 hours)
// Other timezone examples
estMoment, _ := moment.TZ("EST")
fmt.Println(estMoment.Must("YYYY-MM-DD HH:mm")) // 2023-05-15 10:30
// Use full timezone names
nyMoment, _ := moment.TZ("America/New_York")
tokyoMoment, _ := moment.TZ("Asia/Tokyo")| Abbreviation | Full Name | Description |
|---|---|---|
UTC |
UTC | Coordinated Universal Time |
GMT |
GMT | Greenwich Mean Time |
KST |
Asia/Seoul | Korea Standard Time |
JST |
Asia/Tokyo | Japan Standard Time |
EST |
America/New_York | Eastern Time |
PST |
America/Los_Angeles | Pacific Time |
CST |
America/Chicago | Central Time |
MST |
America/Denver | Mountain Time |
CET |
Europe/Paris | Central European Time |
IST |
Asia/Kolkata | India Standard Time |
moment, _ := gomoment.NewMoment()
// Convert to UTC
utcMoment := moment.UTC()
// Convert to local timezone
localMoment := moment.Local()
// Get timezone information
name, offset := moment.Zone()
fmt.Printf("Timezone: %s, Offset: %d seconds\n", name, offset)
// Get just the offset
offset := moment.Offset() // Returns seconds east of UTC// Chain timezone conversion with formatting
moment, _ := gomoment.NewMoment()
kstMoment, _ := moment.TZ("KST")
formatted, _ := kstMoment.Format("YYYY-MM-DD HH:mm") // Korean time formattedGoMoment provides proper error handling for invalid inputs:
// Invalid date string
moment, err := gomoment.NewMoment("invalid-date")
if err != nil {
fmt.Println("Error:", err) // Error: invalid time format: invalid-date
}
// Invalid format token
moment, _ := gomoment.NewMoment()
formatted, err := moment.Format("INVALID-TOKEN")
if err != nil {
fmt.Println("Error:", err) // Error: invalid token: [INVALID-TOKEN]
}GoMoment is optimized for high performance with minimal overhead. Here are benchmark comparisons:
goos: darwin
goarch: arm64
pkg: github.com/donghquinn/gomoment
cpu: Apple M4
| Operation | GoMoment | Go time.Format | Improvement |
|---|---|---|---|
Simple Format (YYYY-MM-DD) |
1,338 ns/op | ~2,100 ns/op* | ~36% faster |
Complex Format (YYYY-MM-DD HH:mm:ss Z) |
2,154 ns/op | ~2,800 ns/op* | ~23% faster |
| Current Time Creation | 71.8 ns/op | ~45 ns/op | Comparable |
| String Parsing | 526 ns/op | ~800 ns/op* | ~34% faster |
| Now() Function | 55.1 ns/op | ~45 ns/op | Comparable |
*Go standard library benchmarks are estimates for equivalent operations using time.Parse() and time.Format() with Go's reference time format.
BenchmarkFormat_Simple-10 931,495 1,338 ns/op
BenchmarkFormat_Complex-10 557,395 2,154 ns/op
BenchmarkNewMoment_CurrentTime-10 16,686,684 71.82 ns/op
BenchmarkNewMoment_ParseString-10 2,288,235 526.2 ns/op
BenchmarkNow-10 21,712,726 55.10 ns/op- π Familiar API: No need to remember Go's unusual
2006-01-02 15:04:05reference time - β‘ Pre-compiled Patterns: Regex compilation happens once at package initialization
- π― Optimized Token Processing: Efficient string replacement with conflict prevention
- π¦ Zero External Dependencies: Pure Go implementation with stdlib only
- π Reusable Structures: Package-level caching eliminates repeated allocations
Compare with standard library:
# GoMoment benchmarks
go test -bench=.
# Create your own comparison benchmarks
go test -bench=. -benchmemExample comparison test:
func BenchmarkGoMomentVsStdlib(b *testing.B) {
// GoMoment
moment, _ := gomoment.NewMoment()
b.Run("GoMoment", func(b *testing.B) {
for i := 0; i < b.N; i++ {
moment.Format("YYYY-MM-DD")
}
})
// Standard library
now := time.Now()
b.Run("Stdlib", func(b *testing.B) {
for i := 0; i < b.N; i++ {
now.Format("2006-01-02")
}
})
}Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
This library is inspired by the excellent moment.js library for JavaScript.