mirror of
https://github.com/TehPeGaSuS/xmasbot.git
synced 2026-07-09 16:25:45 +02:00
118 lines
2.9 KiB
Go
118 lines
2.9 KiB
Go
// This utility validates Time Zone dataset against osm database and tz shapefile,
|
|
// double check the results, sometimes false positives
|
|
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"flag"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"sort"
|
|
"time"
|
|
|
|
"github.com/ugjka/go-tz/v2"
|
|
"github.com/TehPeGaSuS/xmasbot/nyb"
|
|
)
|
|
|
|
// Set target year
|
|
var target = func() time.Time {
|
|
tmp := time.Now().UTC()
|
|
if tmp.Month() == time.December && tmp.Day() < 26 {
|
|
return time.Date(tmp.Year(), time.December, 25, 0, 0, 0, 0, time.UTC)
|
|
}
|
|
return time.Date(tmp.Year()+1, time.December, 25, 0, 0, 0, 0, time.UTC)
|
|
}()
|
|
|
|
var email *string
|
|
var nominatim *string
|
|
|
|
func main() {
|
|
email = flag.String("email", "", "nominatim email")
|
|
nominatim = flag.String("nominatim", "https://nominatim.openstreetmap.org", "nominatim server")
|
|
flag.Parse()
|
|
if *email == "" {
|
|
fmt.Fprintf(os.Stderr, "%s", "provide email with -email flag\n")
|
|
return
|
|
}
|
|
var zones nyb.TZS
|
|
if err := json.Unmarshal(nyb.Zones, &zones); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
//print target to be sure
|
|
fmt.Println("Target:", target)
|
|
sort.Sort(sort.Reverse(zones))
|
|
for _, zone := range zones {
|
|
fmt.Println("Zone:", zone.Offset)
|
|
for _, country := range zone.Countries {
|
|
if len(country.Cities) == 0 {
|
|
remoteOffset, err := timeZone(country.Name, "")
|
|
if err != nil {
|
|
log.Println(country.Name, err)
|
|
} else {
|
|
if remoteOffset != zone.Offset {
|
|
fmt.Printf("%s: Offset mismatch; Local: %v, Remote: %v\n",
|
|
country.Name, zone.Offset, remoteOffset)
|
|
}
|
|
}
|
|
}
|
|
for _, city := range country.Cities {
|
|
remoteOffset, err := timeZone(country.Name, city)
|
|
if err != nil {
|
|
log.Println(city+", "+country.Name, err)
|
|
} else {
|
|
if remoteOffset != zone.Offset {
|
|
fmt.Printf("%s, %s: Offset mismatch; Local: %v, Remote: %v\n",
|
|
city, country.Name, zone.Offset, remoteOffset)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get Timezone Offset
|
|
func timeZone(country, city string) (float64, error) {
|
|
var mapj nyb.NominatimResults
|
|
var err error
|
|
if country == "CAR" || country == "Congo" {
|
|
mapj, err = nyb.NominatimFetcherLong(*email, *nominatim, country, "", "")
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
} else {
|
|
mapj, err = nyb.NominatimFetcher(*email, *nominatim, country+", "+city)
|
|
if mapj != nil && len(mapj) == 0 {
|
|
mapj, err = nyb.NominatimFetcher(*email, *nominatim, city+", "+country)
|
|
}
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
}
|
|
if len(mapj) == 0 {
|
|
return 0, fmt.Errorf("no results")
|
|
}
|
|
|
|
point := tz.Point{
|
|
Lat: mapj[0].Lat,
|
|
Lon: mapj[0].Lon,
|
|
}
|
|
tzid, err := tz.GetZone(point)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
zone, err := time.LoadLocation(tzid[0])
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
offset := zoneOffset(target, zone)
|
|
return float64(offset) / 60 / 60, nil
|
|
}
|
|
|
|
func zoneOffset(target time.Time, zone *time.Location) int {
|
|
_, offset := time.Date(target.Year(), target.Month(), target.Day(),
|
|
target.Hour(), target.Minute(), target.Second(),
|
|
target.Nanosecond(), zone).Zone()
|
|
return offset
|
|
}
|