HoraTimezone.parse constructor

HoraTimezone.parse(
  1. String input
)

Parses timezone text.

Supported examples:

  • Z, UTC, GMT
  • UTC+08, GMT-05:30
  • +08, -0530, +05:30
  • Common abbreviations in common, such as JST, PST, CET

Implementation

factory HoraTimezone.parse(String input) {
  final normalized = input.trim();
  if (normalized.isEmpty) {
    throw const FormatException('Invalid timezone format: empty input');
  }

  final upper = normalized.toUpperCase();
  if (upper == 'Z' || upper == 'UTC' || upper == 'GMT') {
    return utc;
  }

  final fromCommon = common[upper];
  if (fromCommon != null) {
    return fromCommon;
  }

  var core = upper;
  if (core.startsWith('UTC') || core.startsWith('GMT')) {
    core = core.substring(3).trim();
    if (core.isEmpty) return utc;
  }

  final compact = core.replaceAll(' ', '');
  final match =
      RegExp(r'^([+-])?(\d{1,2})(?::?(\d{2}))?$').firstMatch(compact);
  if (match == null) {
    throw FormatException('Invalid timezone format: $input');
  }

  final sign = match.group(1) == '-' ? -1 : 1;
  final hours = int.parse(match.group(2)!);
  final minutes = match.group(3) == null ? 0 : int.parse(match.group(3)!);

  if (hours > 23 || minutes > 59) {
    throw FormatException(
      'Invalid timezone format: $input. '
      'Hour must be 0..23 and minute must be 0..59.',
    );
  }

  return HoraTimezone.fromMinutes(
    sign * (hours * 60 + minutes),
    name: core.startsWith('+') || core.startsWith('-')
        ? _nameFromOffset(Duration(minutes: sign * (hours * 60 + minutes)))
        : null,
  );
}