Giter Club home page Giter Club logo

timezonemapper's Introduction

Logo TimeZoneMapper

Build Status Nuget version

Library for mapping *N*X TimeZone ID's (e.g. Europe/Amsterdam) to .Net's TimeZoneInfo classes. This mapping is one-way since, for example, Europe/Amsterdam maps to W. Europe Standard Time but W. Europe Standard Time could map to Europe/Stockholm or Arctic/Longyearbyen just as easily.

The library provides a simple static TimeZoneMap object that exposes 3 types of mappers, each described below under usage. The project is kept up-to-date with the latest mapping information as much as I can, but TimeZoneMapper can use the latest mapping information available online completely transparently.

TimeZoneMapper is available as a NuGet package and comes with (basic) documentation in the form of a Windows Helpfile (.chm).

Usage

The most basic example is as follows:

TimeZoneInfo tzi = TimeZoneMap.DefaultValuesTZMapper.MapTZID("Europe/Amsterdam");

This uses the static TimeZoneMap.DefaultValuesTZMapper to map the string to the specific TimeZoneInfo. The DefaultValuesTZMapper object uses a built-in resource containing the mapping information. If you want more up-to-date mapping information, you can use the OnlineValuesTZMapper.

TimeZoneInfo tzi = TimeZoneMap.OnlineValuesTZMapper.MapTZID("Europe/Amsterdam");

This will retrieve the information from the Unicode Consortium's latest CLDR data. There is a catch though: what if, for some reason, this information is not available (for example an outbound HTTP request is blocked, the data is not available (HTTP status 404 for example) or the data is corrupt (invalid XML for some reason))? Well, simple, we just use the OnlineWithFallbackValuesTZMapper!

TimeZoneInfo tzi = TimeZoneMap.OnlineWithFallbackValuesTZMapper.MapTZID("Europe/Amsterdam");

This will try to download the CLDR data from the Unicode Consortium and when that, for some reason fails, it uses the built-in values as fallback.

Note that an HTTP request will be made only once for as long as the TimeZoneMapper is around (usually the lifetime of the application). Also note that the TimeZoneMapper is case-insensitive; the TimeZone ID Europe/Amsterdam works just as well as EUROPE/AMSTERDAM or eUrOpE/AmStErDaM.

Finally, when you want control over the actual CLDR data and where it is stored, how you cache it etc. you can use the CustomValuesTZMapper. Be sure to add the TimeZoneMapper.TZMappers namespace if you want to use this class. This class' constructor has 3 overloads demonstrated below:

// Overload 1: CustomValuesTZMapper(string, Encoding)

// Load XML from file
var mapper = new CustomValuesTZMapper("myfile.xml", Encoding.UTF8);
TimeZoneInfo tzi = mapper.MapTZID("Europe/Amsterdam");
// Overload 2: CustomValuesTZMapper(string)
    
// Get XML from database, cache, online resource, file, etc. or, in this case, "hard-coded":
string cldrdata = "<supplementalData><windowsZones><mapTimezones otherVersion=\"xyz\" typeVersion=\"zyx\">..."; 
var mapper = new CustomValuesTZMapper(cldrdata);
TimeZoneInfo tzi = mapper.MapTZID("Europe/Amsterdam");
// Overload 3: CustomValuesTZMapper(Stream)

// Use a Stream
using (var mystream = new GZipStream(File.OpenRead("myfile.gz"), CompressionMode.Decompress))
{
    var mapper = new CustomValuesTZMapper(mystream);
    TimeZoneInfo tzi = mapper.MapTZID("Europe/Amsterdam");
}

All you need to do is ensure the data you supply to the CustomValuesTZMapper is valid CLDR data (see this example)

Future

I will try to update the built-in resource every now-and-then.


Icon made by deviantdark, licensed by Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0) (Archived page).

timezonemapper's People

Contributors

ghost1face avatar robthree avatar sandrock avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

timezonemapper's Issues

Handle unknown timezones

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---> System.TimeZoneNotFoundException: The time zone ID 'Libya Standard Time' was not found on the local computer.
   at System.TimeZoneInfo.FindSystemTimeZoneById(String id)
   at TimeZoneMapper.TZMappers.BaseTZMapper.<.ctor>b__2(XElement n, String t)
   ...

We should handle a TimeZoneNotFoundException and just NOT provide a mapping for it. The TimeZone that caused this exception (Libya Standard Time) is not in .Net by default but installed by an update. However, other (new) timezones defined by the CLDR could ofcourse cause the same kind of problem(s). We should create a TryFindSystemTimeZoneById().

Missing America/Indiana/Indianapolis from default timezone map

Hi! Thank you for the great library, very useful!

I recently noticed that the Timezone ID "America/Indiana/Indianapolis" is missing from the default map xml. I'm aware how to add it with a custom XML or I can change to "America/Indianapolis" which is present in the default map so no huge issue at all, just wanted to let you know.

Missing plattform independency (using a Mac)

Your lib is great, thanks for that. However, it does not support the Mac.

I am using the Visual Studio community edition for the Mac. The following code always runs into the catch part with a KeyNotFoundException "The given key was not present in the dictionary".

Please consider to add .NET Core support on the Mac - because it already works on .NET Core (with warnings though...).

public static T3Z3ValidationResult ValidateTimeZone(string tz) {

        TimeZoneInfo tzi;

        try
        {
            tzi = TimeZoneMap.DefaultValuesTZMapper.MapTZID(tz);

            return new T3Z3ValidationResult() { TimeZoneInfo = tzi, IsValid = true };
        }
        catch
        {
            return new T3Z3ValidationResult() { TimeZoneInfo = null, IsValid = false };
        }
    }

Even when I use a simple timezone like "Europe/Berlin".

Issue with GMT-[hours] zones

Example:

    TimeZoneInfo tzi = TimeZoneMap.DefaultValuesTZMapper.MapTZID("Etc/GMT-11");
    Console.WriteLine(tzi.DisplayName);

Result:

(UTC+11:00) Solomon Is., New Caledonia

+11 instead -11.

Duplicate key

The Unicode cosortium released a new CLDR file (2016i) which contains a duplicate key (Antarctica/Casey):

<!-- (UTC+11:00) Solomon Is., New Caledonia -->
<mapZone other="Central Pacific Standard Time" territory="AQ" type="Antarctica/Casey"/>

<!-- (UTC+08:00) Perth -->
<mapZone other="W. Australia Standard Time" territory="AQ" type="Antarctica/Casey"/>

This has been reported. If you're using the OnlineValuesTZMapper you may want to use a fallback mechanism or even just an offline copy of a correct CLDR file.

This is also why the current build fails.

"America/Indiana/Indianapolis"

According to http://en.wikipedia.org/wiki/America/Indiana/Indianapolis, the timezone "America/Indiana/Indianapolis" is in the IANA database, but each call in TimeZoneMapper throws KeyNotFoundException:

TimeZoneMap.OnlineWithFallbackValuesTZMapper.MapTZID(timezone);
TimeZoneMap.DefaultValuesTZMapper.MapTZID(timezone);

What is the recommended way to resolve any timezone in the IANA database to it's Windows Timezone?

missing timezones

These timezones are not mapped:
Chile/Continental
Europe/Istanbul
Asia/Kolkata
Asia/Hebron

Why territory 001 for Europe/Berlin )and not DE?

Hi,

great mapping between Windows and IANA time zones, thanks a lot!

Is there any reason why Europe/Berlin has not territory "DE"?

		**<mapZone other="W. Europe Standard Time" territory="001" type="Europe/Berlin"/>**
		<mapZone other="W. Europe Standard Time" territory="AD" type="Europe/Andorra"/>
		<mapZone other="W. Europe Standard Time" territory="AT" type="Europe/Vienna"/>
		<mapZone other="W. Europe Standard Time" territory="CH" type="Europe/Zurich"/>
		<mapZone other="W. Europe Standard Time" territory="DE" type="Europe/Berlin Europe/Busingen"/>

From IANA tz:
DE +5230+01322 Europe/Berlin Germany (most areas)

.Net Standard compatibility

Hi, this is a great library for mapping UNIX timezones to Windows. Would you be able to make a release that supports .Net Standard please?

timezone name not found

Calcutta name changed officially to Kolkata.
Timezone service lookup based on lat/lon returns "Asia/Kolkata"

TimeZoneMap.OnlineWithFallbackValuesTZMapper.MapTZID("Asia/Kolkata") fails - The given key was not present in the dictionary.

TimeZoneMap.OnlineWithFallbackValuesTZMapper.MapTZID("Asia/Calcutta") works - but it is the old city name that is not current.

`TimeZoneMap.DefaultValuesTZMapper` throws exception

Nuget version: 1.2.31
OS: Manjaro Linux, Windows 10
Framework : net462

Calling TimeZoneMap.DefaultValuesTZMapper throws the following exception:

{System.TimeZoneNotFoundException: The time zone ID 'Yukon Standard Time' was not found on the local computer.
   at System.TimeZoneInfo.FindSystemTimeZoneById(String id)
   at TimeZoneMapper.TZMappers.BaseTZMapper.TryGetTimeZone(String id, Boolean throwOnNonExisting)
   at TimeZoneMapper.TZMappers.BaseTZMapper.<>c__DisplayClass13_0.<.ctor>b__2(XElement n, String t)
   at System.Linq.Enumerable.<SelectManyIterator>d__23`3.MoveNext()
   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__1.MoveNext()
   at TimeZoneMapper.TZMappers.LinqExtensions.ToDictionarySafe[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer, Boolean throwOnDuplicateKey)
   at TimeZoneMapper.TZMappers.BaseTZMapper..ctor(String xmldata, Boolean throwOnDuplicateKey, Boolean throwOnNonExisting)
   at TimeZoneMapper.TZMappers.DefaultValuesTZMapper..ctor()
   at TimeZoneMapper.TimeZoneMap.<>c.<.cctor>b__9_0()
   at System.Lazy`1.CreateValue()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Lazy`1.get_Value()
   at TimeZoneMapper.TimeZoneMap.get_DefaultValuesTZMapper()}
    [System.TimeZoneNotFoundException]: {System.TimeZoneNotFoundException: The time zone ID 'Yukon Standard Time' was not found on the local computer.
   at System.TimeZoneInfo.FindSystemTimeZoneById(String id)
   at TimeZoneMapper.TZMappers.BaseTZMapper.TryGetTimeZone(String id, Boolean throwOnNonExisting)
   at TimeZoneMapper.TZMappers.BaseTZMapper.<>c__DisplayClass13_0.<.ctor>b__2(XElement n, String t)
   at System.Linq.Enumerable.<SelectManyIterator>d__23`3.MoveNext()
   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
   at System.Linq.OrderedEnumerable`1.<GetEnumerator>d__1.MoveNext()
   at TimeZoneMapper.TZMappers.LinqExtensions.ToDictionarySafe[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer, Boolean throwOnDuplicateKey)
   at TimeZoneMapper.TZMappers.BaseTZMapper..ctor(String xmldata, Boolean throwOnDuplicateKey, Boolean throwOnNonExisting)
   at TimeZoneMapper.TZMappers.DefaultValuesTZMapper..ctor()
   at TimeZoneMapper.TimeZoneMap.<>c.<.cctor>b__9_0()
   at System.Lazy`1.CreateValue()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Lazy`1.get_Value()
   at TimeZoneMapper.TimeZoneMap.get_DefaultValuesTZMapper()}
    HResult: -2146233088
    InnerException: null
    Message: "The time zone ID 'Yukon Standard Time' was not found on the local computer."
    Source: "mscorlib"

This is visible in the latest appveyor build.

The issue does not occur with nuget version 1.2.30.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.