IsTime verifies whether a given string represents a valid date or not. Hot-path optimisation: a fast-path looksLikeTime check rules out 99%+ of non-time strings before the 20-format time.Parse loop. Without this, every non-time string allocates ~20 *time.parseError objects (~2.4 KB) — when called m
(stringDate string)
| 284 | // non-time string allocates ~20 *time.parseError objects (~2.4 KB) — when |
| 285 | // called millions of times during a load test, that's GBs of GC pressure. |
| 286 | func IsTime(stringDate string) bool { |
| 287 | date := strings.TrimSpace(stringDate) |
| 288 | if date == "" { |
| 289 | return false |
| 290 | } |
| 291 | if secondsFloat, err := strconv.ParseFloat(date, 64); err == nil { |
| 292 | seconds := int64(secondsFloat / 1e9) |
| 293 | nanoseconds := int64(secondsFloat) % 1e9 |
| 294 | expectedTime := time.Unix(seconds, nanoseconds) |
| 295 | currentTime := time.Now() |
| 296 | if currentTime.Sub(expectedTime) < 24*time.Hour && currentTime.Sub(expectedTime) > -24*time.Hour { |
| 297 | return true |
| 298 | } |
| 299 | } |
| 300 | // Cheap byte-prefix gate to avoid the 20-format time.Parse loop on |
| 301 | // obvious non-time inputs. |
| 302 | if !looksLikeTime(date) { |
| 303 | return false |
| 304 | } |
| 305 | for _, dateFormat := range dateFormats { |
| 306 | _, err := time.Parse(dateFormat, date) |
| 307 | if err == nil { |
| 308 | return true |
| 309 | } |
| 310 | } |
| 311 | return false |
| 312 | } |
| 313 | |
| 314 | type SimulationConfig struct { |
| 315 | APITimeout uint64 |