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 }