« Back to Index

[Go Time Formating + Conversions and Comparisons + Stale]

View original Gist on GitHub

Tags: #go #golang #time #formatting #layout #comparison #conversion #stale

1. Go Time Formating.go

// reference time 'layout': Mon Jan 2 15:04:05 -0700 MST 2006
//
// Note:
// - `Jan` : 'first'  position
// - `2`   : 'second' position
// - `15`  : 'third'  position
// - `04`  : 'fourth' position
// - `05`  : 'fifth'  position
// - `2006`: 'sixth'  position
// - `0700`: 'seventh' position
//
// yes, as far as the display of the 'layout' (Mon Jan 2 15:04:05 -0700 MST 2006)
// is concerned, the 'seventh' layout 'position' value (-0700) is shown _before_ the 'sixth' (i.e. 2006)
// 
// Documentation:
// https://golang.org/pkg/time/#Time.Format
//
// Examples:
// https://gobyexample.com/time-formatting-parsing
// https://play.golang.org/p/T_4Kn9BkSDh

now := time.Now()
timestamp := now.Format("20060102_150405")
fmt.Printf("%s_%s", "integralist", timestamp) // integralist_20091110_230000

// integralist_20091110_230000
//
// - `2009`: current year
// - `11`: current month
// - `10`: current day
// - `230000`: current time (11pm/23:00:00)

2. Go Time Conversion and Comparison.go

package main

import (
	"fmt"
	"time"
)

func main() {
	then := time.Date(2009, 01, 17, 20, 34, 58, 651387237, time.UTC).Unix()
	now := time.Now().Unix() // same as time.Unix(now, 0)
	
	fmt.Println(then) // 1232224498
	fmt.Println(now) // 1257894000
	
	then2 := time.Unix(then, 0)
	now2 := time.Unix(now, 0)
  	now3 := time.Now()
	
	fmt.Println(then2) // 2009-01-17 20:34:58 +0000 UTC
	fmt.Println(now2) // 2009-11-10 23:00:00 +0000 UTC
	fmt.Println(now3) // 2009-11-10 23:00:00 +0000 UTC m=+0.000000001
	
	fmt.Println(then2.Before(now2)) // true
	fmt.Println(now2.After(then2)) // true
	fmt.Println(now2.Equal(then2)) // false
	fmt.Println(now2.Equal(now2)) // true
	fmt.Println(now2.Equal(now3)) // true (even though the object has additional m=+0.000000001
  
    // compare negative time.Duration (e.g. -1s) requires converting to int64
    example := time.Duration(-1*time.Second)
    fmt.Printf("%+v\n", int64(example))
  	if (int64(example) < 0) {
      // do something
    }
}

3. Did time occur longer than 1 minute ago.go

package main

import (
	"fmt"
	"time"
)

func main() {
	p := fmt.Println

	now := time.Now() // in play.golang.org this is always 2009-11-10 23:00:00 +0000 UTC m=+0.000000001
	p("now:", now)

    // I purposely set first 'time' event to be 90 seconds (1.5 minutes) ago
	then := time.Date(2009, 11, 10, 23, 01, 30, 00, time.UTC)
	p("then:", then)

	diff := then.Sub(now)
	p("diff:", diff)

	p("diff hours:", diff.Hours())
	p("diff mins:", diff.Minutes()) // yes! the current time is over a minute ago from the original time
	p("diff secs:", diff.Seconds())
	p("diff ns:", diff.Nanoseconds())
}

// Another way using unix timestamps instead of a date time...

package main

import (
	"fmt"
	"time"
)

func main() {
	created := time.Date(2023, 9, 5, 11, 46, 0, 0, time.Local).Unix()

	// Run program when time is 11:51 (so 5 minutes after 11:46) == token expired
	ttl := time.Duration(300) * time.Second // 5 minutes
	diff := time.Now().Add(-ttl).Unix()

	if created < diff {
		fmt.Println("The token has expired")
	} else {
		fmt.Println("The token has not expired")
	}
}

4. Another way to compare time but in reverse.go

package check

import "time"

// Stale validates if the given time is older than the given duration.
//
// EXAMPLE:
// dur is a string like "24h", "10m" or "5s".
func Stale(lastVersionCheck string, dur string) bool {
    // Notice we prefix with a minute. 
    // This means we can use the `.Add()` function 
    // and it'll still work because it'll just _subtract_ the specified duration.
	d, err := time.ParseDuration("-" + dur)
	if err != nil {
		return false
	}

	if t, _ := time.Parse(time.RFC3339, lastVersionCheck); !t.Before(time.Now().Add(d)) {
		return false
	}
	return true
}

5. Countdown timer.go

package main

import (
	"fmt"
	"log"
	"os"
	"time"

	"github.com/theckman/yacspin"
)

func main() {
	spinner, err := yacspin.New(yacspin.Config{
		CharSet:           yacspin.CharSets[9],
		Frequency:         100 * time.Millisecond,
		StopCharacter:     "✓",
		StopColors:        []string{"fgGreen"},
		StopFailCharacter: "✗",
		StopFailColors:    []string{"fgRed"},
		Suffix:            " ",
		Writer:            os.Stdout,
	})
	if err != nil {
		log.Fatal(err)
	}

	secs := 10
	dur := time.Duration(secs) * time.Second
	end := time.Now().Add(dur)
	timeout := time.After(dur)
	ticker := time.NewTicker(1 * time.Second)

	err = spinner.Start()
	if err != nil {
		log.Fatal(err)
	}
	msg := "Checking service availability"
	spinner.Message(msg + generateTimeout(time.Until(end)))

	for {
		select {
		case <-timeout:
			spinner.StopFailMessage(msg)
			spinErr := spinner.StopFail()
			if spinErr != nil {
				log.Fatal(spinErr)
			}
			return
		case t := <-ticker.C:
			spinner.Message(msg + generateTimeout(end.Sub(t)))
		}
	}
}

func generateTimeout(d time.Duration) string {
	remaining := fmt.Sprintf("timeout countdown: %v", d.Round(time.Second))
	return fmt.Sprintf(" (app is being deployed across Fastly's global network | %s)...", remaining)
}