OutputTimeZones();

OutputDateTime(DateTime.Now, "DateTime.Now");
OutputDateTime(DateTime.UtcNow, "DateTime.UtcNow");

OutputTimeZone(TimeZoneInfo.Local, "TimeZoneInfo.Local");
OutputTimeZone(TimeZoneInfo.Utc, "TimeZoneInfo.Utc");

Write("Podaj strefę czasową lub naciśnij Enter, aby wprowadzić strefę EST: ");
string zoneId = ReadLine()!;

if (string.IsNullOrEmpty(zoneId))
{
  zoneId = "Eastern Standard Time";
}

try
{
  TimeZoneInfo otherZone = TimeZoneInfo.FindSystemTimeZoneById(zoneId);
  OutputTimeZone(otherZone,
    $"TimeZoneInfo.FindSystemTimeZoneById(\"{zoneId}\")");

  SectionTitle($"Jaki jest czas w strefie {zoneId}?");

  Write("Wpisz lokalny czas lub naciśnij Enter, aby wprowadzić bieżący: ");
  string? timeText = ReadLine();
  DateTime localTime;
  if ((string.IsNullOrEmpty(timeText)) || 
    (!DateTime.TryParse(timeText, out localTime)))
  {
    localTime = DateTime.Now;
  }

  DateTime otherZoneTime = TimeZoneInfo.ConvertTime(
    dateTime: localTime, sourceTimeZone: TimeZoneInfo.Local,
    destinationTimeZone: otherZone);

  WriteLine("Godzina {0} w strefie {1} odpowiada godzinie {2} w strefie {3}.",
    localTime, GetCurrentZoneName(TimeZoneInfo.Local, localTime),
    otherZoneTime, GetCurrentZoneName(otherZone, otherZoneTime));
}
catch (TimeZoneNotFoundException)
{
  WriteLine($"Strefa {zoneId} nie jest zarejestrowana w systemie.");
}
catch (InvalidTimeZoneException)
{
  WriteLine($"Błędne lub brakujące dane w strefie {zoneId}.");
}
catch (System.Security.SecurityException)
{
  WriteLine("Aplikacja nie ma uprawnień do odczytu informacji o strefach czasowych.");
}
catch (OutOfMemoryException)
{
  WriteLine($"Pamięć niewystarczająca do załadowania informacji o strefie {zoneId}.");
}
