package whois import ( "fmt" "strconv" "strings" "time" ) func parseDateAuto(s string) time.Time { s = strings.TrimSpace(s) if s == "" { return time.Time{} } withZoneLayouts := []string{ time.RFC3339Nano, time.RFC3339, "2006-01-02T15:04:05.999999999-0700", "2006-01-02T15:04:05-0700", "2006-01-02 15:04:05 -0700", "2006-01-02 15:04:05 -07:00", "2006-01-02 15:04:05 MST", "2006/01/02 15:04:05 (MST)", "02-Jan-2006 15:04:05 MST", "02-01-2006 15:04:05 -0700", } localLayouts := []string{ "2006-01-02T15:04:05.999999999", "2006-01-02T15:04:05", "2006-01-02 15:04:05", "2006-01-02", "2006/01/02 15:04:05", "2006/01/02", "2006.01.02 15:04:05", "2006.01.02", "02-Jan-2006", "02.01.2006 15:04:05", "02.01.2006", "2.1.2006 15:04:05", "2.1.2006", "02-01-2006 15:04:05", "02-01-2006", "Mon Jan 2 15:04:05 2006", } for _, candidate := range normalizeDateCandidates(s) { for _, l := range withZoneLayouts { if t, err := time.Parse(l, candidate); err == nil { return t.In(time.Local) } } for _, l := range localLayouts { if t, err := time.ParseInLocation(l, candidate, time.Local); err == nil { return t } } } return time.Time{} } func normalizeDateCandidates(s string) []string { seen := map[string]struct{}{} out := make([]string, 0, 6) push := func(v string) { v = strings.TrimSpace(v) if v == "" { return } if _, ok := seen[v]; ok { return } seen[v] = struct{}{} out = append(out, v) } push(s) push(strings.Trim(s, "\"'")) if i := strings.Index(s, " ("); i > 0 && strings.HasSuffix(s, ")") { push(s[:i]) } if strings.HasSuffix(strings.ToUpper(s), " UTC") { push(strings.TrimSpace(s[:len(s)-4]) + " +0000") } if gmt := normalizeGMTOffsetSuffix(s); gmt != "" { push(gmt) } return out } func normalizeGMTOffsetSuffix(s string) string { trimmed := strings.TrimSpace(s) upper := strings.ToUpper(trimmed) idx := strings.LastIndex(upper, " GMT") if idx <= 0 { return "" } base := strings.TrimSpace(trimmed[:idx]) offset := strings.TrimSpace(trimmed[idx+4:]) if len(offset) < 2 { return "" } sign := offset[0] if sign != '+' && sign != '-' { return "" } offset = offset[1:] hourText := offset minText := "00" if p := strings.Index(offset, ":"); p >= 0 { hourText = offset[:p] minText = offset[p+1:] } if hourText == "" { return "" } hour, err := strconv.Atoi(hourText) if err != nil { return "" } mins := 0 if minText != "" { mins, err = strconv.Atoi(minText) if err != nil { return "" } } return fmt.Sprintf("%s %c%02d%02d", base, sign, hour, mins) }