Ejemplo n.º 1
0
        /// <summary>
        /// Parses TimeZones and Rules from the files in the provided
        /// Olson/TZ Database directory. The directory provided must be a valid TZ Database.
        /// </summary>
        /// <param name="directory">The valid directory to parse Rules and TimeZones from.</param>
        public void ReadTZDirectory()
        {
            try
            {
                // Mapping from TZname to: id, Ccode, Cname.
                var tzNameToInfo = ReadTabFiles();

                TimeZones.BeginLoadData();
                Rules.BeginLoadData();
                Leaps.BeginLoadData();

                foreach (OlsonFileInfo file in _olsonFiles.GetConsumingEnumerable())
                {
                    if (!file.IsTabFile)
                    {
                        RaiseFileParsing(file);
                        string[] lines = File.ReadAllLines(file.FullName);

                        // Process items.
                        for (int i = 0; i < lines.Length; i++)
                        {
                            string line = lines[i].TrimStart();

                            if (!isCommentNullOrWhiteSpace(line))
                            {
                                string[] fields = ParseFields(line);

                                switch (fields[0])
                                {
                                case Rule.RULE_NAME:
                                {
                                    short from = Rule.ParseStartYear(fields[Rule.FromIndex]);
                                    short to   = Rule.ParseEndYear(fields[Rule.ToIndex], from);

                                    if (from > _curYear || to < _curYear)
                                    {
                                        continue;
                                    }

                                    // No parsing necessary.
                                    string name = fields[Rule.NameIndex];

                                    var rule = Rules.NewRow();
                                    rule[1] = name;
                                    rule[2] = Rule.ParseBias(fields[Rule.SaveIndex]);
                                    rule[3] = from;
                                    rule[4] = to;
                                    rule[5] = Rule.ParseMonth(fields[Rule.InIndex]);
                                    rule[6] = fields[Rule.OnIndex];
                                    rule[7] = Rule.ParseTime(fields[Rule.AtIndex]);
                                    rule[8] = Rule.ParseTimeType(ref fields[Rule.AtIndex]);
                                    rule[9] = Rule.ParseAbrev(fields[Rule.LetterIndex]) ?? (object)System.DBNull.Value;

                                    _ruleRows.Add(rule);
                                    RaiseEntryParsed(null);
                                    break;
                                }

                                case TimeZone.ZONE_NAME:
                                {
                                    // First TZ.
                                    int init = i;
                                    // Count to last
                                    do
                                    {
                                        i++;
                                    } while (i < lines.Length && TimeZone.IsContinuation(lines[i]));

                                    // If first was not the only...
                                    if (i - init != 1)
                                    {
                                        string[] continuation = ParseFields(lines[--i].Trim());

                                        // Continuation has a non-tab delimited date...
                                        if (continuation.Length > 4 && int.Parse(continuation[3]) < _curYear)
                                        {
                                            continue;
                                        }
                                        System.Array.Copy(continuation, 0, fields, 2, continuation.Length);
                                    }
                                    else
                                    {
                                        if (fields.Length > 5 && int.Parse(fields[5]) < _curYear)
                                        {
                                            continue;
                                        }
                                    }

                                    string   name        = TimeZone.ParseName(fields[TimeZone.NameIndex]);
                                    string   countryCode = null;
                                    string   countryName = null;
                                    string   coord       = null;
                                    string   comments    = null;
                                    int      id          = 0;
                                    string[] tokens;
                                    if (tzNameToInfo.TryGetValue(name, out tokens))
                                    {
                                        id          = System.Convert.ToInt32(tokens[0]);
                                        countryCode = tokens[1];
                                        countryName = tokens[2];
                                        coord       = tokens[3];
                                        comments    = tokens[4];
                                    }
                                    else
                                    {
                                        App.ExceptionLogger.LogLow(new System.Exception("OlsonParser.cs Ln 390:"
                                                                                        + "Error attempting to get a TimeZone's iso/tab info."));
                                        continue;
                                    }
                                    short  bias     = TimeZone.ParseBias(fields[TimeZone.GMTOffsetIndex]);
                                    string ruleName = TimeZone.ParseRuleName(fields[TimeZone.RuleIndex]);
                                    string tzAbrev  = TimeZone.ParseTzAbrev(fields[TimeZone.FormatIndex]);

                                    var timeZone = TimeZones.NewRow();
                                    timeZone[0] = id;
                                    timeZone[1] = name;
                                    timeZone[2] = bias;
                                    timeZone[3] = ruleName;
                                    timeZone[4] = tzAbrev;
                                    timeZone[5] = countryCode;
                                    timeZone[6] = countryName;
                                    timeZone[7] = comments;
                                    timeZone[8] = coord;

                                    TimeZoneLookupTable[name] = timeZone;
                                    _timeZoneRows.Add(timeZone);
                                    RaiseEntryParsed(null);
                                    break;
                                }

                                case Link.LINK_NAME:
                                {
                                    var link = new string[] { fields[Link.FromZoneNameIndex], fields[Link.ToZoneNameIndex] };
                                    _links.Add(link);
                                    RaiseEntryParsed(null);
                                    break;
                                }

                                case Leap.LEAP_NAME:
                                {
                                    var leap = Leaps.NewRow();
                                    leap[1] = Leap.ParseYear(fields[Leap.YearIndex]);
                                    leap[2] = fields[Leap.MonthIndex];
                                    leap[3] = Leap.ParseDay(fields[Leap.DayIndex]);
                                    leap[4] = Leap.ParseTime(fields[Leap.TimeIndex]);
                                    leap[5] = Leap.ParseCorrection(fields[Leap.CorrectionIndex]);
                                    leap[6] = Leap.ParseRs(fields[Leap.RsIndex]);

                                    _leapRows.Add(leap);
                                    RaiseEntryParsed(null);
                                    break;
                                }
                                }
                                ParsedEntries++;
                            }
                        }
                        RaiseFileParsed(file);
                    }
                }
                // Adding all links to list of TimeZones.
                foreach (string[] link in _links)
                {
                    System.Data.DataRow from;
                    if (!TimeZoneLookupTable.TryGetValue(link[Link.FromZoneNameIndex], out from))
                    {
                        App.ExceptionLogger.LogLow(new System.Exception("OlsonParser.cs Ln 364: Error attempting to find the \"From\" TimeZone for the link:"
                                                                        + link[0].ToString()));
                        continue;
                    }

                    string toName          = link[Link.ToZoneNameIndex];
                    System.Data.DataRow to = TimeZones.NewRow();
                    to[0] = ++_lastUID;
                    to[1] = toName;
                    to[2] = from[2];
                    to[3] = from[3];
                    to[4] = from[4];
                    to[5] = from[5];
                    to[6] = from[6];
                    to[7] = from[7];
                    to[8] = from[8];

                    if (!TimeZoneLookupTable.TryAdd(toName, to))
                    {
                        App.ExceptionLogger.LogLow(new System.Exception("OlsonParser.cs Ln 373: Error attempting to add the TimeZone for the link:"
                                                                        + link.ToString()));
                        continue;
                    }
                    try
                    {
                        _timeZoneRows.Add(to);
                        RaiseEntryParsed(null);
                        ParsedEntries++;
                    }
                    catch (System.Exception e)
                    {
                        App.ExceptionLogger.LogLow(e);
                        continue;
                    }
                }

                RaiseDirectoryParsed(Directory);
            }
            finally
            {
                TimeZones.EndLoadData();
                Rules.EndLoadData();
                Leaps.EndLoadData();
            }
        }