cronToHuman function

String cronToHuman(
  1. String cron, {
  2. bool utc = false,
})

Convert a cron expression to a human-readable string. Covers common patterns; falls through to the raw cron string for anything else.

The utc option exists for remote triggers which run on servers and always use UTC cron strings -- that path translates UTC -> local for display.

Implementation

String cronToHuman(String cron, {bool utc = false}) {
  final parts = cron.trim().split(RegExp(r'\s+'));
  if (parts.length != 5) return cron;

  final minute = parts[0];
  final hour = parts[1];
  final dayOfMonth = parts[2];
  final month = parts[3];
  final dayOfWeek = parts[4];

  // Every N minutes: */N * * * *
  final everyMinMatch = RegExp(r'^\*/(\d+)$').firstMatch(minute);
  if (everyMinMatch != null &&
      hour == '*' &&
      dayOfMonth == '*' &&
      month == '*' &&
      dayOfWeek == '*') {
    final n = int.parse(everyMinMatch.group(1)!);
    return n == 1 ? 'Every minute' : 'Every $n minutes';
  }

  // Every hour: N * * * *
  if (RegExp(r'^\d+$').hasMatch(minute) &&
      hour == '*' &&
      dayOfMonth == '*' &&
      month == '*' &&
      dayOfWeek == '*') {
    final m = int.parse(minute);
    if (m == 0) return 'Every hour';
    return 'Every hour at :${m.toString().padLeft(2, '0')}';
  }

  // Every N hours: M */N * * *
  final everyHourMatch = RegExp(r'^\*/(\d+)$').firstMatch(hour);
  if (RegExp(r'^\d+$').hasMatch(minute) &&
      everyHourMatch != null &&
      dayOfMonth == '*' &&
      month == '*' &&
      dayOfWeek == '*') {
    final n = int.parse(everyHourMatch.group(1)!);
    final m = int.parse(minute);
    final suffix = m == 0 ? '' : ' at :${m.toString().padLeft(2, '0')}';
    return n == 1 ? 'Every hour$suffix' : 'Every $n hours$suffix';
  }

  // Remaining cases reference hour+minute.
  if (!RegExp(r'^\d+$').hasMatch(minute) || !RegExp(r'^\d+$').hasMatch(hour)) {
    return cron;
  }
  final m = int.parse(minute);
  final h = int.parse(hour);
  final fmtTime = utc ? _formatUtcTimeAsLocal : _formatLocalTime;

  // Daily at specific time: M H * * *
  if (dayOfMonth == '*' && month == '*' && dayOfWeek == '*') {
    return 'Every day at ${fmtTime(m, h)}';
  }

  // Specific day of week: M H * * D
  if (dayOfMonth == '*' &&
      month == '*' &&
      RegExp(r'^\d$').hasMatch(dayOfWeek)) {
    final dayIndex = int.parse(dayOfWeek) % 7;
    String? dayName;
    if (utc) {
      final ref = DateTime.now().toUtc();
      final daysToAdd = (dayIndex - (ref.weekday % 7) + 7) % 7;
      final target = ref.add(Duration(days: daysToAdd));
      final local = DateTime.utc(
        target.year,
        target.month,
        target.day,
        h,
        m,
      ).toLocal();
      dayName = _dayNames[local.weekday % 7];
    } else {
      dayName = _dayNames[dayIndex];
    }
    return 'Every $dayName at ${fmtTime(m, h)}';
  }

  // Weekdays: M H * * 1-5
  if (dayOfMonth == '*' && month == '*' && dayOfWeek == '1-5') {
    return 'Weekdays at ${fmtTime(m, h)}';
  }

  return cron;
}