changeset 70:43506af70483

Do proper timezone handling for reminders.
author Lewin Bormann <lbo@spheniscida.de>
date Tue, 27 Jun 2017 21:38:50 +0200
parents 683193cb3194
children 8f0bc3d2675d
files handler_remind.go main.go sql/remind.go
diffstat 3 files changed, 19 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/handler_remind.go	Mon Dec 12 21:28:53 2016 +0100
+++ b/handler_remind.go	Tue Jun 27 21:38:50 2017 +0200
@@ -33,7 +33,7 @@
 // Returns the parsed time (t.IsZero() if parsing was unsuccessful), and the index of the first non-time
 // character in the string
 func parseReminderString(s string) (time.Time, int) {
-	now := time.Now()
+	now := time.Now().In(localTZ)
 
 	if m := dateRE.FindStringSubmatch(s); len(m) >= 6 {
 		y, _ := strconv.ParseInt(m[1], 10, 32)
@@ -47,9 +47,8 @@
 			sec, _ = strconv.ParseInt(m[6], 10, 32)
 		}
 
-		t := time.Date(int(y), time.Month(M), int(d), int(h), int(min), int(sec), 0, time.UTC)
-
-		return t.Add(-time.Duration(*flagLocalOffset) * time.Second), dateRE.FindStringIndex(s)[1]
+		t := time.Date(int(y), time.Month(M), int(d), int(h), int(min), int(sec), 0, localTZ)
+		return t, dateRE.FindStringIndex(s)[1]
 	} else if m := dateOfWeekRE.FindStringSubmatch(s); len(m) >= 4 {
 		h, _ := strconv.ParseInt(m[2], 10, 32)
 		min, _ := strconv.ParseInt(m[3], 10, 32)
@@ -77,7 +76,7 @@
 				pointInTargetDay.Day(),
 				int(h),
 				int(min),
-				int(sec), 0, time.UTC).Add(-time.Duration(*flagLocalOffset) * time.Second), dateOfWeekRE.FindStringIndex(s)[1]
+				int(sec), 0, localTZ), dateOfWeekRE.FindStringIndex(s)[1]
 		} else {
 			return time.Unix(0, 0), 0
 		}
@@ -98,8 +97,7 @@
 		// duration since midnight of alert time. Converting to UTC for database storage
 		alert := (time.Duration(h)*time.Hour +
 			time.Duration(min)*time.Minute +
-			time.Duration(sec)*time.Second -
-			(time.Duration(*flagLocalOffset) * time.Second))
+			time.Duration(sec)*time.Second)
 
 		if alert > timeOfDay { // later today
 			return midnight.Add(alert), hhmmRE.FindStringIndex(s)[1]
@@ -151,7 +149,7 @@
 
 	// saving the time here, before alert time calculation, so "+10m" will be displayed as such, not as "0:09" because
 	// it technically is 9.999999 minutes.
-	now := time.Now()
+	now := time.Now().In(localTZ)
 
 	// restStart is the index of the first character of the remaining text
 	alertTime, restStart := parseReminderString(strings.Trim(msg.Text, " "))
@@ -212,7 +210,7 @@
 	buttons := make([][]inlineKeyboardButton, len(rms))
 
 	for i := range rms {
-		t := rms[i].Due.Add(time.Duration(*flagLocalOffset) * time.Second)
+		t := rms[i].Due.In(localTZ)
 		var date string
 
 		if t.Sub(time.Now()) < 24*time.Hour {
--- a/main.go	Mon Dec 12 21:28:53 2016 +0100
+++ b/main.go	Tue Jun 27 21:38:50 2017 +0200
@@ -31,11 +31,22 @@
 	flagDBHost   = flag.String("dbhost", "/var/run/postgresql/", "Socket path or address for database")
 
 	flagLocalOffset = flag.Int("tz_off", 3600, "Seconds offset from UTC")
+	flagTZ          = flag.String("tz", "Europe/Berlin", "Timezone of clients")
 
 	// SHARED VARIABLES
 	backend *sql.Storage
+
+	localTZ *time.Location
 )
 
+func init() {
+	var err error
+	localTZ, err = time.LoadLocation(*flagTZ)
+	if err != nil {
+		localTZ = time.FixedZone("local", *flagLocalOffset)
+	}
+}
+
 func setUpDatabase() error {
 	c := sql.MakeConnectParams(*flagDatabase, *flagDBUser, *flagDBPass, *flagDBHost, *flagDBPort)
 	db, err := sql.NewStorage(c)
--- a/sql/remind.go	Mon Dec 12 21:28:53 2016 +0100
+++ b/sql/remind.go	Tue Jun 27 21:38:50 2017 +0200
@@ -138,7 +138,7 @@
 // Takes a reminder, inserts it, and returns a reminder with the fields of rm and additionally ReminderID set.
 func (r Reminders) InsertReminder(rm Reminder) (Reminder, error) {
 	if stmt, ok := r.db.prepared[insertReminder]; ok {
-		row := stmt.QueryRow(pq.FormatTimestamp(rm.Due), rm.Text, rm.Owner, rm.ChatID, rm.ReplyTo)
+		row := stmt.QueryRow(pq.FormatTimestamp(rm.Due.In(time.UTC)), rm.Text, rm.Owner, rm.ChatID, rm.ReplyTo)
 
 		var id uint