chronogo

package module
v0.6.8 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 4, 2025 License: MIT Imports: 13 Imported by: 0

README

chronogo

Version Go Version License CI Security Codecov Go Reference

A comprehensive Go datetime library inspired by Python's Pendulum. chronogo enhances Go's standard time package with natural language parsing, business date operations, localization support, and a fluent API for intuitive datetime manipulation.

Features

Core Capabilities
  • Natural Language Parsing: Parse dates in 7 languages - English, Spanish, Portuguese, French, German, Chinese, Japanese (powered by godateparser)
  • Enhanced DateTime Type: Extended functionality built on Go's time.Time
  • Fluent API: Method chaining for readable, expressive code
  • Convenience Methods: On() and At() for quick date/time setting
  • Diff Type: Rich datetime differences with calendar-aware and precise calculations
  • ISO 8601 Support: Long year detection, ordinal dates, week dates, intervals
  • Immutable Operations: Thread-safe with all methods returning new instances
Business Operations
  • Holiday Support: 34 countries with comprehensive regional data (via goholiday)
  • Business Day Calculations: Working day arithmetic with automatic holiday awareness
  • Enhanced Calculator: High-performance operations with custom weekend support
  • Holiday-Aware Scheduler: Intelligent scheduling that respects holidays and business days
  • Calendar Integration: Holiday calendars with formatted output and tracking
Localization
  • 7 Locales for Formatting: en-US, es-ES, fr-FR, de-DE, zh-Hans, pt-BR, ja-JP
  • Localized Date Formatting: Format dates and times in multiple languages
  • Human-Readable Differences: "2 hours ago", "hace 2 horas", "il y a 2 heures", "2時間前"
  • Ordinal Numbers: Language-specific ordinal formatting (1st, 2nd, 3rd, 日, etc.)
Advanced Features
  • Timezone Operations: Proper DST handling with optimized conversions
  • Period Type: Time intervals with powerful iteration capabilities
  • Comparison Methods: Closest, Farthest, Between, and boolean checks
  • Testing Helpers: Time mocking and freezing for deterministic tests
  • Serialization: Built-in JSON/Text marshalers and SQL driver integration
  • High Performance: Optimized operations with 90% test coverage

Installation

go get github.com/coredds/chronogo

Quick Start

package main

import (
    "fmt"
    "time"
    "github.com/coredds/chronogo"
)

func main() {
    // Natural language parsing in multiple languages
    dt1, _ := chronogo.Parse("tomorrow")
    dt2, _ := chronogo.Parse("next Monday")
    dt3, _ := chronogo.Parse("3 days ago")
    dt4, _ := chronogo.Parse("mañana")        // Spanish
    dt5, _ := chronogo.Parse("明天")           // Chinese
    
    // Technical format parsing
    dt6, _ := chronogo.Parse("2024-01-15T14:30:00Z")  // ISO 8601
    dt7, _ := chronogo.Parse("1705329000")             // Unix timestamp
    dt8, _ := chronogo.Parse("2023-359")               // Ordinal date
    dt9, _ := chronogo.Parse("2023-W52-1")             // Week date
    
    // Convenience methods
    meeting := chronogo.Now().On(2024, time.June, 15).At(14, 30, 0)
    
    // ISO 8601 long year detection
    if chronogo.Date(2020, time.January, 1).IsLongYear() {
        fmt.Println("2020 has 53 ISO weeks")
    }
    
    // Rich Diff type
    start := chronogo.Date(2023, time.January, 15)
    end := chronogo.Date(2024, time.March, 20)
    diff := end.Diff(start)
    
    fmt.Printf("%d years, %d months\n", diff.Years(), diff.Months())
    fmt.Printf("%.2f days\n", diff.InDays())
    fmt.Println(diff.ForHumans())  // "1 year from now"
    
    // Business date calculations
    calc := chronogo.NewEnhancedBusinessDayCalculator("US")
    workday := calc.AddBusinessDays(chronogo.Today(), 5)
    
    // Holiday checking
    usChecker := chronogo.NewGoHolidayChecker("US")
    if usChecker.IsHoliday(chronogo.Today()) {
        fmt.Println("Holiday:", usChecker.GetHolidayName(chronogo.Today()))
    }
    
    // Holiday-aware scheduling
    scheduler := chronogo.NewHolidayAwareScheduler("US")
    meetings := scheduler.ScheduleRecurring(chronogo.Now(), 24*time.Hour, 10)
    
    // Period iteration
    period := chronogo.NewPeriod(chronogo.Now(), chronogo.Now().AddDays(7))
    for _, day := range period.Days() {
        fmt.Println(day.Format("Monday, January 2"))
    }
}

Usage Examples

Natural Language Parsing
// Parse dates in multiple languages
dt1, _ := chronogo.Parse("tomorrow")
dt2, _ := chronogo.Parse("next Monday")
dt3, _ := chronogo.Parse("3 days ago")
dt4, _ := chronogo.Parse("mañana")        // Spanish
dt5, _ := chronogo.Parse("demain")        // French
dt6, _ := chronogo.Parse("明天")           // Chinese

// Configure languages
chronogo.SetDefaultParseLanguages("en", "es")

// Strict mode (technical formats only)
dt7, _ := chronogo.ParseStrict("2024-01-15T14:30:00Z")  // OK
dt8, _ := chronogo.ParseStrict("tomorrow")               // Error
Convenience Methods
// Quick date and time setting
dt := chronogo.Now()
  .On(2024, time.December, 25)
  .At(14, 30, 0)

// ISO 8601 long year detection
if dt.IsLongYear() {
    fmt.Println("This year has 53 ISO weeks")
}

// Boundary operations
start := dt.StartOfMonth()
end := dt.EndOfMonth()
firstMonday := dt.FirstWeekdayOf(time.Monday)
lastFriday := dt.LastWeekdayOf(time.Friday)
Diff Type
// Create difference between dates
start := chronogo.Date(2023, time.January, 15)
end := chronogo.Date(2025, time.March, 20)
diff := start.Diff(end)

// Calendar-aware differences
fmt.Printf("%d years, %d months\n", diff.Years(), diff.Months())

// Precise differences
fmt.Printf("%.2f years\n", diff.InYears())
fmt.Printf("%d total days\n", diff.InDays())

// Human-readable
fmt.Println(diff.ForHumans())      // "2 years from now"
fmt.Println(diff.CompactString())  // "2y 2m"

// Comparisons
if diff.IsPositive() {
    fmt.Println("Future date")
}
Business Date Operations
// Business day calculations
today := chronogo.Today()
deadline := today.AddBusinessDays(5)

// Holiday checking
if today.IsHoliday() {
    fmt.Println("It's a holiday!")
}

// Enhanced calculator with custom weekends
calc := chronogo.NewEnhancedBusinessDayCalculator("US")
calc.SetCustomWeekends([]time.Weekday{time.Friday, time.Saturday})

nextBiz := calc.NextBusinessDay(today)
bizDays := calc.BusinessDaysBetween(today, today.AddDays(30))

// Multi-country support (34 countries)
usChecker := chronogo.NewGoHolidayChecker("US")
ukChecker := chronogo.NewGoHolidayChecker("GB")
jpChecker := chronogo.NewGoHolidayChecker("JP")
Holiday-Aware Scheduler
// Create scheduler
scheduler := chronogo.NewHolidayAwareScheduler("US")

// Schedule recurring meetings (avoids holidays)
start := chronogo.Date(2025, time.September, 1)
meetings := scheduler.ScheduleRecurring(start, 7*24*time.Hour, 8)

// Monthly end-of-month reports
reports := scheduler.ScheduleMonthlyEndOfMonth(start, 6)

// Business days only
bizMeetings := scheduler.ScheduleBusinessDays(start, 10)
Localization
dt := chronogo.Date(2024, time.January, 15, 14, 30, 0, 0, time.UTC)

// Localized formatting (7 locales supported)
result, _ := dt.FormatLocalized("dddd, MMMM Do YYYY", "en-US")
// "Monday, January 15th 2024"

result, _ = dt.FormatLocalized("dddd, Do de MMMM de YYYY", "es-ES")
// "lunes, 15º de enero de 2024"

result, _ = dt.FormatLocalized("YYYY年MMMM Do dddd", "ja-JP")
// "2024年1月 15日 月曜日"

// Human-readable differences
past := chronogo.Now().AddHours(-2)
result, _ = past.HumanStringLocalized("en-US")  // "2 hours ago"
result, _ = past.HumanStringLocalized("es-ES")  // "hace 2 horas"
result, _ = past.HumanStringLocalized("fr-FR")  // "il y a 2 heures"
result, _ = past.HumanStringLocalized("ja-JP")  // "2時間前"

// Default locale
chronogo.SetDefaultLocale("ja-JP")
result = dt.FormatLocalizedDefault("YYYY年MMMM Do")
Timezone Operations
// Create and convert timezones
meeting := chronogo.Parse("2025-01-15 14:00")
  .InTimezone("America/New_York")

tokyo := meeting.InTimezone("Asia/Tokyo")
london := meeting.InTimezone("Europe/London")

// DST-aware conversions
fmt.Println("NYC:", meeting.Format("15:04"))
fmt.Println("Tokyo:", tokyo.Format("15:04"))
fmt.Println("London:", london.Format("15:04"))
Period Operations
// Create period
start := chronogo.Date(2025, time.January, 1)
end := chronogo.Date(2025, time.January, 31)
period := chronogo.NewPeriod(start, end)

// Iterate by day
for _, dt := range period.Days() {
    fmt.Println(dt.Format("Jan 2"))
}

// Custom intervals
for _, dt := range period.RangeByUnitSlice(chronogo.Hour, 6) {
    fmt.Println(dt.Format("Jan 2 15:04"))
}

// Check containment
inRange := period.Contains(chronogo.Date(2025, time.January, 15))
Testing Helpers
// Mock current time
chronogo.SetTestNow(chronogo.Date(2024, time.January, 1))
defer chronogo.ClearTestNow()

// Freeze time
chronogo.FreezeTime(chronogo.Date(2024, time.January, 1))
defer chronogo.UnfreezeTime()

// Time travel
chronogo.TravelTo(chronogo.Date(2024, time.June, 1))
defer chronogo.TravelBack()

// Scoped mocking with auto-cleanup
chronogo.WithTestNow(chronogo.Date(2024, time.January, 1), func() {
    // Test code here
})

Supported Countries

Business date operations support 34 countries via goholiday integration:

US, GB, CA, AU, NZ, DE, FR, JP, IN, BR, MX, IT, ES, NL, KR, PT, PL, RU, CN, TH, SG, TR, UA, AT, BE, CH, CL, FI, IE, IL, NO, SE, AR, ID

Dependencies

  • godateparser: Natural language date parsing in 7 languages
  • goholiday: Holiday data for 34 countries with regional subdivisions

Documentation

Full API documentation: pkg.go.dev/github.com/coredds/chronogo

Testing

go test -cover ./...

Current coverage: 90% with comprehensive edge case handling

Security

Automated security scanning with GitHub Actions:

  • CodeQL static analysis
  • Go vulnerability database checks (govulncheck)
  • Dependency vulnerability scanning
  • License compliance checking

Security tools: gosec, Semgrep, Snyk, OSSF Scorecard

Run local security checks:

# Unix/Linux/macOS
make security
./scripts/security-check.sh

# Windows PowerShell
.\scripts\security-check.ps1

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure tests pass and linting is clean
  5. Submit a pull request

License

MIT License - see LICENSE file

Changelog

See CHANGELOG.md for detailed release notes.

Documentation

Overview

Package chronogo provides a Go implementation of powerful datetime handling for easy-to-use datetime and timezone operations.

Example

Example demonstrates basic usage of chronogo similar to the PRD sample.

package main

import (
	"fmt"
	"time"

	chronogo "github.com/coredds/chronogo"
)

func main() {
	// Load timezone
	loc, _ := chronogo.LoadLocation("America/New_York")

	// Get current time
	now := chronogo.Now()
	fmt.Println("Current time:", now.ToDateTimeString())

	// Create custom datetime
	dt := chronogo.Date(2025, time.July, 30, 11, 0, 0, 0, loc)
	fmt.Println("Custom datetime:", dt.String())

	// Add time
	dt2 := dt.AddDays(5).AddHours(3)
	fmt.Println("After 5 days 3 hours:", dt2.String())

	// Convert to UTC
	fmt.Println("In UTC:", dt2.UTC().String())

	// Check if DST is in effect
	if dt2.IsDST() {
		fmt.Println("DST is in effect")
	}

	// Get duration difference
	diff := dt2.Sub(now)
	fmt.Println("Duration from now:", diff)

	// Human-friendly difference
	fmt.Println("Diff for humans:", dt2.DiffForHumans(now))

	// Custom formatting
	fmt.Println("Formatted:", dt2.Format("2006-01-02 15:04:05 MST"))
}
Example (Arithmetic)

Example_arithmetic demonstrates date/time arithmetic.

package main

import (
	"fmt"
	"time"

	chronogo "github.com/coredds/chronogo"
)

func main() {
	dt := chronogo.Date(2023, time.January, 15, 12, 30, 45, 0, time.UTC)
	fmt.Println("Original:", dt.String())

	// Add various units
	fmt.Println("Add 1 year:", dt.AddYears(1).String())
	fmt.Println("Add 3 months:", dt.AddMonths(3).String())
	fmt.Println("Add 10 days:", dt.AddDays(10).String())
	fmt.Println("Add 5 hours:", dt.AddHours(5).String())

	// Subtract units
	fmt.Println("Subtract 2 weeks:", dt.AddDays(-14).String())

	// Method chaining
	future := dt.AddYears(1).AddMonths(6).AddDays(15)
	fmt.Println("Chained operations:", future.String())

	// Set specific components
	newYear := dt.SetYear(2025)
	fmt.Println("Set year to 2025:", newYear.String())

	newTime := dt.SetHour(18).SetMinute(0).SetSecond(0)
	fmt.Println("Set time to 18:00:00:", newTime.String())
}
Example (Comparison)

Example_comparison demonstrates date/time comparisons.

package main

import (
	"fmt"
	"time"

	chronogo "github.com/coredds/chronogo"
)

func main() {
	dt1 := chronogo.Date(2023, time.January, 15, 12, 0, 0, 0, time.UTC)
	dt2 := chronogo.Date(2023, time.January, 16, 12, 0, 0, 0, time.UTC)
	dt3 := chronogo.Date(2023, time.January, 15, 12, 0, 0, 0, time.UTC)

	fmt.Println("dt1:", dt1.ToDateString())
	fmt.Println("dt2:", dt2.ToDateString())
	fmt.Println("dt3:", dt3.ToDateString())

	fmt.Println("dt1.Before(dt2):", dt1.Before(dt2))
	fmt.Println("dt1.After(dt2):", dt1.After(dt2))
	fmt.Println("dt1.Equal(dt3):", dt1.Equal(dt3))

	// Convenience methods
	now := chronogo.Now()
	past := now.AddDays(-1)
	future := now.AddDays(1)

	fmt.Println("Past is past:", past.IsPast())
	fmt.Println("Future is future:", future.IsFuture())

	// Leap year check
	fmt.Println("2024 is leap year:", chronogo.Date(2024, time.January, 1, 0, 0, 0, 0, time.UTC).IsLeapYear())
	fmt.Println("2023 is leap year:", chronogo.Date(2023, time.January, 1, 0, 0, 0, 0, time.UTC).IsLeapYear())
}
Example (Formatting)

Example_formatting demonstrates various formatting options.

package main

import (
	"fmt"
	"time"

	chronogo "github.com/coredds/chronogo"
)

func main() {
	dt := chronogo.Date(2023, time.December, 25, 15, 30, 45, 0, time.UTC)

	// Built-in formats
	fmt.Println("Date string:", dt.ToDateString())
	fmt.Println("Time string:", dt.ToTimeString())
	fmt.Println("DateTime string:", dt.ToDateTimeString())
	fmt.Println("ISO 8601:", dt.ToISO8601String())

	// Custom formats using Go's layout
	fmt.Println("Custom format 1:", dt.Format("Monday, January 2, 2006"))
	fmt.Println("Custom format 2:", dt.Format("02/01/2006 15:04"))
	fmt.Println("Custom format 3:", dt.Format("Jan 2, 2006 at 3:04 PM"))

	// Human-friendly formats
	fmt.Println("Age:", dt.Age())
	fmt.Println("Time ago:", dt.DiffForHumans())
}
Example (HumanReadable)

Example_humanReadable demonstrates human-friendly time representations.

package main

import (
	"fmt"
	"time"

	chronogo "github.com/coredds/chronogo"
)

func main() {
	now := chronogo.Now()

	// Various time differences
	times := []chronogo.DateTime{
		now.AddSeconds(-30),
		now.AddMinutes(-5),
		now.AddHours(-2),
		now.AddDays(-1),
		now.AddDays(-7),
		now.AddDays(-30),
		now.AddYears(-1),
		now.AddSeconds(30),
		now.AddMinutes(5),
		now.AddHours(2),
		now.AddDays(1),
		now.AddDays(7),
		now.AddDays(30),
		now.AddYears(1),
	}

	fmt.Println("Human-readable time differences:")
	for _, t := range times {
		fmt.Printf("  %s\n", t.DiffForHumans(now))
	}

	// Duration humanization
	durations := []time.Duration{
		30 * time.Second,
		5 * time.Minute,
		2 * time.Hour,
		25 * time.Hour,
		7 * 24 * time.Hour,
	}

	fmt.Println("\nHumanized durations:")
	for _, d := range durations {
		fmt.Printf("  %v = %s\n", d, chronogo.Humanize(d))
	}
}
Example (Parsing)

Example_parsing demonstrates various parsing capabilities.

package main

import (
	"fmt"

	chronogo "github.com/coredds/chronogo"
)

func main() {
	// Parse ISO 8601
	dt1, _ := chronogo.ParseISO8601("2023-12-25T15:30:45Z")
	fmt.Println("Parsed ISO 8601:", dt1.String())

	// Parse common formats
	dt2, _ := chronogo.Parse("2023-12-25 15:30:45")
	fmt.Println("Parsed datetime:", dt2.String())

	// Parse with custom format
	dt3, _ := chronogo.FromFormat("25/12/2023 15:30", "02/01/2006 15:04")
	fmt.Println("Parsed custom format:", dt3.String())

	// Parse Unix timestamp
	dt4, _ := chronogo.TryParseUnix("1703516445")
	fmt.Println("From Unix timestamp:", dt4.String())
}
Example (Period)

Example_period demonstrates Period usage for time intervals.

package main

import (
	"fmt"
	"time"

	chronogo "github.com/coredds/chronogo"
)

func main() {
	start := chronogo.Date(2023, time.January, 1, 0, 0, 0, 0, time.UTC)
	end := chronogo.Date(2023, time.January, 10, 0, 0, 0, 0, time.UTC)

	period := chronogo.NewPeriod(start, end)
	fmt.Println("Period duration:", period.String())
	fmt.Println("Days in period:", period.Days())
	fmt.Println("Hours in period:", period.Hours())

	// Check if a date is in the period
	middle := chronogo.Date(2023, time.January, 5, 0, 0, 0, 0, time.UTC)
	fmt.Println("Contains middle date:", period.Contains(middle))

	// Iterate over period
	fmt.Println("Dates in period (every 2 days):")
	count := 0
	for dt := range period.Range("days", 2) {
		if count < 3 { // Limit output for example
			fmt.Printf("  %s\n", dt.ToDateString())
		}
		count++
	}
}
Example (Timezones)

Example_timezones demonstrates timezone handling.

package main

import (
	"fmt"
	"time"

	chronogo "github.com/coredds/chronogo"
)

func main() {
	// Create datetime in different timezones
	utc := chronogo.UTC(2023, time.December, 25, 12, 0, 0, 0)
	fmt.Println("UTC time:", utc.String())

	// Convert to different timezones
	if ny, err := chronogo.LoadLocation("America/New_York"); err == nil {
		nyTime := utc.In(ny)
		fmt.Println("New York time:", nyTime.String())
		fmt.Println("Is DST in NY:", nyTime.IsDST())
	}

	if tokyo, err := chronogo.LoadLocation("Asia/Tokyo"); err == nil {
		tokyoTime := utc.In(tokyo)
		fmt.Println("Tokyo time:", tokyoTime.String())
	}

	if london, err := chronogo.LoadLocation("Europe/London"); err == nil {
		londonTime := utc.In(london)
		fmt.Println("London time:", londonTime.String())
	}
}

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrInvalidFormat    = errors.New("invalid datetime format")
	ErrInvalidTimezone  = errors.New("invalid timezone")
	ErrInvalidDuration  = errors.New("invalid duration")
	ErrInvalidRange     = errors.New("invalid range")
	ErrInvalidOperation = errors.New("invalid operation")
)

Common error variables for easier error checking

View Source
var (

	// Common parsing errors
	ErrEmptyString      = errors.New("empty string")
	ErrNoMatchingFormat = errors.New("no matching format found")
)
View Source
var DefaultParseConfig = ParseConfig{
	Languages:    []string{"en", "es", "pt", "fr", "de", "zh", "ja"},
	Location:     time.UTC,
	PreferFuture: false,
}

DefaultParseConfig provides sensible defaults: all languages enabled, UTC location

Functions

func AvailableTimezones

func AvailableTimezones() []string

AvailableTimezones returns a list of commonly used timezone names. This is helpful for error suggestions and validation.

func ClearDSTCache

func ClearDSTCache()

ClearDSTCache clears the DST cache (useful for testing or memory management)

func ClearTestNow

func ClearTestNow()

ClearTestNow clears any test time and restores normal time behavior.

func FreezeTime

func FreezeTime()

FreezeTime freezes time at the current moment for testing. All calls to Now() will return the same frozen time until UnfreezeTime() is called.

Example:

chronogo.FreezeTime()
defer chronogo.UnfreezeTime()

now1 := chronogo.Now()
time.Sleep(100 * time.Millisecond)
now2 := chronogo.Now() // Same as now1, time is frozen

func FreezeTimeAt

func FreezeTimeAt(dt DateTime)

FreezeTimeAt freezes time at a specific DateTime for testing.

Example:

chronogo.FreezeTimeAt(chronogo.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC))
defer chronogo.UnfreezeTime()

func GetAvailableLocales

func GetAvailableLocales() []string

GetAvailableLocales returns all registered locale codes

func GetDefaultLocale

func GetDefaultLocale() string

GetDefaultLocale returns the current default locale code

func GetDefaultParseLanguages

func GetDefaultParseLanguages() []string

GetDefaultParseLanguages returns the current default languages for parsing

func Humanize

func Humanize(duration time.Duration) string

Humanize returns a human-readable representation of a duration. Uses the default locale for time unit names.

Note: This provides a simple duration representation. For relative time differences (e.g., "2 hours ago"), use DiffForHumans() instead.

func IsFrozen

func IsFrozen() bool

IsFrozen returns true if time is currently frozen.

func IsTestMode

func IsTestMode() bool

IsTestMode returns true if time is currently being mocked for testing.

func IsValidTimezone

func IsValidTimezone(name string) bool

IsValidTimezone checks if a timezone name is valid.

func LoadLocation

func LoadLocation(name string) (*time.Location, error)

LoadLocation loads a timezone by name. This is a convenience wrapper around time.LoadLocation.

func MustLoadLocation

func MustLoadLocation(name string) *time.Location

MustLoadLocation is like LoadLocation but panics on error.

func RegisterLocale

func RegisterLocale(locale *Locale)

RegisterLocale registers a new locale in the global registry

func SetDefaultLocale

func SetDefaultLocale(code string) error

SetDefaultLocale sets the default locale for operations

func SetDefaultParseLanguages

func SetDefaultParseLanguages(languages ...string)

SetDefaultParseLanguages sets the default languages for Parse() and ParseInLocation(). This is a convenience function for applications that primarily use specific languages. Default is all supported languages: en, es, pt, fr, de, zh, ja

func SetTestNow

func SetTestNow(dt DateTime)

SetTestNow sets a fixed time to be returned by Now() for testing purposes. This is useful for writing deterministic tests that depend on the current time. Call ClearTestNow() to restore normal behavior.

Example:

chronogo.SetTestNow(chronogo.Date(2024, 1, 15, 12, 0, 0, 0, time.UTC))
defer chronogo.ClearTestNow()

now := chronogo.Now() // Returns 2024-01-15 12:00:00 UTC

func TravelBack

func TravelBack(d time.Duration)

TravelBack moves the test time backwards by the specified duration.

Example:

chronogo.TravelBack(24 * time.Hour) // Go back 1 day
defer chronogo.ClearTestNow()

func TravelForward

func TravelForward(d time.Duration)

TravelForward moves the test time forward by the specified duration.

Example:

chronogo.TravelForward(7 * 24 * time.Hour) // Go forward 1 week
defer chronogo.ClearTestNow()

func TravelTo

func TravelTo(dt DateTime)

TravelTo moves the test time to a specific DateTime. This is useful for testing time-dependent behavior at different points in time. Unlike FreezeTime, subsequent calls to Now() will still advance normally from this point.

Example:

chronogo.TravelTo(chronogo.Date(2024, 12, 25, 0, 0, 0, 0, time.UTC))
defer chronogo.ClearTestNow()

now := chronogo.Now() // Returns 2024-12-25 00:00:00 UTC
time.Sleep(1 * time.Second)
later := chronogo.Now() // Returns 2024-12-25 00:00:01 UTC (time advances)

func UnfreezeTime

func UnfreezeTime()

UnfreezeTime unfreezes time and restores normal time behavior.

func ValidateCountryCode

func ValidateCountryCode(countryCode string) error

ValidateCountryCode validates if a country code is supported. New in goholiday v0.6.3+ - provides validation before creating checkers.

func ValidateRange

func ValidateRange(start, end DateTime) error

ValidateRange checks if a date range is valid.

func WithFrozenTime

func WithFrozenTime(fn func())

WithFrozenTime executes a function with frozen time and automatically cleans up.

Example:

chronogo.WithFrozenTime(func() {
    now1 := chronogo.Now()
    time.Sleep(100 * time.Millisecond)
    now2 := chronogo.Now() // Same as now1
})

func WithFrozenTimeAt

func WithFrozenTimeAt(dt DateTime, fn func())

WithFrozenTimeAt executes a function with time frozen at a specific DateTime.

Example:

chronogo.WithFrozenTimeAt(chronogo.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC), func() {
    // Time is frozen at 2024-01-01 00:00:00 UTC
})

func WithTestNow

func WithTestNow(dt DateTime, fn func())

WithTestNow executes a function with a specific test time and automatically cleans up. This is useful for scoped time mocking in tests.

Example:

chronogo.WithTestNow(chronogo.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC), func() {
    now := chronogo.Now() // Returns 2024-01-01 00:00:00 UTC
    // ... test code ...
})
// Test time automatically cleared after function returns

Types

type CalendarEntry

type CalendarEntry struct {
	Date        DateTime
	IsWeekend   bool
	IsHoliday   bool
	HolidayName string
	IsToday     bool
}

CalendarEntry represents a day in a calendar with holiday information

func (CalendarEntry) String

func (ce CalendarEntry) String() string

FormatCalendarEntry formats a calendar entry for display

type ChronoDuration

type ChronoDuration struct {
	time.Duration
}

ChronoDuration extends Go's time.Duration with human-readable formatting and additional operations.

func NewDuration

func NewDuration(d time.Duration) ChronoDuration

NewDuration creates a new ChronoDuration from a time.Duration.

func NewDurationFromComponents

func NewDurationFromComponents(hours, minutes, seconds int) ChronoDuration

NewDurationFromComponents creates a ChronoDuration from individual components.

func ParseISODuration

func ParseISODuration(s string) (ChronoDuration, error)

ParseISODuration parses an ISO 8601 duration string (e.g., "P1Y2M3DT4H5M6S", "PT15M", "P2W").

Notes:

  • Years and months are approximated using the same factors as ChronoDuration methods: 1 year = 365.25 days, 1 month = 30.44 days.
  • Weeks are converted as 7 days.
  • A leading minus sign is supported for negative durations.

func (ChronoDuration) Abs

func (cd ChronoDuration) Abs() ChronoDuration

Abs returns the absolute value of the duration.

func (ChronoDuration) Add

Add adds another duration to this one.

func (ChronoDuration) Days

func (cd ChronoDuration) Days() float64

Days returns the number of days in the duration.

func (ChronoDuration) Divide

func (cd ChronoDuration) Divide(factor float64) ChronoDuration

Divide divides the duration by a factor.

func (ChronoDuration) HumanString

func (cd ChronoDuration) HumanString() string

HumanString returns a human-readable representation of the duration.

func (ChronoDuration) IsNegative

func (cd ChronoDuration) IsNegative() bool

IsNegative returns true if the duration is negative.

func (ChronoDuration) IsPositive

func (cd ChronoDuration) IsPositive() bool

IsPositive returns true if the duration is positive.

func (ChronoDuration) IsZero

func (cd ChronoDuration) IsZero() bool

IsZero returns true if the duration is zero.

func (ChronoDuration) Months

func (cd ChronoDuration) Months() float64

Months returns the approximate number of months in the duration.

func (ChronoDuration) Multiply

func (cd ChronoDuration) Multiply(factor float64) ChronoDuration

Multiply multiplies the duration by a factor.

func (ChronoDuration) String

func (cd ChronoDuration) String() string

String returns a string representation of the duration.

func (ChronoDuration) Subtract

func (cd ChronoDuration) Subtract(other ChronoDuration) ChronoDuration

Subtract subtracts another duration from this one.

func (ChronoDuration) Weeks

func (cd ChronoDuration) Weeks() float64

Weeks returns the number of weeks in the duration.

func (ChronoDuration) Years

func (cd ChronoDuration) Years() float64

Years returns the approximate number of years in the duration.

type ChronoError

type ChronoError struct {
	Op         string // Operation that caused the error
	Path       string // Path or context where error occurred
	Err        error  // Underlying error
	Input      string // Input that caused the error (for parsing errors)
	Suggestion string // Helpful suggestion for fixing the error
}

ChronoError represents errors that occur in chronogo operations.

func FormatError

func FormatError(format string, err error) *ChronoError

FormatError creates a ChronoError for formatting operations.

func ParseError

func ParseError(input string, err error) *ChronoError

ParseError creates a ChronoError for parsing operations.

func RangeError

func RangeError(start, end DateTime, err error) *ChronoError

RangeError creates a ChronoError for range operations.

func TimezoneError

func TimezoneError(timezone string, err error) *ChronoError

TimezoneError creates a ChronoError for timezone operations.

func (*ChronoError) Error

func (e *ChronoError) Error() string

Error implements the error interface.

func (*ChronoError) Is

func (e *ChronoError) Is(target error) bool

Is implements error comparison for errors.Is().

func (*ChronoError) Unwrap

func (e *ChronoError) Unwrap() error

Unwrap returns the underlying error for error wrapping support.

type DateTime

type DateTime struct {
	time.Time
}

DateTime wraps Go's time.Time to extend functionality while maintaining compatibility. It provides timezone-aware datetime operations with a fluent API.

func Date

func Date(year int, month time.Month, day, hour, min, sec, nsec int, loc *time.Location) DateTime

Date creates a DateTime similar to time.Date() but returns our DateTime type.

func FromFormat

func FromFormat(value, layout string) (DateTime, error)

FromFormat parses a datetime string using a custom format layout. This is similar to strptime but uses Go's time format syntax.

func FromFormatInLocation

func FromFormatInLocation(value, layout string, loc *time.Location) (DateTime, error)

FromFormatInLocation parses a datetime string using a custom format layout in the specified location.

func FromFormatTokens

func FromFormatTokens(value, format string) (DateTime, error)

FromFormatTokens parses a datetime string using chronogo-style format tokens. Converts token-based format to Go time format and then parses.

func FromFormatTokensInLocation

func FromFormatTokensInLocation(value, format string, loc *time.Location) (DateTime, error)

FromFormatTokensInLocation parses using token-style format in the specified location.

func FromUnix

func FromUnix(sec int64, nsec int64, loc *time.Location) DateTime

FromUnix creates a DateTime from Unix timestamp.

func FromUnixMicro

func FromUnixMicro(us int64, loc *time.Location) DateTime

FromUnixMicro creates a DateTime from a Unix timestamp in microseconds in the specified location.

func FromUnixMilli

func FromUnixMilli(ms int64, loc *time.Location) DateTime

FromUnixMilli creates a DateTime from a Unix timestamp in milliseconds in the specified location.

func FromUnixNano

func FromUnixNano(ns int64, loc *time.Location) DateTime

FromUnixNano creates a DateTime from a Unix timestamp in nanoseconds in the specified location.

func GetTestNow

func GetTestNow() *DateTime

GetTestNow returns the current test time if set, otherwise nil.

func Instance

func Instance(t time.Time) DateTime

Instance creates a DateTime from a standard time.Time.

func MustFromFormat

func MustFromFormat(input, layout string) DateTime

MustFromFormat is like FromFormat but panics on error.

func MustParse

func MustParse(input string) DateTime

MustParse is like Parse but panics on error. Useful for constants.

func MustParseInLocation

func MustParseInLocation(input string, loc *time.Location) DateTime

MustParseInLocation is like ParseInLocation but panics on error.

func Now

func Now() DateTime

Now returns the current datetime in the local timezone. When testing helpers are active (SetTestNow, FreezeTime, TravelTo), this will return the mocked time instead of the actual current time.

func NowIn

func NowIn(loc *time.Location) DateTime

NowIn returns the current datetime in the specified timezone. When testing helpers are active, this will return the mocked time in the specified timezone.

func NowUTC

func NowUTC() DateTime

NowUTC returns the current datetime in UTC timezone. When testing helpers are active, this will return the mocked time in UTC.

func Parse

func Parse(value string, options ...ParseOptions) (DateTime, error)

Parse is an intelligent datetime parser that handles: - Technical formats (ISO 8601, RFC 3339, Unix timestamps) via fast path - Natural language expressions ("tomorrow", "next Monday", "3 days ago") - Common datetime formats with lenient parsing - Multi-language support (English, Spanish, Portuguese, French, German, Chinese, Japanese)

The parser automatically tries technical formats first for performance, then falls back to natural language parsing via godateparser for maximum flexibility.

Examples:

Parse("2024-01-15T14:30:00Z")     // ISO 8601
Parse("tomorrow")                  // Natural language
Parse("next Monday")               // Relative date
Parse("3 days ago")                // Relative with quantity
Parse("demain")                    // French for "tomorrow"
Parse("明天")                       // Chinese for "tomorrow"

func ParseISO8601

func ParseISO8601(value string) (DateTime, error)

ParseISO8601 parses an ISO 8601 formatted datetime string.

func ParseInLocation

func ParseInLocation(value string, loc *time.Location, options ...ParseOptions) (DateTime, error)

ParseInLocation parses a datetime string in the specified location. Supports the same formats as Parse() but uses the provided location for timezone-naive inputs and relative date calculations.

func ParseRFC3339

func ParseRFC3339(value string) (DateTime, error)

ParseRFC3339 parses an RFC 3339 formatted datetime string.

func ParseStrict

func ParseStrict(value string) (DateTime, error)

ParseStrict parses using only technical formats (RFC3339, ISO8601, Unix timestamps). No natural language parsing is attempted.

func ParseStrictInLocation

func ParseStrictInLocation(value string, loc *time.Location) (DateTime, error)

ParseStrictInLocation is the location-aware strict parser. Only technical formats are accepted (RFC3339, ISO8601, Unix timestamps).

func ParseWith

func ParseWith(value string, config ParseConfig) (DateTime, error)

ParseWith parses a datetime string using the provided configuration. This is the most flexible parsing function, allowing fine control over natural language parsing, languages, and location.

func Today

func Today() DateTime

Today returns today's date at midnight in the local timezone.

func TodayIn

func TodayIn(loc *time.Location) DateTime

TodayIn returns today's date at midnight in the specified timezone.

func Tomorrow

func Tomorrow() DateTime

Tomorrow returns tomorrow's date at midnight in the local timezone.

func TryParseUnix

func TryParseUnix(value string) (DateTime, error)

TryParseUnix attempts to parse a string as a Unix timestamp.

func UTC

func UTC(year int, month time.Month, day, hour, min, sec, nsec int) DateTime

UTC creates a DateTime in UTC timezone.

func Yesterday

func Yesterday() DateTime

Yesterday returns yesterday's date at midnight in the local timezone.

func (DateTime) Add

func (dt DateTime) Add(duration time.Duration) DateTime

Add adds a time.Duration to the datetime.

func (DateTime) AddBusinessDays

func (dt DateTime) AddBusinessDays(days int, holidayChecker ...HolidayChecker) DateTime

AddBusinessDays adds the specified number of business days.

func (DateTime) AddDays

func (dt DateTime) AddDays(days int) DateTime

AddDays adds the specified number of days.

func (DateTime) AddFluent

func (dt DateTime) AddFluent() *FluentDuration

AddFluent returns a FluentDuration for adding time units to the DateTime.

func (DateTime) AddHours

func (dt DateTime) AddHours(hours int) DateTime

AddHours adds the specified number of hours.

func (DateTime) AddMinutes

func (dt DateTime) AddMinutes(minutes int) DateTime

AddMinutes adds the specified number of minutes.

func (DateTime) AddMonths

func (dt DateTime) AddMonths(months int) DateTime

AddMonths adds the specified number of months.

func (DateTime) AddSeconds

func (dt DateTime) AddSeconds(seconds int) DateTime

AddSeconds adds the specified number of seconds.

func (DateTime) AddYears

func (dt DateTime) AddYears(years int) DateTime

AddYears adds the specified number of years.

func (DateTime) After

func (dt DateTime) After(other DateTime) bool

After reports whether the datetime is after other.

func (DateTime) Age

func (dt DateTime) Age() string

Age returns the age of the DateTime compared to now. Uses the default locale for output.

Note: This is a simplified age calculation. For more precise age calculations with years, months, and days, use Diff().

func (DateTime) At

func (dt DateTime) At(hour, minute, second int) DateTime

At is a convenience method that sets the time components (hour, minute, second) in one call. This is a simpler alternative to using Set().Hour().Minute().Second() for time modifications. The date components (year, month, day) and nanoseconds remain unchanged.

Examples:

dt := chronogo.Today()
dt2 := dt.At(14, 30, 0)    // Sets time to 14:30:00, keeps current date
dt3 := dt.At(9, 0, 0)      // Sets time to 09:00:00, keeps current date
dt4 := dt.At(23, 59, 59)   // Sets time to 23:59:59, keeps current date

func (DateTime) Average

func (dt DateTime) Average(other DateTime) DateTime

Average returns the DateTime that is exactly halfway between this DateTime and another. This is useful for finding the midpoint between two dates.

Example:

start := chronogo.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
end := chronogo.Date(2024, 1, 31, 0, 0, 0, 0, time.UTC)
midpoint := start.Average(end) // Returns 2024-01-16

func (DateTime) Before

func (dt DateTime) Before(other DateTime) bool

Before reports whether the datetime is before other.

func (DateTime) Between

func (dt DateTime) Between(a, b DateTime, inclusive bool) bool

Between reports whether dt is within the range (a, b) or [a, b] depending on inclusive. The order of a and b does not matter.

func (DateTime) BusinessDaysBetween

func (dt DateTime) BusinessDaysBetween(other DateTime, holidayChecker ...HolidayChecker) int

BusinessDaysBetween returns the number of business days between two dates.

func (DateTime) BusinessDaysInMonth

func (dt DateTime) BusinessDaysInMonth(holidayChecker ...HolidayChecker) int

BusinessDaysInMonth returns the number of business days in the month.

func (DateTime) BusinessDaysInYear

func (dt DateTime) BusinessDaysInYear(holidayChecker ...HolidayChecker) int

BusinessDaysInYear returns the number of business days in the year.

func (DateTime) Clamp

func (dt DateTime) Clamp(a, b DateTime) DateTime

Clamp returns dt clamped to the [min, max] range (order-agnostic).

func (DateTime) Closest

func (dt DateTime) Closest(dates ...DateTime) DateTime

Closest returns the closest DateTime from a list of DateTimes. Returns zero DateTime if the list is empty.

Example:

dt := chronogo.Now()
dates := []chronogo.DateTime{
    chronogo.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC),
    chronogo.Date(2024, 6, 15, 0, 0, 0, 0, time.UTC),
    chronogo.Date(2024, 12, 31, 0, 0, 0, 0, time.UTC),
}
closest := dt.Closest(dates...)

func (DateTime) ClosestWeekday

func (dt DateTime) ClosestWeekday(weekday time.Weekday) DateTime

ClosestWeekday returns the closest occurrence of the specified weekday. If the current day is the specified weekday, it returns the current DateTime. If two occurrences are equidistant, it returns the future one.

Example:

dt := chronogo.Date(2024, 1, 15, 12, 0, 0, 0, time.UTC) // Monday
closest := dt.ClosestWeekday(time.Wednesday) // Returns nearest Wednesday

func (DateTime) DayOfYear

func (dt DateTime) DayOfYear() int

DayOfYear returns the day of the year (1-366).

func (DateTime) DaysInMonth

func (dt DateTime) DaysInMonth() int

DaysInMonth returns the number of days in the datetime's month.

func (DateTime) DaysInYear

func (dt DateTime) DaysInYear() int

DaysInYear returns the number of days in the datetime's year (365 or 366 for leap years).

func (DateTime) Diff

func (dt DateTime) Diff(other DateTime) Diff

Diff returns a Diff object representing the difference between two DateTimes. The returned Diff provides both precise duration-based and calendar-aware period-based methods.

Examples:

dt1 := chronogo.Date(2023, 1, 15, 10, 0, 0, 0, time.UTC)
dt2 := chronogo.Date(2024, 3, 20, 14, 30, 0, 0, time.UTC)
diff := dt2.Diff(dt1)

// Precise differences
fmt.Println(diff.InHours())  // Total hours as float
fmt.Println(diff.InDays())   // Total days as float

// Calendar-aware differences
fmt.Println(diff.Years())    // Full years
fmt.Println(diff.Months())   // Total full months

// Human-readable
fmt.Println(diff.ForHumans())

func (DateTime) DiffAbs

func (dt DateTime) DiffAbs(other DateTime) Diff

DiffAbs returns the absolute difference between two DateTimes. The returned Diff always represents a positive duration.

func (DateTime) DiffForHumans

func (dt DateTime) DiffForHumans(other ...DateTime) string

DiffForHumans returns a human-readable string describing the difference between this DateTime and another DateTime or the current time. Uses the default locale (set via SetDefaultLocale). Defaults to English.

Examples:

  • English: "2 hours ago", "in 3 days"
  • Spanish: "hace 2 horas", "en 3 días"
  • Japanese: "2時間前", "3日後"

func (DateTime) DiffForHumansComparison

func (dt DateTime) DiffForHumansComparison(other DateTime) string

DiffForHumansComparison returns a human-readable string describing the difference between this DateTime and another using "before/after" format for explicit comparisons. Uses the default locale.

Examples:

  • English: "2 hours before", "3 days after"
  • Spanish: "hace 2 horas", "en 3 días" (same as DiffForHumans in Spanish)
  • Japanese: "2時間前", "3日後" (same as DiffForHumans in Japanese)

func (DateTime) DiffForHumansNow

func (dt DateTime) DiffForHumansNow() string

DiffForHumansNow returns a human-readable string describing the difference between this DateTime and the current time. Uses the default locale.

func (DateTime) EndOfDay

func (dt DateTime) EndOfDay() DateTime

EndOfDay returns a new DateTime set to the end of the day (23:59:59.999999999).

func (DateTime) EndOfMonth

func (dt DateTime) EndOfMonth() DateTime

EndOfMonth returns a new DateTime set to the end of the month (last day at 23:59:59.999999999).

func (DateTime) EndOfQuarter

func (dt DateTime) EndOfQuarter() DateTime

EndOfQuarter returns a new DateTime set to the end of the quarter.

func (DateTime) EndOfWeek

func (dt DateTime) EndOfWeek() DateTime

EndOfWeek returns a new DateTime set to the end of the week (Sunday at 23:59:59.999999999).

func (DateTime) EndOfYear

func (dt DateTime) EndOfYear() DateTime

EndOfYear returns a new DateTime set to the end of the year (December 31st at 23:59:59.999999999).

func (DateTime) Equal

func (dt DateTime) Equal(other DateTime) bool

Equal reports whether the datetime is equal to other.

func (DateTime) Farthest

func (dt DateTime) Farthest(dates ...DateTime) DateTime

Farthest returns the farthest DateTime from a list of DateTimes. Returns zero DateTime if the list is empty.

Example:

dt := chronogo.Now()
dates := []chronogo.DateTime{
    chronogo.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC),
    chronogo.Date(2024, 6, 15, 0, 0, 0, 0, time.UTC),
    chronogo.Date(2024, 12, 31, 0, 0, 0, 0, time.UTC),
}
farthest := dt.Farthest(dates...)

func (DateTime) FarthestWeekday

func (dt DateTime) FarthestWeekday(weekday time.Weekday) DateTime

FarthestWeekday returns the farthest occurrence of the specified weekday within the week. This returns the occurrence that is furthest from the current day (3-4 days away).

Example:

dt := chronogo.Date(2024, 1, 15, 12, 0, 0, 0, time.UTC) // Monday
farthest := dt.FarthestWeekday(time.Thursday) // Returns the Thursday that's ~3-4 days away

func (DateTime) FirstWeekdayOf

func (dt DateTime) FirstWeekdayOf(weekday time.Weekday) DateTime

FirstWeekdayOf returns the first occurrence of the specified weekday in the current month.

Example:

dt := chronogo.Date(2024, 3, 15, 0, 0, 0, 0, time.UTC)
firstMonday := dt.FirstWeekdayOf(time.Monday) // First Monday of March 2024

func (DateTime) Format

func (dt DateTime) Format(layout string) string

Format formats the datetime using Go's time format layout.

func (DateTime) FormatLocalized

func (dt DateTime) FormatLocalized(pattern, localeCode string) (string, error)

FormatLocalized formats the datetime using locale-specific patterns

func (DateTime) FormatLocalizedDefault

func (dt DateTime) FormatLocalizedDefault(pattern string) string

FormatLocalizedDefault formats using the default locale

func (DateTime) GetHolidayCalendar

func (dt DateTime) GetHolidayCalendar(countryCode string) *HolidayCalendar

Convenience methods for DateTime

func (DateTime) GetHolidayName

func (dt DateTime) GetHolidayName(holidayChecker ...HolidayChecker) string

GetHolidayName returns the name of the holiday if the date is a holiday. Returns empty string if the date is not a holiday. If no holiday checker is provided, it uses the default US holiday checker.

func (DateTime) GetHolidaysInRange

func (dt DateTime) GetHolidaysInRange(end DateTime, holidayChecker ...HolidayChecker) map[DateTime]string

GetHolidaysInRange returns all holidays between this date and the end date. If no holiday checker is provided, it uses the default US holiday checker. New in goholiday v0.6.4+ - optimized for calendar operations.

func (DateTime) GetMonthName

func (dt DateTime) GetMonthName(localeCode string) (string, error)

GetMonthName returns the localized month name

func (DateTime) GetMonthNameDefault

func (dt DateTime) GetMonthNameDefault() string

GetMonthNameDefault returns the localized month name using default locale

func (DateTime) GetMonthlyHolidays

func (dt DateTime) GetMonthlyHolidays(countryCode string) []CalendarEntry

func (DateTime) GetUpcomingHolidays

func (dt DateTime) GetUpcomingHolidays(countryCode string, count int) []CalendarEntry

func (DateTime) GetWeekdayName

func (dt DateTime) GetWeekdayName(localeCode string) (string, error)

GetWeekdayName returns the localized weekday name

func (DateTime) GetWeekdayNameDefault

func (dt DateTime) GetWeekdayNameDefault() string

GetWeekdayNameDefault returns the localized weekday name using default locale

func (DateTime) HumanStringLocalized

func (dt DateTime) HumanStringLocalized(localeCode string, other ...DateTime) (string, error)

HumanStringLocalized returns a human-readable difference in the specified locale

func (DateTime) HumanStringLocalizedDefault

func (dt DateTime) HumanStringLocalizedDefault(other ...DateTime) string

HumanStringLocalizedDefault returns a human-readable difference using the default locale

func (DateTime) ISOWeek

func (dt DateTime) ISOWeek() (year, week int)

ISOWeek returns the ISO 8601 year and week number. Week 1 is the first week with at least 4 days in the new year.

func (DateTime) ISOWeekNumber

func (dt DateTime) ISOWeekNumber() int

ISOWeekNumber returns the ISO 8601 week number (1-53).

func (DateTime) ISOWeekYear

func (dt DateTime) ISOWeekYear() int

ISOWeekYear returns the ISO 8601 year for the week containing the datetime.

func (DateTime) In

func (dt DateTime) In(loc *time.Location) DateTime

In converts the datetime to the specified timezone.

func (DateTime) IsAnniversary

func (dt DateTime) IsAnniversary(other DateTime) bool

IsAnniversary checks if the given DateTime represents the same anniversary (month and day). This is an alias for IsBirthday and can be used for any recurring annual event.

Example:

anniversary := chronogo.Date(2010, 6, 20, 0, 0, 0, 0, time.UTC)
today := chronogo.Date(2024, 6, 20, 10, 0, 0, 0, time.UTC)
today.IsAnniversary(anniversary) // Returns true

func (DateTime) IsBirthday

func (dt DateTime) IsBirthday(other DateTime) bool

IsBirthday checks if the given DateTime represents the same birthday (month and day). This is useful for checking if a date is someone's birthday, regardless of the year.

Example:

birthday := chronogo.Date(1990, 5, 15, 0, 0, 0, 0, time.UTC)
today := chronogo.Date(2024, 5, 15, 12, 0, 0, 0, time.UTC)
today.IsBirthday(birthday) // Returns true

func (DateTime) IsBusinessDay

func (dt DateTime) IsBusinessDay(holidayChecker ...HolidayChecker) bool

IsBusinessDay returns true if the date is a business day (Monday-Friday and not a holiday). If no holiday checker is provided, it uses the default US holiday checker.

func (DateTime) IsDST

func (dt DateTime) IsDST() bool

IsDST returns whether the datetime is in daylight saving time.

func (DateTime) IsDSTOptimized

func (dt DateTime) IsDSTOptimized() bool

IsDSTOptimized returns whether the datetime is in daylight saving time using optimized caching

func (DateTime) IsFirstDayOfMonth

func (dt DateTime) IsFirstDayOfMonth() bool

IsFirstDayOfMonth returns whether the datetime is the first day of the month.

func (DateTime) IsFirstDayOfYear

func (dt DateTime) IsFirstDayOfYear() bool

IsFirstDayOfYear returns whether the datetime is the first day of the year (January 1st).

func (DateTime) IsFuture

func (dt DateTime) IsFuture() bool

IsFuture returns whether the datetime is in the future compared to now.

func (DateTime) IsHoliday

func (dt DateTime) IsHoliday(holidayChecker ...HolidayChecker) bool

IsHoliday returns true if the date is a holiday. If no holiday checker is provided, it uses the default US holiday checker.

func (DateTime) IsLastDayOfMonth

func (dt DateTime) IsLastDayOfMonth() bool

IsLastDayOfMonth returns whether the datetime is the last day of the month.

func (DateTime) IsLastDayOfYear

func (dt DateTime) IsLastDayOfYear() bool

IsLastDayOfYear returns whether the datetime is the last day of the year (December 31st).

func (DateTime) IsLeapYear

func (dt DateTime) IsLeapYear() bool

IsLeapYear returns whether the datetime's year is a leap year.

func (DateTime) IsLocal

func (dt DateTime) IsLocal() bool

IsLocal returns whether the datetime is in the local timezone.

func (DateTime) IsLongYear

func (dt DateTime) IsLongYear() bool

IsLongYear returns whether the datetime's year is an ISO 8601 long year. A long year has 53 ISO weeks instead of the normal 52. This occurs when the year starts on a Thursday or is a leap year starting on Wednesday.

Examples:

chronogo.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC).IsLongYear() // true - 2020 has 53 ISO weeks
chronogo.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC).IsLongYear() // false - 2021 has 52 ISO weeks

func (DateTime) IsNthWeekdayOf

func (dt DateTime) IsNthWeekdayOf(n int, unit string) bool

IsNthWeekdayOf checks if the current DateTime is the nth occurrence of its weekday in the specified unit.

Example:

dt := chronogo.Date(2024, 3, 11, 0, 0, 0, 0, time.UTC) // 2nd Monday of March
isSecond := dt.IsNthWeekdayOf(2, "month") // Returns true

func (DateTime) IsPast

func (dt DateTime) IsPast() bool

IsPast returns whether the datetime is in the past compared to now.

func (DateTime) IsSameDay

func (dt DateTime) IsSameDay(other DateTime) bool

IsSameDay checks if the given DateTime is on the same calendar day. This compares year, month, and day, ignoring time components.

Example:

dt1 := chronogo.Date(2024, 5, 15, 8, 0, 0, 0, time.UTC)
dt2 := chronogo.Date(2024, 5, 15, 20, 0, 0, 0, time.UTC)
dt1.IsSameDay(dt2) // Returns true

func (DateTime) IsSameMonth

func (dt DateTime) IsSameMonth(other DateTime) bool

IsSameMonth checks if the given DateTime is in the same month and year.

Example:

dt1 := chronogo.Date(2024, 5, 1, 0, 0, 0, 0, time.UTC)
dt2 := chronogo.Date(2024, 5, 31, 0, 0, 0, 0, time.UTC)
dt1.IsSameMonth(other) // Returns true

func (DateTime) IsSameQuarter

func (dt DateTime) IsSameQuarter(other DateTime) bool

IsSameQuarter checks if the given DateTime is in the same quarter and year.

Example:

dt1 := chronogo.Date(2024, 1, 15, 0, 0, 0, 0, time.UTC) // Q1
dt2 := chronogo.Date(2024, 3, 20, 0, 0, 0, 0, time.UTC) // Q1
dt1.IsSameQuarter(dt2) // Returns true

func (DateTime) IsSameWeek

func (dt DateTime) IsSameWeek(other DateTime) bool

IsSameWeek checks if the given DateTime is in the same ISO week and year.

Example:

dt1 := chronogo.Date(2024, 1, 15, 0, 0, 0, 0, time.UTC)
dt2 := chronogo.Date(2024, 1, 17, 0, 0, 0, 0, time.UTC)
dt1.IsSameWeek(dt2) // Returns true if in same ISO week

func (DateTime) IsSameYear

func (dt DateTime) IsSameYear(other DateTime) bool

IsSameYear checks if the given DateTime is in the same year.

Example:

dt1 := chronogo.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
dt2 := chronogo.Date(2024, 12, 31, 0, 0, 0, 0, time.UTC)
dt1.IsSameYear(other) // Returns true

func (DateTime) IsUTC

func (dt DateTime) IsUTC() bool

IsUTC returns whether the datetime is in UTC timezone.

func (DateTime) IsWeekday

func (dt DateTime) IsWeekday() bool

IsWeekday returns whether the datetime falls on a weekday (Monday through Friday).

func (DateTime) IsWeekend

func (dt DateTime) IsWeekend() bool

IsWeekend returns whether the datetime falls on a weekend (Saturday or Sunday).

func (DateTime) IsZero

func (dt DateTime) IsZero() bool

IsZero reports whether the time instant is January 1, year 1, 00:00:00 UTC.

func (DateTime) LastWeekdayOf

func (dt DateTime) LastWeekdayOf(weekday time.Weekday) DateTime

LastWeekdayOf returns the last occurrence of the specified weekday in the current month.

Example:

dt := chronogo.Date(2024, 3, 15, 0, 0, 0, 0, time.UTC)
lastFriday := dt.LastWeekdayOf(time.Friday) // Last Friday of March 2024

func (DateTime) Local

func (dt DateTime) Local() DateTime

Local converts the datetime to the local timezone.

func (DateTime) Location

func (dt DateTime) Location() *time.Location

Location returns the current timezone location.

func (DateTime) MarshalJSON

func (dt DateTime) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

func (DateTime) MarshalText

func (dt DateTime) MarshalText() ([]byte, error)

MarshalText implements encoding.TextMarshaler.

func (DateTime) NextBusinessDay

func (dt DateTime) NextBusinessDay(holidayChecker ...HolidayChecker) DateTime

NextBusinessDay returns the next business day.

func (DateTime) NextOrSameWeekday

func (dt DateTime) NextOrSameWeekday(weekday time.Weekday) DateTime

NextOrSameWeekday returns the next occurrence of the specified weekday, or the current DateTime if it's already that weekday.

Example:

dt := chronogo.Date(2024, 1, 15, 12, 0, 0, 0, time.UTC) // Monday
next := dt.NextOrSameWeekday(time.Monday) // Returns the same Monday
next := dt.NextOrSameWeekday(time.Tuesday) // Returns next Tuesday

func (DateTime) NextWeekday

func (dt DateTime) NextWeekday(weekday time.Weekday) DateTime

NextWeekday returns the next occurrence of the specified weekday. If the current day is the specified weekday, it returns the same weekday next week.

Example:

dt := chronogo.Date(2024, 1, 15, 12, 0, 0, 0, time.UTC) // Monday
next := dt.NextWeekday(time.Wednesday) // Returns next Wednesday

func (DateTime) NthWeekdayOf

func (dt DateTime) NthWeekdayOf(n int, weekday time.Weekday, unit string) DateTime

NthWeekdayOf returns the nth occurrence of the specified weekday in the given month/year. n can be 1-5 for first through fifth occurrence, or -1 for the last occurrence.

Example:

// Get the 2nd Monday of March 2024
dt := chronogo.Date(2024, 3, 1, 0, 0, 0, 0, time.UTC)
secondMonday := dt.NthWeekdayOf(2, time.Monday, "month")

// Get the last Friday of the year
lastFriday := dt.NthWeekdayOf(-1, time.Friday, "year")

func (DateTime) NthWeekdayOfMonth

func (dt DateTime) NthWeekdayOfMonth(n int, weekday time.Weekday) DateTime

NthWeekdayOfMonth returns the nth occurrence of the specified weekday in the current month. This is a convenience wrapper for NthWeekdayOf with "month" unit.

Example:

dt := chronogo.Date(2024, 3, 1, 0, 0, 0, 0, time.UTC)
thirdTuesday := dt.NthWeekdayOfMonth(3, time.Tuesday) // 3rd Tuesday of March 2024

func (DateTime) NthWeekdayOfYear

func (dt DateTime) NthWeekdayOfYear(n int, weekday time.Weekday) DateTime

NthWeekdayOfYear returns the nth occurrence of the specified weekday in the current year.

Example:

dt := chronogo.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC)
tenthMonday := dt.NthWeekdayOfYear(10, time.Monday) // 10th Monday of 2024

func (DateTime) On

func (dt DateTime) On(year int, month time.Month, day int) DateTime

On is a convenience method that sets the date components (year, month, day) in one call. This is a simpler alternative to using Set().Year().Month().Day() for date modifications. The time components (hour, minute, second, nanosecond) remain unchanged.

Examples:

dt := chronogo.Now()
dt2 := dt.On(2024, time.January, 15)  // Sets date to 2024-01-15, keeps current time
dt3 := dt.On(2025, time.December, 31) // Sets date to 2025-12-31, keeps current time

func (DateTime) PreviousBusinessDay

func (dt DateTime) PreviousBusinessDay(holidayChecker ...HolidayChecker) DateTime

PreviousBusinessDay returns the previous business day.

func (DateTime) PreviousOrSameWeekday

func (dt DateTime) PreviousOrSameWeekday(weekday time.Weekday) DateTime

PreviousOrSameWeekday returns the previous occurrence of the specified weekday, or the current DateTime if it's already that weekday.

Example:

dt := chronogo.Date(2024, 1, 15, 12, 0, 0, 0, time.UTC) // Monday
prev := dt.PreviousOrSameWeekday(time.Monday) // Returns the same Monday
prev := dt.PreviousOrSameWeekday(time.Sunday) // Returns previous Sunday

func (DateTime) PreviousWeekday

func (dt DateTime) PreviousWeekday(weekday time.Weekday) DateTime

PreviousWeekday returns the previous occurrence of the specified weekday. If the current day is the specified weekday, it returns the same weekday last week.

Example:

dt := chronogo.Date(2024, 1, 15, 12, 0, 0, 0, time.UTC) // Monday
prev := dt.PreviousWeekday(time.Friday) // Returns previous Friday

func (DateTime) Quarter

func (dt DateTime) Quarter() int

Quarter returns the quarter of the year (1-4).

func (DateTime) Round

func (dt DateTime) Round(unit Unit) DateTime

Round returns dt rounded to the nearest boundary of the given unit. Ties are rounded up to the next boundary. Calendar-aware for day/week/month/quarter/year using local timezone boundaries.

func (*DateTime) Scan

func (dt *DateTime) Scan(value any) error

Scan implements the sql.Scanner interface for database deserialization.

func (DateTime) ScheduleMonthlyEndOfMonth

func (dt DateTime) ScheduleMonthlyEndOfMonth(countryCode string, months int) []DateTime

func (DateTime) ScheduleRecurring

func (dt DateTime) ScheduleRecurring(countryCode string, frequency time.Duration, count int) []DateTime

Convenience methods for DateTime

func (DateTime) Set

func (dt DateTime) Set() *FluentDateTime

Set returns a FluentDateTime for setting specific components of the DateTime.

func (DateTime) SetDay

func (dt DateTime) SetDay(day int) DateTime

SetDay returns a new DateTime with the day set to the specified value.

func (DateTime) SetHour

func (dt DateTime) SetHour(hour int) DateTime

SetHour returns a new DateTime with the hour set to the specified value.

func (DateTime) SetMinute

func (dt DateTime) SetMinute(minute int) DateTime

SetMinute returns a new DateTime with the minute set to the specified value.

func (DateTime) SetMonth

func (dt DateTime) SetMonth(month time.Month) DateTime

SetMonth returns a new DateTime with the month set to the specified value.

func (DateTime) SetSecond

func (dt DateTime) SetSecond(second int) DateTime

SetSecond returns a new DateTime with the second set to the specified value.

func (DateTime) SetYear

func (dt DateTime) SetYear(year int) DateTime

SetYear returns a new DateTime with the year set to the specified value.

func (DateTime) StartOfDay

func (dt DateTime) StartOfDay() DateTime

StartOfDay returns a new DateTime set to the beginning of the day (00:00:00).

func (DateTime) StartOfMonth

func (dt DateTime) StartOfMonth() DateTime

StartOfMonth returns a new DateTime set to the beginning of the month (first day at 00:00:00).

func (DateTime) StartOfQuarter

func (dt DateTime) StartOfQuarter() DateTime

StartOfQuarter returns a new DateTime set to the beginning of the quarter.

func (DateTime) StartOfWeek

func (dt DateTime) StartOfWeek() DateTime

StartOfWeek returns a new DateTime set to the beginning of the week (Monday at 00:00:00).

func (DateTime) StartOfYear

func (dt DateTime) StartOfYear() DateTime

StartOfYear returns a new DateTime set to the beginning of the year (January 1st at 00:00:00).

func (DateTime) String

func (dt DateTime) String() string

String returns the default string representation (ISO 8601 format).

func (DateTime) Sub

func (dt DateTime) Sub(other DateTime) time.Duration

Sub returns the time.Duration between two DateTime instances.

func (DateTime) Subtract

func (dt DateTime) Subtract(duration time.Duration) DateTime

Subtract subtracts a time.Duration from the datetime.

func (DateTime) SubtractBusinessDays

func (dt DateTime) SubtractBusinessDays(days int, holidayChecker ...HolidayChecker) DateTime

SubtractBusinessDays subtracts the specified number of business days.

func (DateTime) SubtractDays

func (dt DateTime) SubtractDays(days int) DateTime

SubtractDays subtracts the specified number of days.

func (DateTime) SubtractHours

func (dt DateTime) SubtractHours(hours int) DateTime

SubtractHours subtracts the specified number of hours.

func (DateTime) SubtractMinutes

func (dt DateTime) SubtractMinutes(minutes int) DateTime

SubtractMinutes subtracts the specified number of minutes.

func (DateTime) SubtractMonths

func (dt DateTime) SubtractMonths(months int) DateTime

SubtractMonths subtracts the specified number of months.

func (DateTime) SubtractSeconds

func (dt DateTime) SubtractSeconds(seconds int) DateTime

SubtractSeconds subtracts the specified number of seconds.

func (DateTime) SubtractYears

func (dt DateTime) SubtractYears(years int) DateTime

SubtractYears subtracts the specified number of years.

func (DateTime) TimeAgo

func (dt DateTime) TimeAgo() string

TimeAgo returns a human-readable string representing how long ago this DateTime occurred. Uses the default locale.

func (DateTime) TimeFromNow

func (dt DateTime) TimeFromNow() string

TimeFromNow returns a human-readable string representing when this DateTime will occur relative to now. Uses the default locale.

func (DateTime) ToAtomString

func (dt DateTime) ToAtomString() string

ToAtomString returns the datetime in Atom feed format (RFC 3339). This is an alias for ToW3CString().

func (DateTime) ToCookieString

func (dt DateTime) ToCookieString() string

ToCookieString returns the datetime in HTTP cookie format (RFC 1123). Example: "Mon, 15 Jan 2024 12:00:00 GMT"

func (DateTime) ToDateString

func (dt DateTime) ToDateString() string

ToDateString returns the date portion as a string (YYYY-MM-DD).

func (DateTime) ToDateTimeString

func (dt DateTime) ToDateTimeString() string

ToDateTimeString returns the datetime as a string (YYYY-MM-DD HH:MM:SS).

func (DateTime) ToISO8601String

func (dt DateTime) ToISO8601String() string

ToISO8601String returns the datetime in ISO 8601 format.

func (DateTime) ToRSSString

func (dt DateTime) ToRSSString() string

ToRSSString returns the datetime in RSS feed format (RFC 1123Z). Example: "Mon, 15 Jan 2024 12:00:00 +0000"

func (DateTime) ToTimeString

func (dt DateTime) ToTimeString() string

ToTimeString returns the time portion as a string (HH:MM:SS).

func (DateTime) ToW3CString

func (dt DateTime) ToW3CString() string

ToW3CString returns the datetime in W3C format (ISO 8601 / RFC 3339). Example: "2024-01-15T12:00:00Z" or "2024-01-15T12:00:00+00:00"

func (DateTime) Truncate

func (dt DateTime) Truncate(unit Unit) DateTime

Truncate returns dt truncated to the start of the given unit. For calendar units (day/week/month/quarter/year) this aligns to the logical start boundary in the current location (e.g., StartOfDay, Monday StartOfWeek).

func (DateTime) UTC

func (dt DateTime) UTC() DateTime

UTC converts the datetime to UTC timezone.

func (DateTime) UnixMicro

func (dt DateTime) UnixMicro() int64

UnixMicro returns t as a Unix time, the number of microseconds elapsed since January 1, 1970 UTC.

func (DateTime) UnixMilli

func (dt DateTime) UnixMilli() int64

UnixMilli returns t as a Unix time, the number of milliseconds elapsed since January 1, 1970 UTC.

func (DateTime) UnixNano

func (dt DateTime) UnixNano() int64

UnixNano returns t as a Unix time, the number of nanoseconds elapsed since January 1, 1970 UTC.

func (*DateTime) UnmarshalJSON

func (dt *DateTime) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler.

func (*DateTime) UnmarshalText

func (dt *DateTime) UnmarshalText(data []byte) error

UnmarshalText implements encoding.TextUnmarshaler.

func (DateTime) Unwrap

func (dt DateTime) Unwrap() time.Time

Unwrap returns the underlying time.Time value.

func (DateTime) Validate

func (dt DateTime) Validate() error

Validate checks if a DateTime is valid and returns a helpful error if not.

func (DateTime) Value

func (dt DateTime) Value() (driver.Value, error)

Value implements the driver.Valuer interface for database serialization.

func (DateTime) WeekOfMonth

func (dt DateTime) WeekOfMonth() int

WeekOfMonth returns the week number within the month (1-6). The first week of the month is the week containing the first day of the month.

func (DateTime) WeekOfMonthISO

func (dt DateTime) WeekOfMonthISO() int

WeekOfMonthISO returns the ISO-style week of month using Monday as the first day of week and accounting for the weekday of the month's first day.

func (DateTime) WeekOfMonthWithStart

func (dt DateTime) WeekOfMonthWithStart(start time.Weekday) int

WeekOfMonthWithStart returns the week of the month using a custom week start day. For example, start = time.Sunday yields Sunday-start weeks.

func (DateTime) WeekdayOccurrenceInMonth

func (dt DateTime) WeekdayOccurrenceInMonth() int

WeekdayOccurrenceInMonth returns which occurrence of the weekday this is in the month (1-5). Returns 0 if it cannot be determined.

Example:

dt := chronogo.Date(2024, 3, 11, 0, 0, 0, 0, time.UTC) // 2nd Monday of March
occurrence := dt.WeekdayOccurrenceInMonth() // Returns 2

func (DateTime) WithEnhancedBusinessDays

func (dt DateTime) WithEnhancedBusinessDays(countryCode string) *EnhancedBusinessDayCalculator

Convenience methods for DateTime that use enhanced calculator

type DefaultHolidayChecker

type DefaultHolidayChecker struct {
	// contains filtered or unexported fields
}

DefaultHolidayChecker provides common holidays for different regions.

func NewUSHolidayChecker

func NewUSHolidayChecker() *DefaultHolidayChecker

NewUSHolidayChecker creates a holiday checker with common US federal holidays.

func (*DefaultHolidayChecker) AddHoliday

func (hc *DefaultHolidayChecker) AddHoliday(holiday Holiday)

AddHoliday adds a custom holiday to the checker.

func (*DefaultHolidayChecker) GetHolidays

func (hc *DefaultHolidayChecker) GetHolidays(year int) []DateTime

GetHolidays returns all holidays for a given year.

func (*DefaultHolidayChecker) IsHoliday

func (hc *DefaultHolidayChecker) IsHoliday(dt DateTime) bool

IsHoliday checks if the given date is a holiday.

type Diff

type Diff struct {
	// contains filtered or unexported fields
}

Diff represents the difference between two DateTime instances. It provides both precise (Duration-based) and calendar-aware (Period-based) difference methods. This type unifies the functionality of time.Duration and Period into a single, convenient API.

func (Diff) Abs

func (d Diff) Abs() Diff

Abs returns a new Diff with positive duration.

func (Diff) CompactString

func (d Diff) CompactString() string

CompactString returns a compact string representation (e.g., "2y 3m 5d").

func (Diff) Compare

func (d Diff) Compare(other Diff) int

Compare compares this Diff with another Diff and returns:

  • -1 if this Diff is shorter
  • 0 if they are equal
  • 1 if this Diff is longer

func (Diff) Days

func (d Diff) Days() int

Days returns the number of full 24-hour days in the difference.

func (Diff) Duration

func (d Diff) Duration() time.Duration

Duration returns the precise time.Duration between the two DateTimes.

func (Diff) End

func (d Diff) End() DateTime

End returns the later DateTime in the comparison.

func (Diff) EqualTo

func (d Diff) EqualTo(other Diff) bool

EqualTo returns true if this Diff has the same duration as the other Diff.

func (Diff) ForHumans

func (d Diff) ForHumans() string

ForHumans returns a human-readable string describing the difference. Uses the default locale (set via SetDefaultLocale). Defaults to English.

Examples:

  • English: "2 years ago", "in 3 months"
  • Spanish: "hace 2 años", "en 3 meses"
  • Japanese: "2年前", "3ヶ月後"

func (Diff) ForHumansComparison

func (d Diff) ForHumansComparison() string

ForHumansComparison returns a human-readable comparison string. Uses the default locale.

Examples:

  • English: "2 years before", "3 months after"
  • Spanish: "hace 2 años", "en 3 meses"
  • Japanese: "2年前", "3ヶ月後"

func (Diff) ForHumansLocalized

func (d Diff) ForHumansLocalized(localeCode string) (string, error)

ForHumansLocalized returns a human-readable string in the specified locale.

func (Diff) Hours

func (d Diff) Hours() int

Hours returns the number of full hours in the difference.

func (Diff) InDays

func (d Diff) InDays() float64

InDays returns the total difference expressed as days (with fractional part).

func (Diff) InHours

func (d Diff) InHours() float64

InHours returns the total difference expressed as hours (with fractional part).

func (Diff) InMinutes

func (d Diff) InMinutes() float64

InMinutes returns the total difference expressed as minutes (with fractional part).

func (Diff) InMonths

func (d Diff) InMonths() float64

InMonths returns the total difference expressed as months (with fractional part). This uses an approximate calculation (30.44 days per month).

func (Diff) InSeconds

func (d Diff) InSeconds() float64

InSeconds returns the total difference expressed as seconds (with fractional part).

func (Diff) InWeeks

func (d Diff) InWeeks() float64

InWeeks returns the total difference expressed as weeks (with fractional part).

func (Diff) InYears

func (d Diff) InYears() float64

InYears returns the total difference expressed as years (with fractional part). This uses an approximate calculation (365.25 days per year).

func (Diff) Invert

func (d Diff) Invert() Diff

Invert returns a new Diff with start and end swapped.

func (Diff) IsNegative

func (d Diff) IsNegative() bool

IsNegative returns true if the end DateTime is before the start DateTime.

func (Diff) IsPositive

func (d Diff) IsPositive() bool

IsPositive returns true if the end DateTime is after the start DateTime.

func (Diff) IsZero

func (d Diff) IsZero() bool

IsZero returns true if the two DateTimes are identical.

func (Diff) LongerThan

func (d Diff) LongerThan(other Diff) bool

LongerThan returns true if this Diff is longer than the other Diff.

func (Diff) MarshalJSON

func (d Diff) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

func (Diff) Minutes

func (d Diff) Minutes() int

Minutes returns the number of full minutes in the difference.

func (Diff) Months

func (d Diff) Months() int

Months returns the total number of full calendar months in the difference. This is calendar-aware and accounts for varying month lengths.

func (Diff) Period

func (d Diff) Period() Period

Period returns the Period representation for calendar-aware operations.

func (Diff) Seconds

func (d Diff) Seconds() int

Seconds returns the number of full seconds in the difference.

func (Diff) ShorterThan

func (d Diff) ShorterThan(other Diff) bool

ShorterThan returns true if this Diff is shorter than the other Diff.

func (Diff) Start

func (d Diff) Start() DateTime

Start returns the earlier DateTime in the comparison.

func (Diff) String

func (d Diff) String() string

String returns a detailed string representation of the difference.

func (Diff) Weeks

func (d Diff) Weeks() int

Weeks returns the number of full weeks in the difference.

func (Diff) Years

func (d Diff) Years() int

Years returns the number of full calendar years in the difference. This is calendar-aware and accounts for leap years and varying month lengths.

type EnhancedBusinessDayCalculator

type EnhancedBusinessDayCalculator struct {
	// contains filtered or unexported fields
}

EnhancedBusinessDayCalculator wraps goholiday's optimized BusinessDayCalculator to provide high-performance business day calculations with extensive holiday support.

func NewEnhancedBusinessDayCalculator

func NewEnhancedBusinessDayCalculator(countryCode string) *EnhancedBusinessDayCalculator

NewEnhancedBusinessDayCalculator creates a new enhanced business day calculator for the specified country with optimized performance.

func (*EnhancedBusinessDayCalculator) AddBusinessDays

func (ebc *EnhancedBusinessDayCalculator) AddBusinessDays(dt DateTime, days int) DateTime

AddBusinessDays adds business days using optimized calculation

func (*EnhancedBusinessDayCalculator) BusinessDaysBetween

func (ebc *EnhancedBusinessDayCalculator) BusinessDaysBetween(start, end DateTime) int

BusinessDaysBetween calculates business days between dates with optimized algorithms

func (*EnhancedBusinessDayCalculator) IsBusinessDay

func (ebc *EnhancedBusinessDayCalculator) IsBusinessDay(dt DateTime) bool

IsBusinessDay checks if a date is a business day using optimized algorithms

func (*EnhancedBusinessDayCalculator) IsEndOfMonth

func (ebc *EnhancedBusinessDayCalculator) IsEndOfMonth(dt DateTime) bool

IsEndOfMonth checks if a date is the last business day of the month. New in goholiday v0.6.3+ - useful for end-of-month business processes.

func (*EnhancedBusinessDayCalculator) NextBusinessDay

func (ebc *EnhancedBusinessDayCalculator) NextBusinessDay(dt DateTime) DateTime

NextBusinessDay returns the next business day using optimized lookup

func (*EnhancedBusinessDayCalculator) PreviousBusinessDay

func (ebc *EnhancedBusinessDayCalculator) PreviousBusinessDay(dt DateTime) DateTime

PreviousBusinessDay returns the previous business day using optimized lookup

func (*EnhancedBusinessDayCalculator) SetCustomWeekends

func (ebc *EnhancedBusinessDayCalculator) SetCustomWeekends(weekends []time.Weekday)

SetCustomWeekends allows setting custom weekend days (e.g., Friday-Saturday for some regions)

type FluentDateTime

type FluentDateTime struct {
	// contains filtered or unexported fields
}

FluentDateTime provides a fluent API for building and manipulating DateTime instances. It allows method chaining for more readable and expressive date/time operations.

func (*FluentDateTime) Build

func (fdt *FluentDateTime) Build() DateTime

Build returns the final DateTime with all modifications applied.

func (*FluentDateTime) Day

func (fdt *FluentDateTime) Day(day int) *FluentDateTime

Day sets the day component.

func (*FluentDateTime) Hour

func (fdt *FluentDateTime) Hour(hour int) *FluentDateTime

Hour sets the hour component.

func (*FluentDateTime) Minute

func (fdt *FluentDateTime) Minute(minute int) *FluentDateTime

Minute sets the minute component.

func (*FluentDateTime) Month

func (fdt *FluentDateTime) Month(month time.Month) *FluentDateTime

Month sets the month component.

func (*FluentDateTime) Second

func (fdt *FluentDateTime) Second(second int) *FluentDateTime

Second sets the second component.

func (*FluentDateTime) Timezone

func (fdt *FluentDateTime) Timezone(loc *time.Location) *FluentDateTime

Timezone sets the timezone.

func (*FluentDateTime) Year

func (fdt *FluentDateTime) Year(year int) *FluentDateTime

Year sets the year component.

type FluentDuration

type FluentDuration struct {
	// contains filtered or unexported fields
}

FluentDuration provides a fluent API for building durations with human-readable methods. It stores calendar units (years, months) separately from time units for accurate arithmetic. This design ensures that date arithmetic follows Go's time package behavior for calendar operations while maintaining precision for time-based operations.

func (*FluentDuration) Days

func (fd *FluentDuration) Days(days int) *FluentDuration

Days adds the specified number of days to the duration.

func (*FluentDuration) From

func (fd *FluentDuration) From(dt DateTime) DateTime

From subtracts the accumulated duration from a DateTime and returns the result.

func (*FluentDuration) Hours

func (fd *FluentDuration) Hours(hours int) *FluentDuration

Hours adds the specified number of hours to the duration.

func (*FluentDuration) Microseconds

func (fd *FluentDuration) Microseconds(microseconds int) *FluentDuration

Microseconds adds the specified number of microseconds to the duration.

func (*FluentDuration) Milliseconds

func (fd *FluentDuration) Milliseconds(milliseconds int) *FluentDuration

Milliseconds adds the specified number of milliseconds to the duration.

func (*FluentDuration) Minutes

func (fd *FluentDuration) Minutes(minutes int) *FluentDuration

Minutes adds the specified number of minutes to the duration.

func (*FluentDuration) Months

func (fd *FluentDuration) Months(months int) *FluentDuration

Months adds the specified number of months to the duration.

func (*FluentDuration) Nanoseconds

func (fd *FluentDuration) Nanoseconds(nanoseconds int) *FluentDuration

Nanoseconds adds the specified number of nanoseconds to the duration.

func (*FluentDuration) Seconds

func (fd *FluentDuration) Seconds(seconds int) *FluentDuration

Seconds adds the specified number of seconds to the duration.

func (*FluentDuration) To

func (fd *FluentDuration) To(dt DateTime) DateTime

To applies the accumulated duration to a DateTime and returns the result.

func (*FluentDuration) Weeks

func (fd *FluentDuration) Weeks(weeks int) *FluentDuration

Weeks adds the specified number of weeks to the duration.

func (*FluentDuration) Years

func (fd *FluentDuration) Years(years int) *FluentDuration

Years adds the specified number of years to the duration.

type GoHolidayChecker

type GoHolidayChecker struct {
	// contains filtered or unexported fields
}

GoHolidayChecker wraps the goholiday library to implement the HolidayChecker interface. This provides comprehensive holiday data for multiple countries and regions.

func NewGoHolidayChecker

func NewGoHolidayChecker(country string) *GoHolidayChecker

NewGoHolidayChecker creates a new holiday checker using the goholiday library. The country parameter should be a 2-letter ISO country code (e.g., "US", "GB", "CA", "AU", "NZ", "DE", "FR", "JP", "IN", "BR", "MX", "IT", "ES", "NL", "KR", "PT", "PL", "RU", "CN", "TH", "SG", "TR", "UA", "AT", "BE", "CH", "CL", "FI", "IE", "IL", "NO", "SE"). goholiday v0.6.4+ supports 34 countries with comprehensive regional subdivision data and multi-language holiday names. Based on Vacanza holidays framework. See DEPENDENCIES.md for version tracking.

func (*GoHolidayChecker) AreHolidays

func (ghc *GoHolidayChecker) AreHolidays(dates []DateTime) []bool

AreHolidays performs batch holiday checking for efficient range operations. New in goholiday v0.6.4+ - optimized for bulk date processing.

func (*GoHolidayChecker) ClearCache

func (ghc *GoHolidayChecker) ClearCache()

ClearCache clears the holiday cache to free memory. Useful for long-running applications. New in goholiday v0.6.3+.

func (*GoHolidayChecker) CountHolidaysInRange

func (ghc *GoHolidayChecker) CountHolidaysInRange(start, end DateTime) int

CountHolidaysInRange counts holidays within a date range.

func (*GoHolidayChecker) GetCountry

func (ghc *GoHolidayChecker) GetCountry() string

GetCountry returns the country code for this holiday checker.

func (*GoHolidayChecker) GetHolidayCategories

func (ghc *GoHolidayChecker) GetHolidayCategories() []goholidays.HolidayCategory

GetHolidayCategories returns the supported holiday categories for this country. New in goholiday v0.6.3+ - categories include "public", "bank", "school", etc.

func (*GoHolidayChecker) GetHolidayCount

func (ghc *GoHolidayChecker) GetHolidayCount(year int) (int, error)

GetHolidayCount returns the number of holidays in a given year. New in goholiday v0.6.3+ - efficient counting without loading all holidays.

func (*GoHolidayChecker) GetHolidayName

func (ghc *GoHolidayChecker) GetHolidayName(dt DateTime) string

GetHolidayName returns the name of the holiday if the date is a holiday, empty string otherwise.

func (*GoHolidayChecker) GetHolidaysInRange

func (ghc *GoHolidayChecker) GetHolidaysInRange(start, end DateTime) map[DateTime]string

GetHolidaysInRange returns all holidays in the specified date range. Returns a map where keys are holiday dates and values are holiday names. New in goholiday v0.6.4+ - optimized for calendar operations.

func (*GoHolidayChecker) GetLanguage

func (ghc *GoHolidayChecker) GetLanguage() string

GetLanguage returns the language used for holiday names. New in goholiday v0.6.3+ - supports multi-language holiday names.

func (*GoHolidayChecker) GetSubdivisions

func (ghc *GoHolidayChecker) GetSubdivisions() []string

GetSubdivisions returns the supported subdivisions for this country. New in goholiday v0.6.3+ - provides access to regional holiday data.

func (*GoHolidayChecker) IsHoliday

func (ghc *GoHolidayChecker) IsHoliday(dt DateTime) bool

IsHoliday checks if the given date is a holiday using the goholiday library.

type Holiday

type Holiday struct {
	Name    string
	Month   time.Month
	Day     int
	Year    *int          // nil for recurring holiday
	WeekDay *time.Weekday // for holidays like "first Monday of September"
	WeekNum *int          // which week of the month (1-5, -1 for last)
}

Holiday represents a specific holiday with optional recurring rules.

type HolidayAwareScheduler

type HolidayAwareScheduler struct {
	// contains filtered or unexported fields
}

HolidayAwareScheduler provides intelligent scheduling that respects holidays and business days

func NewHolidayAwareScheduler

func NewHolidayAwareScheduler(countryCode string) *HolidayAwareScheduler

NewHolidayAwareScheduler creates a new scheduler for the specified country

func (*HolidayAwareScheduler) ScheduleBusinessDays

func (has *HolidayAwareScheduler) ScheduleBusinessDays(start DateTime, days int) []DateTime

ScheduleBusinessDays schedules events on business days only

func (*HolidayAwareScheduler) ScheduleMonthlyEndOfMonth

func (has *HolidayAwareScheduler) ScheduleMonthlyEndOfMonth(start DateTime, months int) []DateTime

ScheduleMonthlyEndOfMonth schedules events at the end of each month, adjusting for holidays months: number of months to schedule for

func (*HolidayAwareScheduler) ScheduleQuarterly

func (has *HolidayAwareScheduler) ScheduleQuarterly(start DateTime, quarters int) []DateTime

ScheduleQuarterly schedules events quarterly, avoiding holidays

func (*HolidayAwareScheduler) ScheduleRecurring

func (has *HolidayAwareScheduler) ScheduleRecurring(start DateTime, frequency time.Duration, count int) []DateTime

ScheduleRecurring creates a recurring schedule that avoids holidays and weekends frequency: how often to schedule (e.g., 24*time.Hour for daily, 7*24*time.Hour for weekly) count: how many occurrences to generate

func (*HolidayAwareScheduler) ScheduleWeekly

func (has *HolidayAwareScheduler) ScheduleWeekly(start DateTime, weeks int) []DateTime

ScheduleWeekly schedules weekly events, moving to next business day if needed

type HolidayCalendar

type HolidayCalendar struct {
	// contains filtered or unexported fields
}

HolidayCalendar provides calendar functionality with holiday awareness

func NewHolidayCalendar

func NewHolidayCalendar(countryCode string) *HolidayCalendar

NewHolidayCalendar creates a new holiday calendar for the specified country

func (*HolidayCalendar) GenerateMonth

func (hc *HolidayCalendar) GenerateMonth(year int, month time.Month) []CalendarEntry

GenerateMonth generates calendar entries for a specific month

func (*HolidayCalendar) GetMonthlyHolidays

func (hc *HolidayCalendar) GetMonthlyHolidays(year int, month time.Month) []CalendarEntry

GetMonthlyHolidays returns all holidays in a specific month

func (*HolidayCalendar) GetUpcomingHolidays

func (hc *HolidayCalendar) GetUpcomingHolidays(from DateTime, count int) []CalendarEntry

GetUpcomingHolidays returns the next N holidays from the given date

func (*HolidayCalendar) GetYearlyHolidays

func (hc *HolidayCalendar) GetYearlyHolidays(year int) []CalendarEntry

GetYearlyHolidays returns all holidays in a specific year

func (*HolidayCalendar) PrintMonth

func (hc *HolidayCalendar) PrintMonth(year int, month time.Month)

PrintMonth prints a formatted calendar for the specified month

type HolidayChecker

type HolidayChecker interface {
	IsHoliday(dt DateTime) bool
}

HolidayChecker is an interface for checking if a date is a holiday. Users can implement this interface to provide custom holiday logic.

func NewHolidayChecker

func NewHolidayChecker(country string) HolidayChecker

NewHolidayChecker creates a new goholiday-based holiday checker for the specified country. This is the recommended way to create holiday checkers for production use. Supported countries: US, GB, CA, AU, NZ, DE, FR, JP, IN, BR, MX, IT, ES, NL, KR, PT, PL, RU, CN, TH, SG, TR, UA, AT, BE, CH, CL, FI, IE, IL, NO, SE (34 countries with comprehensive regional subdivisions) Features: Sub-microsecond holiday lookups, multi-language support, thread-safe operations, intelligent caching Based on Vacanza holidays framework. See DEPENDENCIES.md for version tracking.

type ISO8601Duration

type ISO8601Duration struct {
	Years   int
	Months  int
	Days    int
	Hours   int
	Minutes int
	Seconds float64
}

ISO8601Duration represents a parsed ISO 8601 duration

type Locale

type Locale struct {
	Code         string                   // Locale code (e.g., "en-US", "es-ES")
	Name         string                   // Human-readable name
	MonthNames   []string                 // Full month names (January, February, ...)
	MonthAbbr    []string                 // Abbreviated month names (Jan, Feb, ...)
	WeekdayNames []string                 // Full weekday names (Monday, Tuesday, ...)
	WeekdayAbbr  []string                 // Abbreviated weekday names (Mon, Tue, ...)
	AMPMNames    []string                 // AM/PM indicators
	Ordinals     map[int]string           // Ordinal suffixes (1st, 2nd, 3rd, ...)
	TimeUnits    map[string]TimeUnitNames // Time unit names for human differences
	DateFormats  map[string]string        // Common date format patterns
}

Locale represents a specific locale configuration for formatting dates and times.

func GetLocale

func GetLocale(code string) (*Locale, error)

GetLocale retrieves a locale by code

type LocaleRegistry

type LocaleRegistry struct {
	// contains filtered or unexported fields
}

LocaleRegistry manages available locales

type ParseConfig

type ParseConfig struct {
	// Strict mode: only parse technical formats (ISO 8601, RFC 3339, Unix timestamps)
	// When false, enables natural language parsing via godateparser
	Strict bool

	// Languages for natural language parsing (e.g., "en", "es", "pt", "fr", "de", "zh", "ja")
	// Default: all supported languages
	Languages []string

	// Location for parsing (default: UTC)
	Location *time.Location

	// Prefer future dates when parsing ambiguous relative dates
	// e.g., "Friday" will prefer next Friday if today is not Friday
	PreferFuture bool
}

ParseConfig holds configuration for intelligent parsing with natural language support.

type ParseOptions

type ParseOptions struct {
	Exact  bool // Return exact type (Date, Time, Interval) if true
	Strict bool // Use strict parsing (RFC3339/ISO8601 only) if true
}

ParseOptions defines options for advanced parsing

type Period

type Period struct {
	Start DateTime
	End   DateTime
}

Period represents a time interval between two DateTime instances. It provides iteration capabilities and human-friendly representations.

func NewPeriod

func NewPeriod(start, end DateTime) Period

NewPeriod creates a new Period between two DateTime instances.

func (Period) Abs

func (p Period) Abs() Period

Abs returns a new Period with positive duration.

func (Period) Contains

func (p Period) Contains(dt DateTime) bool

Contains checks if a DateTime falls within the period.

func (Period) Days

func (p Period) Days() int

Days returns the number of full days in the period.

func (Period) Duration

func (p Period) Duration() time.Duration

Duration returns the time.Duration of the period.

func (Period) Encompasses

func (p Period) Encompasses(other Period) bool

Encompasses checks if this period completely contains another period.

Example:

outer := chronogo.NewPeriod(
    chronogo.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC),
    chronogo.Date(2024, 12, 31, 0, 0, 0, 0, time.UTC),
)
inner := chronogo.NewPeriod(
    chronogo.Date(2024, 6, 1, 0, 0, 0, 0, time.UTC),
    chronogo.Date(2024, 6, 30, 0, 0, 0, 0, time.UTC),
)
outer.Encompasses(inner) // Returns true

func (Period) FastRangeDays

func (p Period) FastRangeDays(step ...int) []DateTime

FastRangeDays returns a slice of DateTime instances for day-based iteration Optimized for the most common use case of daily iteration.

func (Period) ForEach

func (p Period) ForEach(unit string, step int, fn func(DateTime))

ForEach iterates over the period with the given unit and step, calling fn for each DateTime.

func (Period) Gap

func (p Period) Gap(other Period) Period

Gap returns the period between this period and another period. If the periods overlap, returns a zero period.

Example:

p1 := chronogo.NewPeriod(start1, end1)
p2 := chronogo.NewPeriod(start2, end2)
gap := p1.Gap(p2) // Returns the period between them

func (Period) Hours

func (p Period) Hours() int

Hours returns the number of full hours in the period.

func (Period) InDays

func (p Period) InDays() float64

InDays returns the total period expressed in days as a float.

func (Period) InHours

func (p Period) InHours() float64

InHours returns the total period expressed in hours as a float.

func (Period) InMinutes

func (p Period) InMinutes() float64

InMinutes returns the total period expressed in minutes as a float.

func (Period) InSeconds

func (p Period) InSeconds() float64

InSeconds returns the total period expressed in seconds as a float.

func (Period) IsNegative

func (p Period) IsNegative() bool

IsNegative returns true if the period represents a negative duration (end before start).

func (Period) Merge

func (p Period) Merge(other Period) Period

Merge combines this period with another period, returning a new period that spans from the earliest start to the latest end.

Example:

p1 := chronogo.NewPeriod(start1, end1)
p2 := chronogo.NewPeriod(start2, end2)
merged := p1.Merge(p2) // Returns period covering both

func (Period) Minutes

func (p Period) Minutes() int

Minutes returns the number of full minutes in the period.

func (Period) Months

func (p Period) Months() int

Months returns the total number of full months in the period.

func (Period) Overlaps

func (p Period) Overlaps(other Period) bool

Overlaps checks if this period overlaps with another period. Two periods overlap if they share any common time.

Example:

p1 := chronogo.NewPeriod(
    chronogo.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC),
    chronogo.Date(2024, 1, 10, 0, 0, 0, 0, time.UTC),
)
p2 := chronogo.NewPeriod(
    chronogo.Date(2024, 1, 5, 0, 0, 0, 0, time.UTC),
    chronogo.Date(2024, 1, 15, 0, 0, 0, 0, time.UTC),
)
p1.Overlaps(p2) // Returns true

func (Period) Range

func (p Period) Range(unit string, step ...int) <-chan DateTime

Range returns a channel that yields DateTime instances within the period. The step parameter determines the unit: "days", "hours", "minutes", "seconds".

func (Period) RangeByUnit

func (p Period) RangeByUnit(unit Unit, step ...int) <-chan DateTime

RangeByUnit returns a channel that yields DateTime instances within the period using typed units.

func (Period) RangeByUnitSlice

func (p Period) RangeByUnitSlice(unit Unit, step ...int) []DateTime

RangeByUnitSlice returns a pre-allocated slice of DateTime instances for better performance when you need all values at once rather than iterating.

func (Period) RangeByUnitWithContext

func (p Period) RangeByUnitWithContext(ctx context.Context, unit Unit, step ...int) <-chan DateTime

RangeByUnitWithContext returns a channel that yields DateTime instances within the period using typed units with context cancellation support.

func (Period) RangeDays

func (p Period) RangeDays(step ...int) <-chan DateTime

RangeDays is a convenience method for ranging by days.

func (Period) RangeHours

func (p Period) RangeHours(step ...int) <-chan DateTime

RangeHours is a convenience method for ranging by hours.

func (Period) RangeWithContext

func (p Period) RangeWithContext(ctx context.Context, unit string, step ...int) <-chan DateTime

RangeWithContext returns a channel that yields DateTime instances within the period with context cancellation. The step parameter determines the unit: "years", "months", "days", "hours", "minutes", "seconds". This method provides memory-safe iteration by respecting context cancellation and preventing goroutine leaks.

func (Period) Seconds

func (p Period) Seconds() int

Seconds returns the number of full seconds in the period.

func (Period) String

func (p Period) String() string

String returns a string representation of the period.

func (Period) Years

func (p Period) Years() int

Years returns the number of full years in the period.

type TimeUnitNames

type TimeUnitNames struct {
	Singular string
	Plural   string
}

TimeUnitNames contains singular and plural forms for time units

type Unit

type Unit int

Unit represents a logical time unit used by various helpers.

const (
	UnitSecond Unit = iota
	UnitMinute
	UnitHour
	UnitDay
	UnitWeek
	UnitMonth
	UnitQuarter
	UnitYear
)

Directories

Path Synopsis
cmd
chrono-demo command
Demo program showcasing chronogo's comprehensive datetime functionality
Demo program showcasing chronogo's comprehensive datetime functionality
diff-demo command
localization command
testing-demo command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL