parseHumanReadableTime function

DateTime? parseHumanReadableTime(
  1. String humanTime, [
  2. List<String> months = months_
])

Parse a human-readable time string

using relative six-month timestamp formatting (e.g., MMM DD HH:MM for recent dates, MMM DD YYYY for older dates)

// 6 months ago, format MMM DD YYYY
print(parseHumanReadableTime('May 20 2000')); // 2000-05-20 00:00:00
// less than 6 months, format MMM DD HH:MM
print(parseHumanReadableTime('Dec 09 16:33')); // 2025-12-09 16:33:00 // now.year is 2025

Implementation

DateTime? parseHumanReadableTime(
  String humanTime, [
  List<String> months = months_,
]) {
  final parts = humanTime.trim().split(' ');
  if (parts.length != 3) return null; // Invalid format
  final [month_, day_, last_, ...] = parts;
  if (!months.contains(month_)) return null;
  final month = months.indexOf(month_) + 1;
  final day = int.tryParse(day_);
  if (day == null || day < 1 || day > 31) return null;

  // Format: "MMM DD YYYY" (e.g., "May 20 2000")
  if (!humanTime.contains(':')) {
    final year = int.tryParse(last_);
    if (year == null || year < 1) return null; // Invalid year
    return DateTime(year, month, day);
  }

  // Format: "MMM DD HH:MM" e.g., "May 20 10:30"
  final timeParts = last_.split(':');
  if (timeParts.length != 2) return null; // Invalid time format

  final hour = int.tryParse(timeParts.first);
  final minute = int.tryParse(timeParts.last);

  if (hour == null ||
      hour < 0 ||
      hour > 23 ||
      minute == null ||
      minute < 0 ||
      minute > 59) {
    return null; // Invalid hour or minute
  }

  final now = DateTime.now().toLocal();
  final mtime = DateTime(now.year, month, day, hour, minute);

  // Check if time is in the future
  final sixMonthsAgo = now.subtract(const Duration(days: 180));
  if (mtime.isBefore(sixMonthsAgo)) {
    return DateTime(now.year - 1, month, day, hour, minute);
  }

  return mtime;
}