1. go
  2. /standard library
  3. /time

Working with Time and Date in Go

Go's time package provides comprehensive functionality for working with dates, times, durations, and time zones. This guide covers common time-related operations and best practices.

Basic Time Operations

Getting Current Time

func timeBasics() {
    // Get current time
    now := time.Now()
    fmt.Printf("Current time: %v\n", now)
    
    // Get components
    year := now.Year()
    month := now.Month()
    day := now.Day()
    hour := now.Hour()
    minute := now.Minute()
    second := now.Second()
    
    fmt.Printf("Date: %d-%02d-%02d\n", year, month, day)
    fmt.Printf("Time: %02d:%02d:%02d\n", hour, minute, second)
}

Creating Time Objects

func createTime() {
    // Create time from components
    t1 := time.Date(2024, time.March, 19, 14, 30, 0, 0, time.UTC)
    
    // Parse time string
    t2, err := time.Parse("2006-01-02", "2024-03-19")
    if err != nil {
        log.Fatal(err)
    }
    
    // Parse with layout
    t3, err := time.Parse(time.RFC3339, "2024-03-19T14:30:00Z")
    if err != nil {
        log.Fatal(err)
    }
}

Time Formatting

Standard Formats

func formatTime(t time.Time) {
    // Standard formats
    fmt.Println(t.Format(time.RFC3339))     // "2024-03-19T14:30:00Z"
    fmt.Println(t.Format(time.RFC822))      // "19 Mar 24 14:30 UTC"
    fmt.Println(t.Format(time.RFC1123))     // "Tue, 19 Mar 2024 14:30:00 UTC"
    fmt.Println(t.Format(time.UnixDate))    // "Tue Mar 19 14:30:00 UTC 2024"
    fmt.Println(t.Format(time.Kitchen))     // "2:30PM"
}

Custom Formats

func customFormat(t time.Time) {
    // Custom formats using reference time: "Mon Jan 2 15:04:05 MST 2006"
    layouts := []string{
        "2006-01-02",                 // Date only
        "15:04:05",                   // Time only
        "2006-01-02 15:04:05",        // Date and time
        "Monday, January 2, 2006",     // Full date
        "Mon, Jan 2 '06",             // Short date
    }
    
    for _, layout := range layouts {
        fmt.Println(t.Format(layout))
    }
}

Time Calculations

Adding and Subtracting Time

func timeCalculations() {
    now := time.Now()
    
    // Add duration
    future := now.Add(24 * time.Hour)        // Add 1 day
    futureWeek := now.AddDate(0, 0, 7)       // Add 1 week
    
    // Subtract duration
    past := now.Add(-2 * time.Hour)          // 2 hours ago
    lastWeek := now.AddDate(0, 0, -7)        // 1 week ago
    
    // Time difference
    duration := future.Sub(now)
    hours := duration.Hours()
    minutes := duration.Minutes()
    seconds := duration.Seconds()
}

Comparing Times

func compareTime(t1, t2 time.Time) {
    if t1.Before(t2) {
        fmt.Println("t1 is before t2")
    }
    
    if t1.After(t2) {
        fmt.Println("t1 is after t2")
    }
    
    if t1.Equal(t2) {
        fmt.Println("t1 is equal to t2")
    }
}

Time Zones

Working with Time Zones

func timeZones() error {
    // Load time zone
    nyc, err := time.LoadLocation("America/New_York")
    if err != nil {
        return fmt.Errorf("loading time zone: %w", err)
    }
    
    // Create time in specific zone
    t := time.Date(2024, time.March, 19, 14, 30, 0, 0, nyc)
    
    // Convert to different zone
    utc := t.UTC()
    local := t.Local()
    
    // Get zone information
    name, offset := t.Zone()
    fmt.Printf("Zone: %s, Offset: %d\n", name, offset)
    
    return nil
}

Time Zone Conversions

func convertTimeZones() error {
    // Get current time
    now := time.Now()
    
    // Convert to different zones
    zones := []string{
        "America/New_York",
        "Europe/London",
        "Asia/Tokyo",
        "Australia/Sydney",
    }
    
    for _, zone := range zones {
        loc, err := time.LoadLocation(zone)
        if err != nil {
            return fmt.Errorf("loading zone %s: %w", zone, err)
        }
        
        zoneTime := now.In(loc)
        fmt.Printf("%s: %s\n", zone, zoneTime.Format(time.RFC3339))
    }
    
    return nil
}

Working with Durations

Duration Operations

func durationExamples() {
    // Create durations
    d1 := 2 * time.Hour
    d2 := 30 * time.Minute
    d3 := 45 * time.Second
    
    // Combine durations
    total := d1 + d2 + d3
    
    // Get components
    hours := total.Hours()
    minutes := total.Minutes()
    seconds := total.Seconds()
    
    // Parse duration string
    d, err := time.ParseDuration("1h30m")
    if err != nil {
        log.Fatal(err)
    }
}

Best Practices

  1. Use UTC for Storage

    func storeTime() time.Time {
        // Always store times in UTC
        return time.Now().UTC()
    }
    
  2. Handle Time Zones Carefully

    func displayLocalTime(t time.Time, userZone string) (string, error) {
        loc, err := time.LoadLocation(userZone)
        if err != nil {
            return "", fmt.Errorf("invalid timezone: %w", err)
        }
        return t.In(loc).Format(time.RFC1123), nil
    }
    
  3. Use Time Constants

    const (
        dayDuration = 24 * time.Hour
        weekDuration = 7 * dayDuration
        yearDuration = 365 * dayDuration
    )
    
  4. Handle Monotonic Clock

    func measureDuration() time.Duration {
        start := time.Now() // Contains monotonic clock reading
        // ... do work ...
        return time.Since(start) // Uses monotonic clock for accuracy
    }
    

Next Steps