Well, you can't do it just with a country code - you need a time zone. In some countries there are multiple time zones.
Once you have a time zone as a DateTimeZone
(either via a BCL TimeZoneInfo
or from the TZDB time zone provider) you would:
- Construct a
LocalDateTime
from the value you've got, e.g. using LocalDateTimePattern
to parse text
- Call
LocalDateTime.InZoneLeniently
(or similar - more about that in a moment) to get the ZonedDateTime
- Use
WithZone(DateTimeZone.Utc)
to convert it to a UTC-based ZonedDateTime
The part about InZoneLeniently
, InZoneStrictly
or InZone(DateTimeZone, ZoneLocalMappingResolver)
is because a local date and time might occur twice or not at all, around DST transitions. See the user guide for more details on that.
Sample code:
using System;
using NodaTime;
using NodaTime.Text;
class Test
{
static void Main()
{
var text = "Feb 5, 2016 7:45 PM";
var zone = DateTimeZoneProviders.Tzdb["Europe/Istanbul"];
var pattern = LocalDateTimePattern.CreateWithInvariantCulture("MMM d, uuuu h:mm tt");
var local = pattern.Parse(text).Value;
var zoned = local.InZoneStrictly(zone);
var utc = zoned.WithZone(DateTimeZone.Utc);
Console.WriteLine(utc); // 2016-02-05T17:45:00 UTC (+00)
}
}
Now, for finding the time zone from a country code, the TZDB (IANA) database comes with information about time zone locations, which is exposed in Noda Time. For example, if you have an ISO-3166 2-letter country code, you could use:
using NodaTime;
using NodaTime.TimeZones;
using System.Linq;
...
var code = "TR"; // Turkey
var zoneId = TzdbDateTimeZoneSource.Default.ZoneLocations
.Single(loc => loc.CountryCode == code)
.ZoneId;
var zone = DateTimeZoneProviders.Tzdb[zoneId];
The Single
call will fail if there's more than one zone with the given country code (or none).
If you're going to frequently look up the zones, you might want to build a dictionary:
var zonesByCountryCode = TzdbDateTimeZoneSource.Default
.ZoneLocations
.GroupBy(loc => loc.CountryCode)
.Where(g => g.Count() == 1) // Single-zone countries only
.ToDictionary(g => g.Key, g => g.First());