public void ReadDatabase() { bool generateList; generateList = true; // First, get all of the data from the tz db List<string[]> links = new List<string[]>(); List<PublicDomain.TzDatabase.TzRule> rules = new List<PublicDomain.TzDatabase.TzRule>(); List<PublicDomain.TzDatabase.TzZone> zones = new List<PublicDomain.TzDatabase.TzZone>(); TzDatabase.ReadDatabase(TzDatabase.TzDatabaseDirectory, rules, zones, links); // Now, get all of the tab files Dictionary<string, Iso3166> map = TzDatabase.ParseIso3166Tab(TzDatabase.Iso3166TabFile); List<PublicDomain.TzTimeZone.TzZoneDescription> items = TzDatabase.ParseZoneTab(TzDatabase.ZoneTabFile); // Build up the rule lists based on names Dictionary<string, List<PublicDomain.TzDatabase.TzRule>> ruleList = new Dictionary<string, List<PublicDomain.TzDatabase.TzRule>>(); foreach (PublicDomain.TzDatabase.TzRule rule in rules) { if (!ruleList.ContainsKey(rule.RuleName)) { ruleList[rule.RuleName] = new List<PublicDomain.TzDatabase.TzRule>(); } ruleList[rule.RuleName].Add(rule); } // Build up the zone lists based on names Dictionary<string, List<PublicDomain.TzDatabase.TzZone>> zonesList = new Dictionary<string, List<PublicDomain.TzDatabase.TzZone>>(); foreach (PublicDomain.TzDatabase.TzZone zone in zones) { if (!zonesList.ContainsKey(zone.ZoneName)) { zonesList[zone.ZoneName] = new List<PublicDomain.TzDatabase.TzZone>(); } zonesList[zone.ZoneName].Add(zone); } Dictionary<string, PublicDomain.TzTimeZone.TzZoneInfo> zoneList = new Dictionary<string, PublicDomain.TzTimeZone.TzZoneInfo>(); List<PublicDomain.TzDatabase.TzZone> dataZones; List<PublicDomain.TzDatabase.TzRule> dataRules; foreach (string zoneKey in zonesList.Keys) { zonesList.TryGetValue(zoneKey, out dataZones); dataRules = null; // Go through each zone and get the associated rules if (dataZones != null) { dataRules = new List<PublicDomain.TzDatabase.TzRule>(); foreach (PublicDomain.TzDatabase.TzZone dataZone in dataZones) { if (dataZone.HasRules()) { ArrayUtilities.AppendList<PublicDomain.TzDatabase.TzRule>(dataRules, ruleList[dataZone.RuleName]); } else if (ConversionUtilities.IsStringATimeSpan(dataZone.RuleName)) { TimeSpan timedRule = DateTimeUtlities.ParseTimeSpan(dataZone.RuleName, DateTimeUtlities.TimeSpanAssumption.Hours); dataRules.Add( new PublicDomain.TzDatabase.TzRule( dataZone.RuleName, int.MinValue, int.MaxValue, Month.January, 1, null, TimeSpan.Zero, PublicDomain.TzDatabase.TimeModifier.LocalWallTime, timedRule, null, null ) ); } } } //get the lat of this zone for DST usage bool isLatitudeNorth = true; foreach (PublicDomain.TzTimeZone.TzZoneDescription item in items) { if (item.ZoneName == zoneKey) { isLatitudeNorth = item.Location.IsLatitudeNorth; break; } } zoneList[zoneKey] = new TzTimeZone.TzZoneInfo(zoneKey, dataZones, dataRules, isLatitudeNorth); } // Finally, clone the links foreach (string[] pieces in links) { // Find the time zone this is a link to TzTimeZone.TzZoneInfo linkedTo = zoneList[pieces[1]]; TzTimeZone.TzZoneInfo link = linkedTo.Clone(pieces[2]); zoneList[link.ZoneName] = link; } // Now, get the zone list as a List List<PublicDomain.TzTimeZone.TzZoneInfo> tzzones = new List<PublicDomain.TzTimeZone.TzZoneInfo>(); foreach (string key in zoneList.Keys) { tzzones.Add(zoneList[key]); } // Sort it by zone name tzzones.Sort(delegate(PublicDomain.TzTimeZone.TzZoneInfo x, PublicDomain.TzTimeZone.TzZoneInfo y) { return x.ZoneName.CompareTo(y.ZoneName); }); // Print out the zone names //tzzones.ForEach(delegate(PublicDomain.TzTimeZone.TzZoneInfo z) //{ // Console.WriteLine(z.ZoneName); //}); CreateTzCode(generateList, tzzones, 3); }
/** * Override TzTimeZone.GetTimeZone monstrocity that adds 5-6 seconds * to static loading. Load from bundled zoneinfo distribution. */ public static void InitTimeZones(string file) { // Extract line array from bundled zoneinfo Assembly asm = Assembly.GetExecutingAssembly(); Stream stream = Unzip(asm.GetManifestResourceStream(file + ".gz")); int len = (int) stream.Length; // int overflow in [1,2]gb for utf-8 stream byte[] buffer = new byte[len]; stream.Read(buffer, 0, len); buffer = Encoding.Convert(Encoding.ASCII, Encoding.UTF8, buffer); string s = Encoding.UTF8.GetString(buffer, 0, len); string[] ss = s.Split(new char[] {'\n'}); // Python generated with unix linebreaks. obviously. // init datastructures for ReadDatabase call List<TzDatabase.TzRule> rule_list = new List<TzDatabase.TzRule>(); List<TzDatabase.TzZone> zone_list = new List<TzDatabase.TzZone>(); List<string[]> links_list = new List<string[]>(); // Read database TzDatabase.ReadDatabaseFile(ss, rule_list, zone_list, links_list); // zone_name -> Zone mapping Dictionary<string,Zone> name_zone_dict = new Dictionary<string,Zone>(); // iterate over all zones to gather all entries under common key foreach (TzDatabase.TzZone zone in zone_list) { string zone_name = zone.ZoneName; string rule_name = zone.RuleName; if (!name_zone_dict.ContainsKey(zone_name)) { name_zone_dict.Add(zone_name, new Zone(zone_name)); } name_zone_dict[zone_name].zones.Add(zone); // iterate over all rules to see if they match this zone foreach (TzDatabase.TzRule rule in rule_list) { if (rule.RuleName == rule_name) { name_zone_dict[zone_name].rules.Add(rule); } } } // instantiate all timezones foreach (KeyValuePair<string,Zone> pair in name_zone_dict) { string zone_name = pair.Value.zone_name; List<TzDatabase.TzZone> zones = pair.Value.zones; List<TzDatabase.TzRule> rules = pair.Value.rules; TzTimeZone.TzZoneInfo tzzone = new TzTimeZone.TzZoneInfo(zone_name, zones, rules); if (!s_zones.ContainsKey(zone_name)) { s_zones.Add(zone_name, tzzone); } // add links foreach (string[] link in links_list) { string from = link[1]; string to = link[2]; if ((from == zone_name) && (!s_zones.ContainsKey(to))) { tzzone = new TzTimeZone.TzZoneInfo(to, zones, rules); s_zones.Add(to, tzzone); } } } }