104 lines
2.7 KiB
Go
104 lines
2.7 KiB
Go
|
package remind
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
"time"
|
||
|
"unicode"
|
||
|
)
|
||
|
|
||
|
func formatWhen(timestamp time.Time, loc *time.Location) string {
|
||
|
day := "più tardi"
|
||
|
_, todaym, todayd := time.Now().Date()
|
||
|
_, targetm, targetd := timestamp.Date()
|
||
|
if todaym != targetm || todayd != targetd {
|
||
|
day = "il " + timestamp.In(loc).Format("2/1")
|
||
|
}
|
||
|
|
||
|
return fmt.Sprintf("%s alle %s", day, timestamp.In(loc).Format("15:04:05"))
|
||
|
}
|
||
|
|
||
|
func isSscanfValid(n int, err error) bool {
|
||
|
return err == nil
|
||
|
}
|
||
|
|
||
|
func scanMixedDelay(str string) (bool, time.Time, error) {
|
||
|
remaining := str
|
||
|
now := time.Now()
|
||
|
num := 0
|
||
|
sep := ' '
|
||
|
for len(remaining) > 1 {
|
||
|
_, err := fmt.Sscanf(remaining, "%d%c", &num, &sep)
|
||
|
if err != nil {
|
||
|
return false, now, err
|
||
|
}
|
||
|
dur := time.Duration(num)
|
||
|
switch unicode.ToLower(sep) {
|
||
|
case 's':
|
||
|
dur *= time.Second
|
||
|
case 'm':
|
||
|
dur *= time.Minute
|
||
|
case 'h':
|
||
|
dur *= time.Hour
|
||
|
case 'd':
|
||
|
dur *= time.Hour * 24
|
||
|
default:
|
||
|
return true, now, fmt.Errorf("La durata ha una unità che non conosco, usa una di queste: s (secondi) m (minuti) h (ore) d (giorni)")
|
||
|
}
|
||
|
now = now.Add(dur)
|
||
|
nextIndex := strings.IndexRune(remaining, sep)
|
||
|
remaining = remaining[nextIndex+1:]
|
||
|
}
|
||
|
fmt.Printf("tot: %s", now.Sub(time.Now()))
|
||
|
return true, now, nil
|
||
|
}
|
||
|
|
||
|
func parseDuration(date string, loc *time.Location) (time.Time, error) {
|
||
|
now := time.Now().In(loc)
|
||
|
hour := now.Hour()
|
||
|
min := now.Minute()
|
||
|
sec := now.Second()
|
||
|
day := now.Day()
|
||
|
month := now.Month()
|
||
|
year := now.Year()
|
||
|
dayunspecified := false
|
||
|
isDurationFmt, duration, err := scanMixedDelay(date)
|
||
|
switch {
|
||
|
case isSscanfValid(fmt.Sscanf(date, "%d/%d/%d-%d:%d:%d", &day, &month, &year, &hour, &min, &sec)):
|
||
|
case isSscanfValid(fmt.Sscanf(date, "%d/%d/%d-%d:%d", &day, &month, &year, &hour, &min)):
|
||
|
sec = 0
|
||
|
case isSscanfValid(fmt.Sscanf(date, "%d/%d/%d", &day, &month, &year)):
|
||
|
hour = now.Hour()
|
||
|
min = now.Minute()
|
||
|
sec = now.Second()
|
||
|
case isSscanfValid(fmt.Sscanf(date, "%d:%d:%d", &hour, &min, &sec)):
|
||
|
day = now.Day()
|
||
|
month = now.Month()
|
||
|
year = now.Year()
|
||
|
dayunspecified = true
|
||
|
case isSscanfValid(fmt.Sscanf(date, "%d:%d", &hour, &min)):
|
||
|
day = now.Day()
|
||
|
month = now.Month()
|
||
|
year = now.Year()
|
||
|
sec = 0
|
||
|
dayunspecified = true
|
||
|
case isDurationFmt:
|
||
|
return duration, err
|
||
|
default:
|
||
|
return now, fmt.Errorf("Non capisco quando dovrei ricordartelo!")
|
||
|
}
|
||
|
targetDate := time.Date(year, month, day, hour, min, sec, 0, loc)
|
||
|
if targetDate.Before(now) {
|
||
|
// If day was not specified assume tomorrow
|
||
|
if dayunspecified {
|
||
|
targetDate = targetDate.Add(time.Hour * 24)
|
||
|
} else {
|
||
|
return now, fmt.Errorf("Non posso ricordarti cose nel passato!")
|
||
|
}
|
||
|
}
|
||
|
if targetDate.After(now.Add(reminderMaxDuration)) {
|
||
|
return now, fmt.Errorf("Non credo riuscirei a ricordarmi qualcosa per così tanto")
|
||
|
}
|
||
|
return targetDate, nil
|
||
|
}
|