Mercurial > lbo > hg > goe_bot
changeset 67:775f65a3c897
Add second accuracy to reminder parsing
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Mon, 12 Dec 2016 20:51:05 +0100 |
parents | bf69962d10a5 |
children | e6a411adf464 |
files | handler_remind.go |
diffstat | 1 files changed, 36 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/handler_remind.go Mon Dec 12 20:42:32 2016 +0100 +++ b/handler_remind.go Mon Dec 12 20:51:05 2016 +0100 @@ -13,10 +13,10 @@ ) var ( - hhmmRE = regexp.MustCompile(`(\d{1,2}):(\d\d)`) + hhmmRE = regexp.MustCompile(`(\d{1,2}):(\d\d):?(\d\d)?`) durRE = regexp.MustCompile(`\+?(\d+)([smhd])`) - dateRE = regexp.MustCompile(`(\d{4})-(\d\d)-(\d\d) (\d{1,2}):(\d\d)(:..)?`) - dateOfWeekRE = regexp.MustCompile(`(Mo|Di|Mi|Do|Fr|Sa|So) (\d{1,2}):(\d\d)(:..)?`) + dateRE = regexp.MustCompile(`(\d{4})-(\d\d)-(\d\d) (\d{1,2}):(\d\d):?(\d\d)?`) + dateOfWeekRE = regexp.MustCompile(`(Mo|Di|Mi|Do|Fr|Sa|So) (\d{1,2}):(\d\d):?(\d\d)?`) dayOfWeekOff = map[string]time.Weekday{ "So": time.Sunday, @@ -40,14 +40,24 @@ M, _ := strconv.ParseInt(m[2], 10, 32) d, _ := strconv.ParseInt(m[3], 10, 32) h, _ := strconv.ParseInt(m[4], 10, 32) - m, _ := strconv.ParseInt(m[5], 10, 32) + min, _ := strconv.ParseInt(m[5], 10, 32) + sec := int64(0) - t := time.Date(int(y), time.Month(M), int(d), int(h), int(m), 0, 0, time.UTC) + if len(m) >= 7 { + 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] } else if m := dateOfWeekRE.FindStringSubmatch(s); len(m) >= 4 { h, _ := strconv.ParseInt(m[2], 10, 32) min, _ := strconv.ParseInt(m[3], 10, 32) + sec := int64(0) + + if len(m) >= 5 { + sec, _ = strconv.ParseInt(m[4], 10, 32) + } if weekday, ok := dayOfWeekOff[m[1]]; ok { today := now.Weekday() @@ -62,21 +72,34 @@ diff := int(weekday) + int(time.Saturday-today) + 1 pointInTargetDay = now.Add(time.Duration(diff) * 24 * time.Hour) } - return time.Date(pointInTargetDay.Year(), pointInTargetDay.Month(), pointInTargetDay.Day(), int(h), int(min), 0, 0, time.UTC).Add(-time.Duration(*flagLocalOffset) * time.Second), dateOfWeekRE.FindStringIndex(s)[1] + return time.Date(pointInTargetDay.Year(), + pointInTargetDay.Month(), + pointInTargetDay.Day(), + int(h), + int(min), + int(sec), 0, time.UTC).Add(-time.Duration(*flagLocalOffset) * time.Second), dateOfWeekRE.FindStringIndex(s)[1] } else { return time.Unix(0, 0), 0 } } else if m := hhmmRE.FindStringSubmatch(s); len(m) >= 3 { // this has to come after dateRE and dateOfWeekRE, because it's a sub match // Not checking errors as the regex should not let through any non-digits h, _ := strconv.ParseInt(m[1], 10, 32) - m, _ := strconv.ParseInt(m[2], 10, 32) + min, _ := strconv.ParseInt(m[2], 10, 32) + sec := int64(0) + + // seconds, too + if len(m) >= 4 { + sec, _ = strconv.ParseInt(m[3], 10, 32) + } nowH, nowM, nowS := now.Clock() timeOfDay := time.Duration(nowH)*time.Hour + time.Duration(nowM)*time.Minute + time.Duration(nowS)*time.Second midnight := now.Add(-timeOfDay) - // duration since midnight of alert time - // timezone mucking-about because we're using UTC, but users are not - alert := time.Duration(h)*time.Hour + time.Duration(m)*time.Minute - (time.Duration(*flagLocalOffset) * time.Second) + // 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)) if alert > timeOfDay { // later today return midnight.Add(alert), hhmmRE.FindStringIndex(s)[1] @@ -163,8 +186,9 @@ remaining := alertTime.Sub(now) hours := uint64(remaining.Seconds()) / 3600 - minutes := (uint64(remaining.Seconds()+1) % 3600) / 60 - return replyContent{text: fmt.Sprintf("*⏰* Erinnerung #%d in %d:%02d", r.ReminderID, hours, minutes)}, nil + minutes := (uint64(remaining.Seconds()) % 3600) / 60 + seconds := (uint64(remaining.Seconds()) % 60) + return replyContent{text: fmt.Sprintf("*⏰* Erinnerung #%d in %02d:%02d:%02d", r.ReminderID, hours, minutes, seconds)}, nil } func listReminders(ctx context.Context, chatID int64) (replyContent, error) {