package main import ( "flag" "fmt" "log" "time" ) func renderYear() string { // Get Current time var ct time.Time var offset int ct, offset = getCurrentTime() // So what the following does is // Add one year to the current time (and call it next year) // Get the start of this year // Get the start of the next year // The New Year ny := ct.AddDate(1, 0, 0) // Get the start of this and next year t1 := startYear(ct.Year(), 1, 1) t2 := startYear(ny.Year(), 1, 1) // Subtract the current year in seconds from next year, in seconds. // This will leave us with the total year in seconds // I do this in case there is a leap-year, // or some dodgy science reason to add 30 seconds to a day. seconds := t2.Sub(t1).Seconds() // From the current time, subtract the start of this year, in seconds. // This should leave us with how far we are into the year, in seconds. tdiff := ct.Sub(t1).Seconds() // Calculate the percentages percentage := calcPercentageFloat64(seconds, tdiff+float64(offset)) // Wrap things up var render string render = renderPercentage(percentage) render = render + fmt.Sprintf(" %.7f%%", percentage) return render } func renderDay() string { // Get Current time var ct time.Time var offset int ct, offset = getCurrentTime() // Get the Start of the Day sd := time.Date(ct.Year(), ct.Month(), ct.Day(), 0, 0, 0, 0, time.UTC) // Get the End of the Day ed := ct.AddDate(0, 0, 1) ed = time.Date(ed.Year(), ed.Month(), ed.Day(), 0, 0, 0, 0, time.UTC) // From the end of the day, subtract the end of the day to get the number of seconds. // Normally this would be 86400, thanks to science this may change. // Think Leap Seconds // // Get the current number of seconds into the day seconds_total := ed.Sub(sd).Seconds() seconds_tmp := ed.Sub(ct).Seconds() seconds_current := seconds_total - seconds_tmp // Calculate the percentages percentage := calcPercentageFloat64(seconds_total, seconds_current+float64(offset)) // Wrap everything up var render string render = renderPercentage(percentage) render = render + fmt.Sprintf(" %.7f%%", percentage) return render } func renderCustom(t1 time.Time, t2 time.Time) string { var ct time.Time var offset int ct, offset = getCurrentTime() seconds := t2.Sub(t1).Seconds() tdiff := ct.Sub(t1).Seconds() percentage := calcPercentageFloat64(seconds, tdiff+float64(offset)) var render string render = renderPercentage(percentage) render = render + fmt.Sprintf(" %.7f%%", percentage) return render } func getCurrentTime() (time.Time, int) { // Declarations var offset int var loc *time.Location var err error // Current Time ct := time.Now() // Get the offset from whatever the system timezone is _, offset = ct.Local().Zone() // Make sure that the time is in UTC, so the offset makes sense loc, err = time.LoadLocation("UTC") if err != nil { log.Fatal(err) } ct = ct.In(loc) // Return things return ct, offset } // displayPercentage Print a string of blocks simulating percentages func renderPercentage(percentage float64) string { var counter int var balk string for percentage > 2 { balk = balk + "▓" percentage = percentage - 2 counter++ } if percentage < 2 { balk = balk + "▒" counter++ } for counter < 50 { balk = balk + "░" counter++ } return balk } // Get the percentages between two float64s func calcPercentageFloat64(full float64, part float64) float64 { var percentage float64 percentage = part / (full / 100) if percentage >= 100 { percentage = percentage - 100 } return percentage } // Get the start of the year. func startYear(year, month, day int) time.Time { return time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC) } func main() { var dayFlag = flag.Bool("day", true, "Display progress of the day.") var yearFlag = flag.Bool("year", true, "Display progress of this year.") var customFlag = flag.Bool("custom", false, "Display a custom range") var customStart = flag.String("custom-start", "", "Start of the custom range") var customStop = flag.String("custom-stop", "", "Start of the custom range") flag.Parse() if *dayFlag { fmt.Println(renderDay()) } if *yearFlag { fmt.Println(renderYear()) } if *customFlag { bt, err := time.Parse(time.RFC3339, *customStart) if err != nil { log.Fatalln("Error parsing start time: ", err) } pa, err := time.Parse(time.RFC3339, *customStop) if err != nil { log.Fatalln("Error parsing stop time: ", err) } fmt.Println(renderCustom(bt, pa)) } }