25

Is there a program or a table that provides the default timezone for every country?

Yes, the US, Canada, & Russia have multiple timezones. (I think every other country has just one.) But it's better to start on the most likely if a country is known rather than just provide a list starting at GMT.

Preferably in C# but I'll take it in anything and convert to C#.

David Thielen
  • 28,723
  • 34
  • 119
  • 193
  • 3
    China. India. Iran. Brazil.... – Andrew Barber Oct 30 '13 at 23:01
  • What is a "default timezone"??? The zone in with the capital of a country? –  Oct 30 '13 at 23:03
  • 1
    And Australia with at least three timezones, and some states, but not all, have daylight saving time, and Indiana in the US which uses at least two time zones. –  Oct 30 '13 at 23:03
  • Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it. –  Oct 30 '13 at 23:04
  • @Andrew, fun fact: China has indeed only one timezone. Crazy, if you think about the size of that country. But Mongolia has two, that should balance it ;) –  Oct 30 '13 at 23:08
  • @AndrewBarber - China, India, & Iran all have a single timezone. – David Thielen Oct 30 '13 at 23:08
  • @elgonzo - I think the capital would be best. But any reasonable one in the country would be fine. – David Thielen Oct 30 '13 at 23:09
  • @MikeW I'm not asking for an opinion on the best library that solves this. I'm just asking if such a solution exists at all. – David Thielen Oct 30 '13 at 23:10
  • @DavidThielen Do they really? I had no idea. I do know Brazil has multiple, though. (3, I think...) – Andrew Barber Oct 30 '13 at 23:10
  • @AndrewBarber That's why I think this would be a good thing to have. For most countries there is one. And for the remainder, most of the population is in just one of the several zones. – David Thielen Oct 30 '13 at 23:12
  • Also, I know France, Australia, Denmark, and the UK also have multiple. In fact, I think France has the most of any. – Andrew Barber Oct 30 '13 at 23:13
  • @David, maybe this helps you: http://stackoverflow.com/questions/7977736/get-timezone-by-country-and-region . If not, perhaps you can stea..., erm... copy the table from Wikipedia (http://en.wikipedia.org/wiki/List_of_time_zones_by_country) and make yourself a text/excel/csv/json/whatever file with the data. –  Oct 30 '13 at 23:14
  • [Related question](http://stackoverflow.com/questions/7977736/get-timezone-by-country-and-region). Not duplicate because you've imagined the concept of a "default" timezone, but the answer may help. – M.Babcock Oct 30 '13 at 23:14
  • [Here's info from Wikipedia](http://en.wikipedia.org/wiki/List_of_time_zones_by_country) And also, I don't even know what a "Default timezone" would be. I don't think you are correct about people being centered in one timezone. – Andrew Barber Oct 30 '13 at 23:14
  • @Andrew: Since Greenland is basically an autonomous country (they are still member of the so-called "Kingdom of Denmark", though), Denmark has only one timezone (UTC+01:00) –  Oct 30 '13 at 23:15
  • @elgonzo OK, so Greenland has 4, then ;) – Andrew Barber Oct 30 '13 at 23:16
  • @Andrew: Greenland has 4? I thought they have 3. But yes, Greenland has indeed 4 timezones... I think the Chinese are jealous about Greenland... –  Oct 30 '13 at 23:17
  • @AndrewBarber for the U.S. & Russia no it's not one timezone for most people, although the East Coast may have close to half for the U.S. But for the rest I think yes. East Coast for Australia, Ontario for Canada, etc. ps I love the Brazil time that's for "a couple of islands." – David Thielen Oct 30 '13 at 23:19
  • This definitely made for a fun discussion – David Thielen Oct 30 '13 at 23:21
  • France? UK? Indonesia? Mexico? Spain? Portugal? And look at the split in time you would have between about half each of the US; Eastern and Pacific. – Andrew Barber Oct 30 '13 at 23:21
  • Antarctica has all timezones. Yay! Wait... that's no country... –  Oct 30 '13 at 23:22
  • @AndrewBarber France has one zone for France itself. UK has one for the British Isles. Spain & Portugal again one timezone for the main country. Indonesia & Mexico you would have to pick a default but Mexico's default is easy. Indonesia you do have a large population in two of them. But again, starting on either has the correct for half and it's one away in the drop-down list for the other half. – David Thielen Oct 30 '13 at 23:26
  • Speaking to myself: No, Antarctica does not have all timezones. But the penguins don't care anyway... –  Oct 30 '13 at 23:33
  • @MikeW: then daylight savings itself does not apply to all states, which complicates things even more... – Qantas 94 Heavy Oct 31 '13 at 04:31
  • @Qantas94Heavy That's what I meant to say, but it didn't quite come out right –  Oct 31 '13 at 04:33
  • @DavidThielen I agree this has been an interesting convo about the topic! :) – Andrew Barber Oct 31 '13 at 13:25

6 Answers6

34

As identified in the comments of the question, you aren't going to be able to get a single time zone for each country. There are just too many cases of countries that have multiple time zones.

What you can do is filter the list of standard IANA/Olson time zones down to those available within a specific country.

One way to do this in C# is with Noda Time:

IEnumerable<string> zoneIds = TzdbDateTimeZoneSource.Default.ZoneLocations
    .Where(x => x.CountryCode == countryCode)
    .Select(x => x.ZoneId);

Pass a two-digit ISO-3166 country code, such as "AU" for Australia. The results are:

"Australia/Lord_Howe",
"Australia/Hobart",
"Australia/Currie",
"Australia/Melbourne",
"Australia/Sydney",
"Australia/Broken_Hill",
"Australia/Brisbane",
"Australia/Lindeman",
"Australia/Adelaide",
"Australia/Darwin",
"Australia/Perth",
"Australia/Eucla"

And if for some reason you'd like Windows time zone identifiers that you can use with the TimeZoneInfo object, Noda Time can map those too:

var source = TzdbDateTimeZoneSource.Default;
IEnumerable<string> windowsZoneIds = source.ZoneLocations
    .Where(x => x.CountryCode == countryCode)
    .Select(tz => source.WindowsMapping.MapZones
        .FirstOrDefault(x => x.TzdbIds.Contains(
                             source.CanonicalIdMap.First(y => y.Value == tz.ZoneId).Key)))
    .Where(x => x != null)
    .Select(x => x.WindowsId)
    .Distinct()

Again, called with "AU" for Australia returns:

"Tasmania Standard Time",
"AUS Eastern Standard Time",
"Cen. Australia Standard Time",
"E. Australia Standard Time",
"AUS Central Standard Time",
"W. Australia Standard Time"

If you're wondering about how reliable this data is, the country to tzid mapping is part of the IANA time zone database itself, in the zone.tab file. The IANA to Windows mapping data comes from the Unicode CLDR supplemental data. It doesn't get any closer to "official" than that.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • Could you try the same for `FO` country code? (`Faroi Islands`) I can find the code in file (`zone.tab`) but in `C#` I am getting no results for this code.. – Alex Jul 01 '16 at 21:32
  • Try the edit I just made. I hadn't taken into account the IDs in the windows mapping are not always the TZDB canonical ones. – Matt Johnson-Pint Jul 02 '16 at 02:33
  • For windows time zone, it does not work for all cases, for example HR. – Umair Apr 28 '19 at 16:07
  • This produces redundant time zones. For example, the United States only has 3-4 time zones but this returns 29 time zones, many of which are the same time zone! – A X Dec 29 '19 at 01:49
  • Hello I found that the code doesn't work for country with code "AX" so here id my take on your solution: IEnumerable ZoneIds = source.ZoneLocations.Where(key => key.CountryCode == countryCode); IReadOnlyDictionary WindowsZoneIDs = source.TzdbToWindowsIds; List Timezones = new(); foreach (var timezone in ZoneIds) { if (WindowsZoneIDs.ContainsKey(timezone.ZoneId)) Timezones.Add(WindowsZoneIDs[timezone.ZoneId]); } var TimezonesDistinct = Timezones.Distinct(); – Abo Ali Nov 08 '22 at 09:42
4

May not be exactly what you are looking for, but try this: http://msdn.microsoft.com/en-us/library/system.timezoneinfo.aspx

To get a specific time zone:

TimeZoneInfo tZone = TimeZoneInfo.FindSystemTimeZoneById("E. Australia Standard Time");

To see the available zones:

ReadOnlyCollection<TimeZoneInfo> zones = TimeZoneInfo.GetSystemTimeZones();

foreach (TimeZoneInfo zone in zones)
{
     Console.WriteLine(zone.Id);
}
JuStDaN
  • 449
  • 2
  • 7
4

In order to get CountryCode -> TimeZoneInfo mapping i used answer from Matt (2nd code snippet), but it didn't work for many cases. Found simpler and more reliable solution (using same Noda Time): TzdbDateTimeZoneSource.Default.WindowsMapping.MapZones basically has all the data.

Code sample:

Dictionary<string, TimeZoneInfo> GetIsoToTimeZoneMapping()
{
    var source = TzdbDateTimeZoneSource.Default;

    return source.WindowsMapping.MapZones
        .GroupBy(z => z.Territory)
        .ToDictionary(grp => grp.Key, grp => GetTimeZone(source, grp));
}

 TimeZoneInfo GetTimeZone(TzdbDateTimeZoneSource source, IEnumerable<MapZone> territoryLocations)
{
    var result = territoryLocations
        .Select(l => l.WindowsId)
        .Select(TimeZoneInfo.FindSystemTimeZoneById)
        //pick timezone with the minimum offset
        .Aggregate((tz1, tz2) => tz1.BaseUtcOffset < tz2.BaseUtcOffset ? tz1 : tz2);

    return result;
}
0

Latest Windows versions contain file %WINDIR%\Globalization\Time Zone\timezoneMapping.xml which maps Olson to Windows time zone, you can query it as regular XML. I don't know but maybe C# already has a class which works with it.

coder
  • 8,346
  • 16
  • 39
  • 53
0

I've used the per-country default timezones that Microsoft uses for Windows when a user first logs in. They list them at https://learn.microsoft.com/en-us/windows-hardware/manufacture/desktop/default-time-zones.

I also created a script which parses that table out into a JSON file at https://github.com/rahulgi/default-timezones.

Rahul Gupta-Iwasaki
  • 1,683
  • 2
  • 21
  • 39
0

Some countries have more as one timezone for example russia.

In my solution i use NodaTime if you have a longitude information available i select the best timezone for this country.

var countryName = "Russia";
var longitude = 40.332206;

var zones = TzdbDateTimeZoneSource.Default.ZoneLocations.Where(x => x.CountryName == countryName).AsQueryable();
if (!double.IsNaN(longitude))
{
    zones = zones.OrderBy(o => this.Distance(o.Latitude, longitude, o.Latitude, o.Longitude, DistanceUnit.Kilometer));
}
var bestZone = zones.FirstOrDefault();
var dateTimeZone = TzdbDateTimeZoneSource.Default.ForId(bestZone.ZoneId);

var newTime = DateTime.UtcNow.AddSeconds(dateTimeZone.MaxOffset.Seconds);

Calculate distance of geo coordinates

public enum DistanceUnit { StatuteMile, Kilometer, NauticalMile };

private double Distance(double lat1, double lon1, double lat2, double lon2, DistanceUnit unit)
{
    double rlat1 = Math.PI * lat1 / 180;
    double rlat2 = Math.PI * lat2 / 180;
    double theta = lon1 - lon2;
    double rtheta = Math.PI * theta / 180;
    double dist =
        Math.Sin(rlat1) * Math.Sin(rlat2) + Math.Cos(rlat1) *
        Math.Cos(rlat2) * Math.Cos(rtheta);
    dist = Math.Acos(dist);
    dist = dist * 180 / Math.PI;
    dist = dist * 60 * 1.1515;

    switch (unit)
    {
        case DistanceUnit.Kilometer:
            return dist * 1.609344;
        case DistanceUnit.NauticalMile:
            return dist * 0.8684;
        default:
        case DistanceUnit.StatuteMile: //Miles
            return dist;
    }
}
live2
  • 3,771
  • 2
  • 37
  • 46