package main import ( "encoding/json" "fmt" "net/http" "os" "time" ) func getTime(location string) (time.Time, error) { loc, err := time.LoadLocation(location) if err != nil { return time.Now(), err } return time.Now().In(loc), err } var zoneDir string func loadZoneLocations(path string) []string { var locations []string zoneFiles, _ := os.ReadDir("/usr/share/zoneinfo/" + path) for _, file := range zoneFiles { if file.IsDir() { locations = append(locations, loadZoneLocations(path+"/"+file.Name())...) } else { if _, err := time.LoadLocation((path + "/" + file.Name())[1:]); err != nil { continue } locations = append(locations, (path + "/" + file.Name())[1:]) } } return locations } var runtimeLocations = loadZoneLocations(zoneDir) func mainHandler(w http.ResponseWriter, r *http.Request) { now, err := getTime("UTC") if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprint(w, "Could not get current time") return } fmt.Fprintf(w, now.Format("2006-01-02 15:04:05")) } func dayInYearHandler(w http.ResponseWriter, r *http.Request) { now, err := getTime("UTC") if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprint(w, "Could not get current time") return } fmt.Fprintf(w, "%s%d", string(now.Format("06")[1]), now.YearDay()) } func timeAtZoneHandler(w http.ResponseWriter, r *http.Request) { timezone := r.PathValue("timezone") now, err := getTime(timezone) if err != nil { w.WriteHeader(http.StatusNotFound) fmt.Fprint(w, "Timezone not found") return } fmt.Fprintf(w, now.Format("2006-01-02 15:04:05")) } func ZoneListHandler(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") err := json.NewEncoder(w).Encode(runtimeLocations) if err != nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprint(w, "Could not encode zones") } } func main() { http.HandleFunc("GET /", mainHandler) http.HandleFunc("GET /diy", dayInYearHandler) http.HandleFunc("GET /at/{timezone...}", timeAtZoneHandler) http.HandleFunc("GET /timezones", ZoneListHandler) listen := ":8000" fmt.Println("Listening on " + listen) http.ListenAndServe(listen, nil) }