_ _ _
_ _ | |_ ___ | |_ (_)_ __ ___ ___
| | | || __|/ __| | __|| | '_ ` _ \ / _ \
| |_| || |_| (__ | |_ | | | | | | | __/
\___/ \__|\___| \__||_|_| |_| |_|\___|
The utc
package provides an enhanced, zero-dependency wrapper around Go's time.Time
that ensures your times are consistently in UTC while adding powerful convenience methods for real-world applications.
- Nil-safe operations - No more panic on nil receivers
- Guaranteed UTC storage - Eliminates timezone confusion
- Race condition tested - Safe for concurrent applications
- Comprehensive error handling - Graceful failures instead of crashes
- Rich formatting options - US/EU dates, RFC standards, custom layouts
- Automatic timezone handling - PST/PDT, EST/EDT transitions
- Flexible parsing - Handles multiple input formats automatically
- Serialization ready - JSON, YAML, Database, Text encoding
- Zero dependencies - No external packages required
- Lightweight footprint - Minimal impact on your binary size
- Go 1.18+ compatible - Works with modern and legacy Go versions
- Drop-in replacement - Compatible with standard
time.Time
methods
To install the utc
package, use the following command:
go get github.com/agentstation/utc
Requirements: Go 1.18 or later
YAML Usage: The package includes full YAML support. To use YAML functionality, install a YAML library:
go get github.com/goccy/go-yaml # Recommended YAML library
- No external dependencies for core functionality
- Lightweight - adds minimal footprint to your project
- Fast installation -
go get
with no dependency resolution delays
- Go 1.18+ support (broader than most time libraries)
- Cross-platform - works on all Go-supported platforms
- Future-proof - extensively tested across Go 1.18-1.24
- Nil-safe operations - methods return errors instead of panicking
- Race condition tested - safe for concurrent use
- Comprehensive test coverage - battle-tested with 100+ test cases
- Intuitive API - familiar time.Time wrapper with enhanced functionality
- Rich formatting options - US/EU date formats, RFC standards, custom layouts
- Automatic timezone handling - PST/PDT, EST/EDT transitions handled correctly
- Serialization ready - JSON, YAML, Database, Text encoding
- Debug mode - development-time nil pointer detection
- Flexible parsing - handles multiple time formats automatically
Get up and running in seconds:
package main
import (
"fmt"
"github.com/agentstation/utc"
)
func main() {
// Get current time in UTC
now := utc.Now()
fmt.Println("Current UTC time:", now.RFC3339())
// Parse and convert to different formats
t, _ := utc.ParseRFC3339("2024-01-15T10:30:00Z")
fmt.Println("US format:", t.USDateShort()) // "01/15/2024"
fmt.Println("EU format:", t.EUDateShort()) // "15/01/2024"
fmt.Println("Pacific time:", t.Pacific()) // Auto PST/PDT
}
See the difference between utc
and Go's standard time
package:
Feature | Standard time.Time |
utc.Time |
---|---|---|
Timezone Safety | ❌ Manual timezone handling | ✅ Always UTC, automatic conversion |
Nil Safety | ❌ Panics on nil receiver | ✅ Returns errors gracefully |
Dependencies | âś… Zero deps | âś… Zero deps (core) |
Rich Formatting | ❌ Manual layout strings | ✅ Built-in US/EU/ISO formats |
Timezone Conversion | ❌ Manual location loading | ✅ Auto PST/PDT, EST/EDT handling |
JSON Support | âś… Basic marshal/unmarshal | âś… Enhanced parsing & formatting |
YAML Support | ❌ No built-in support | ✅ Full YAML marshal/unmarshal |
Text Encoding | ❌ Limited support | ✅ Full MarshalText/UnmarshalText |
Database Ready | âś… Basic support | âś… Enhanced Scan/Value methods |
Unix Timestamps | âś… Basic Unix() method | âś… Unix + UnixMilli helpers |
Day Boundaries | ❌ Manual calculation | ✅ StartOfDay/EndOfDay methods |
Production Safety | ❌ Can panic unexpectedly | ✅ Error-first design |
Debug Support | ❌ No debugging aids | ✅ Optional debug mode |
Before (standard library):
loc, _ := time.LoadLocation("America/New_York")
t := time.Now().In(loc) // Hope timezone exists!
if t != nil { // Manual nil checking
fmt.Println(t.Format("01/02/2006")) // Remember layout
}
After (with UTC):
t := utc.Now()
fmt.Println(t.Eastern().Format(time.Kitchen)) // Auto EST/EDT
fmt.Println(t.USDateShort()) // "01/15/2024"
// No panics, no manual timezone loading, no layout memorization!
- Import the package:
import "github.com/agentstation/utc"
- Create a new UTC time:
// Get current time in UTC
now := utc.Now()
// Convert existing time.Time to UTC
myTime := utc.New(someTime)
// Parse a time string
t, err := utc.ParseRFC3339("2023-01-01T12:00:00Z")
- Format times using various layouts:
t := utc.Now()
// US formats
fmt.Println(t.USDateShort()) // "01/02/2024"
fmt.Println(t.USDateTime12()) // "01/02/2024 03:04:05 PM"
// EU formats
fmt.Println(t.EUDateShort()) // "02/01/2024"
fmt.Println(t.EUDateTime24()) // "02/01/2024 15:04:05"
// ISO/RFC formats
fmt.Println(t.RFC3339()) // "2024-01-02T15:04:05Z"
fmt.Println(t.ISO8601()) // "2024-01-02T15:04:05Z"
// Components
fmt.Println(t.WeekdayLong()) // "Tuesday"
fmt.Println(t.MonthShort()) // "Jan"
- Convert between timezones:
t := utc.Now()
// Get time in different US timezones
pacific := t.Pacific() // Handles PST/PDT automatically
eastern := t.Eastern() // Handles EST/EDT automatically
central := t.Central() // Handles CST/CDT automatically
mountain := t.Mountain() // Handles MST/MDT automatically
- Serialization and Database operations:
// JSON marshaling
type Event struct {
StartTime utc.Time `json:"start_time"`
EndTime utc.Time `json:"end_time"`
}
// YAML marshaling (requires a YAML library like go-yaml)
type Config struct {
StartTime utc.Time `yaml:"start_time"`
EndTime utc.Time `yaml:"end_time"`
}
// Database operations
type Record struct {
CreatedAt utc.Time `db:"created_at"`
UpdatedAt utc.Time `db:"updated_at"`
}
The package includes full YAML marshaling/unmarshaling support through MarshalYAML
/UnmarshalYAML
methods that implement the standard YAML interfaces. Works with any Go YAML library that follows these interfaces.
Requirements for YAML testing:
- Go 1.21.0+ (required by go-yaml dependency)
github.com/goccy/go-yaml
package
# Install the YAML testing dependency
go get github.com/goccy/[email protected]
# Run all tests including YAML functionality
go test -tags yaml ./...
# Run only YAML-specific tests
go test -tags yaml -run YAML ./...
Note: The YAML marshal/unmarshal methods are available in the main package, but the actual YAML processing requires the go-yaml dependency. Most users won't need YAML functionality for production use.
The project includes comprehensive Makefile targets for testing:
# Run core tests (Go 1.18+, no dependencies)
make test
# Run tests with YAML support (requires Go 1.21.0+)
make test-yaml
# Run all tests (core + YAML)
make test-all
# Generate coverage reports
make coverage # Core tests only
make coverage-yaml # Include YAML tests
make coverage-all # Both coverage reports
The package includes a debug mode that helps identify potential bugs during development:
# Build with debug mode enabled
go build -tags debug
# Run tests with debug mode
go test -tags debug ./...
When debug mode is enabled, the package logs warnings when methods are called on nil receivers:
[UTC DEBUG] 2024/01/02 15:04:05 debug.go:26: String() called on nil *Time receiver
[UTC DEBUG] 2024/01/02 15:04:05 debug.go:26: Value() called on nil *Time receiver
The package includes several convenience methods:
// Unix timestamp conversions
t1 := utc.FromUnix(1704199445) // From Unix seconds
t2 := utc.FromUnixMilli(1704199445000) // From Unix milliseconds
seconds := t.Unix() // To Unix seconds
millis := t.UnixMilli() // To Unix milliseconds
// Day boundaries
start := t.StartOfDay() // 2024-01-02 00:00:00.000000000 UTC
end := t.EndOfDay() // 2024-01-02 23:59:59.999999999 UTC
// Generic timezone conversion
eastern, err := t.In("America/New_York")
tokyo, err := t.In("Asia/Tokyo")
import "github.com/agentstation/utc"
Package utc provides a time.Time wrapper that ensures all times are in UTC.
The package offers enhanced safety by gracefully handling nil receivers instead of panicking, making it more suitable for production environments. When compiled with the debug build tag (-tags debug), it provides additional logging for nil receiver method calls to help identify potential bugs during development.
Key features:
- All times are automatically converted to and stored in UTC
- JSON marshaling/unmarshaling with flexible parsing
- Full YAML marshaling/unmarshaling support
- SQL database compatibility with enhanced type support
- Timezone conversion helpers with automatic DST handling
- Extensive formatting options for US and EU date formats
- Nil-safe operations that return errors instead of panicking
Debug mode:
To enable debug logging, compile with: go build -tags debug
This will log warnings when methods are called on nil receivers.
- func ValidateTimezoneAvailability() error
- type Time
- func FromUnix(sec int64) Time
- func FromUnixMilli(ms int64) Time
- func New(t time.Time) Time
- func Now() Time
- func Parse(layout string, s string) (Time, error)
- func ParseRFC3339(s string) (Time, error)
- func ParseRFC3339Nano(s string) (Time, error)
- func (t Time) ANSIC() string
- func (t Time) Add(d time.Duration) Time
- func (t Time) After(u Time) bool
- func (t Time) Before(u Time) bool
- func (t Time) CST() time.Time
- func (t Time) Central() time.Time
- func (t Time) DateOnly() string
- func (t Time) EST() time.Time
- func (t Time) EUDateLong() string
- func (t Time) EUDateShort() string
- func (t Time) EUDateTime12() string
- func (t Time) EUDateTime24() string
- func (t Time) EUTime12() string
- func (t Time) EUTime24() string
- func (t Time) Eastern() time.Time
- func (t Time) EndOfDay() Time
- func (t Time) Equal(u Time) bool
- func (t Time) Format(layout string) string
- func (t Time) ISO8601() string
- func (t Time) In(name string) (time.Time, error)
- func (t Time) InLocation(loc *time.Location) time.Time
- func (t Time) IsZero() bool
- func (t Time) Kitchen() string
- func (t Time) MST() time.Time
- func (t *Time) MarshalJSON() ([]byte, error)
- func (t Time) MarshalText() ([]byte, error)
- func (t Time) MarshalYAML() (any, error)
- func (t Time) MonthLong() string
- func (t Time) MonthShort() string
- func (t Time) Mountain() time.Time
- func (t Time) PST() time.Time
- func (t Time) Pacific() time.Time
- func (t Time) RFC3339() string
- func (t Time) RFC3339Nano() string
- func (t Time) RFC822() string
- func (t Time) RFC822Z() string
- func (t Time) RFC850() string
- func (t *Time) Scan(value any) error
- func (t Time) StartOfDay() Time
- func (t *Time) String() string
- func (t Time) Sub(u Time) time.Duration
- func (t Time) TimeFormat(layout TimeLayout) string
- func (t Time) TimeOnly() string
- func (t Time) USDateLong() string
- func (t Time) USDateShort() string
- func (t Time) USDateTime12() string
- func (t Time) USDateTime24() string
- func (t Time) USTime12() string
- func (t Time) USTime24() string
- func (t Time) UTC() time.Time
- func (t Time) Unix() int64
- func (t Time) UnixMilli() int64
- func (t *Time) UnmarshalJSON(data []byte) error
- func (t *Time) UnmarshalText(text []byte) error
- func (t *Time) UnmarshalYAML(unmarshal func(any) error) error
- func (t *Time) Value() (driver.Value, error)
- func (t Time) WeekdayLong() string
- func (t Time) WeekdayShort() string
- type TimeLayout
func ValidateTimezoneAvailability() error
ValidateTimezoneAvailability checks if all timezone locations were properly initialized Returns nil if initialization was successful, otherwise returns the initialization error
type Time
Time is an alias for time.Time that defaults to UTC time.
type Time struct {
time.Time
}
func FromUnix
func FromUnix(sec int64) Time
Unix helpers
func FromUnixMilli
func FromUnixMilli(ms int64) Time
func New
func New(t time.Time) Time
New returns a new Time from a time.Time
func Now
func Now() Time
Now returns the current time in UTC
func Parse
func Parse(layout string, s string) (Time, error)
Parse parses a time string in the specified format and returns a utc.Time
func ParseRFC3339
func ParseRFC3339(s string) (Time, error)
ParseRFC3339 parses a time string in RFC3339 format and returns a utc.Time
func ParseRFC3339Nano
func ParseRFC3339Nano(s string) (Time, error)
ParseRFC3339Nano parses a time string in RFC3339Nano format and returns a utc.Time
func (Time) ANSIC
func (t Time) ANSIC() string
ANSIC formats time as "Mon Jan _2 15:04:05 2006"
func (Time) Add
func (t Time) Add(d time.Duration) Time
Add returns the time t+d
func (Time) After
func (t Time) After(u Time) bool
After reports whether the time is after u
func (Time) Before
func (t Time) Before(u Time) bool
Before reports whether the time is before u
func (Time) CST
func (t Time) CST() time.Time
CST returns t in CST
func (Time) Central
func (t Time) Central() time.Time
Central returns t in Central time (handles CST/CDT automatically)
func (Time) DateOnly
func (t Time) DateOnly() string
DateOnly formats time as "2006-01-02"
func (Time) EST
func (t Time) EST() time.Time
EST returns t in EST
func (Time) EUDateLong
func (t Time) EUDateLong() string
EUDateLong formats time as "2 January 2006"
func (Time) EUDateShort
func (t Time) EUDateShort() string
EUDateShort formats time as "02/01/2006"
func (Time) EUDateTime12
func (t Time) EUDateTime12() string
EUDateTime12 formats time as "02/01/2006 03:04:05 PM"
func (Time) EUDateTime24
func (t Time) EUDateTime24() string
EUDateTime24 formats time as "02/01/2006 15:04:05"
func (Time) EUTime12
func (t Time) EUTime12() string
EUTime12 formats time as "3:04 PM"
func (Time) EUTime24
func (t Time) EUTime24() string
EUTime24 formats time as "15:04"
func (Time) Eastern
func (t Time) Eastern() time.Time
Eastern returns t in Eastern time (handles EST/EDT automatically)
func (Time) EndOfDay
func (t Time) EndOfDay() Time
func (Time) Equal
func (t Time) Equal(u Time) bool
Equal reports whether t and u represent the same time instant
func (Time) Format
func (t Time) Format(layout string) string
Format formats the time using the specified layout
func (Time) ISO8601
func (t Time) ISO8601() string
ISO8601 formats time as "2006-01-02T15:04:05Z07:00" (same as RFC3339)
func (Time) In
func (t Time) In(name string) (time.Time, error)
In converts time to a named location (e.g., "America/Los_Angeles").
func (Time) InLocation
func (t Time) InLocation(loc *time.Location) time.Time
InLocation converts time to a provided *time.Location.
func (Time) IsZero
func (t Time) IsZero() bool
Add the useful utility methods while maintaining chainability
func (Time) Kitchen
func (t Time) Kitchen() string
Kitchen formats time as "3:04PM"
func (Time) MST
func (t Time) MST() time.Time
MST returns t in MST
func (*Time) MarshalJSON
func (t *Time) MarshalJSON() ([]byte, error)
MarshalJSON implements the json.Marshaler interface for utc.Time. Returns an error for nil receivers to maintain consistency with standard marshaling behavior.
func (Time) MarshalText
func (t Time) MarshalText() ([]byte, error)
MarshalText implements encoding.TextMarshaler.
func (Time) MarshalYAML
func (t Time) MarshalYAML() (any, error)
MarshalYAML implements the yaml.Marshaler interface for utc.Time
func (Time) MonthLong
func (t Time) MonthLong() string
MonthLong formats time as "January"
func (Time) MonthShort
func (t Time) MonthShort() string
MonthShort formats time as "Jan"
func (Time) Mountain
func (t Time) Mountain() time.Time
Mountain returns t in Mountain time (handles MST/MDT automatically)
func (Time) PST
func (t Time) PST() time.Time
PST returns t in PST
func (Time) Pacific
func (t Time) Pacific() time.Time
Pacific returns t in Pacific time (handles PST/PDT automatically)
func (Time) RFC3339
func (t Time) RFC3339() string
RFC3339 formats time as "2006-01-02T15:04:05Z07:00"
func (Time) RFC3339Nano
func (t Time) RFC3339Nano() string
RFC3339Nano formats time as "2006-01-02T15:04:05.999999999Z07:00"
func (Time) RFC822
func (t Time) RFC822() string
RFC822 formats time as "02 Jan 06 15:04 MST"
func (Time) RFC822Z
func (t Time) RFC822Z() string
RFC822Z formats time as "02 Jan 06 15:04 -0700"
func (Time) RFC850
func (t Time) RFC850() string
RFC850 formats time as "Monday, 02-Jan-06 15:04:05 MST"
func (*Time) Scan
func (t *Time) Scan(value any) error
Scan implements the sql.Scanner interface for database operations for utc.Time It does this by scanning the value into a time.Time, converting the time.Time to UTC, and then assigning the UTC time to the utc.Time.
func (Time) StartOfDay
func (t Time) StartOfDay() Time
Day helpers - times are always in UTC within this package
func (*Time) String
func (t *Time) String() string
String implements the Stringer interface for utc.Time. It prints the time in RFC3339 format.
Unlike many Go types that panic on nil receivers, this method returns "<nil>" to match stdlib conventions (e.g., bytes.Buffer) and improve production safety. In debug builds (compiled with -tags debug), nil receivers are logged to help identify potential bugs.
func (Time) Sub
func (t Time) Sub(u Time) time.Duration
Sub returns the duration t-u
func (Time) TimeFormat
func (t Time) TimeFormat(layout TimeLayout) string
TimeFormat formats the time using the specified layout
func (Time) TimeOnly
func (t Time) TimeOnly() string
TimeOnly formats time as "15:04:05"
func (Time) USDateLong
func (t Time) USDateLong() string
USDateLong formats time as "January 2, 2006"
func (Time) USDateShort
func (t Time) USDateShort() string
USDateShort formats time as "01/02/2006"
func (Time) USDateTime12
func (t Time) USDateTime12() string
USDateTime12 formats time as "01/02/2006 03:04:05 PM"
func (Time) USDateTime24
func (t Time) USDateTime24() string
USDateTime24 formats time as "01/02/2006 15:04:05"
func (Time) USTime12
func (t Time) USTime12() string
USTime12 formats time as "3:04 PM"
func (Time) USTime24
func (t Time) USTime24() string
USTime24 formats time as "15:04"
func (Time) UTC
func (t Time) UTC() time.Time
UTC returns t in UTC
func (Time) Unix
func (t Time) Unix() int64
func (Time) UnixMilli
func (t Time) UnixMilli() int64
func (*Time) UnmarshalJSON
func (t *Time) UnmarshalJSON(data []byte) error
UnmarshalJSON implements the json.Unmarshaler interface for utc.Time
func (*Time) UnmarshalText
func (t *Time) UnmarshalText(text []byte) error
UnmarshalText implements encoding.TextUnmarshaler.
func (*Time) UnmarshalYAML
func (t *Time) UnmarshalYAML(unmarshal func(any) error) error
UnmarshalYAML implements the yaml.Unmarshaler interface for utc.Time
func (*Time) Value
func (t *Time) Value() (driver.Value, error)
Value implements the driver.Valuer interface for database operations for utc.Time. It returns the time.Time value and assumes the time is already in UTC.
Returns an error if called on a nil receiver instead of panicking to allow graceful error handling in database operations. In debug builds, nil receivers are logged.
func (Time) WeekdayLong
func (t Time) WeekdayLong() string
WeekdayLong formats time as "Monday"
func (Time) WeekdayShort
func (t Time) WeekdayShort() string
WeekdayShort formats time as "Mon"
type TimeLayout
type TimeLayout string
Add layout constants at package level
const (
TimeLayoutUSDateShort TimeLayout = "01/02/2006"
TimeLayoutUSDateLong TimeLayout = "January 2, 2006"
TimeLayoutUSDateTime12 TimeLayout = "01/02/2006 03:04:05 PM"
TimeLayoutUSDateTime24 TimeLayout = "01/02/2006 15:04:05"
TimeLayoutUSTime12 TimeLayout = "3:04 PM"
TimeLayoutUSTime24 TimeLayout = "15:04"
TimeLayoutEUDateShort TimeLayout = "02/01/2006"
TimeLayoutEUDateLong TimeLayout = "2 January 2006"
TimeLayoutEUDateTime12 TimeLayout = "02/01/2006 03:04:05 PM"
TimeLayoutEUDateTime24 TimeLayout = "02/01/2006 15:04:05"
TimeLayoutEUTime12 TimeLayout = "3:04 PM"
TimeLayoutEUTime24 TimeLayout = "15:04"
TimeLayoutDateOnly TimeLayout = "2006-01-02"
TimeLayoutTimeOnly TimeLayout = "15:04:05"
TimeLayoutWeekdayLong TimeLayout = "Monday"
TimeLayoutWeekdayShort TimeLayout = "Mon"
TimeLayoutMonthLong TimeLayout = "January"
TimeLayoutMonthShort TimeLayout = "Jan"
)
Generated by gomarkdoc
This project is licensed under the MIT License - see the LICENSE file for details.