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);
        }
Beispiel #2
0
        /**
         * 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);
                    }
                }
            }
        }