Beispiel #1
0
        /// <summary>
        /// Obtient le standard offset applicable à une règle
        /// </summary>
        /// <param name="year"></param>
        /// <param name="rules"></param>
        /// <param name="rule"></param>
        /// <param name="zoneDate"></param>
        /// <param name="gmtOffset"></param>
        /// <returns></returns>
        /// <remarks>Cette fonction compare des règles définies, comme un changement d'heure ne se
        /// produit pas en même temps qu'un autre on peut appliquer le stdoff entre règles sans
        /// se soucier de point recouvrant.
        /// </remarks>
        private static TimeSpan GetLastSaveOffset(int year, List<Rule> rules, Rule rule, TzTimeZoneRuleDate zoneDate, TimeSpan gmtOffset)
        {
            int bestyear = -1;

            TimeSpan range = TimeSpan.MaxValue;
            TimeSpan stdoff = zoneDate.StandardOffset;

            for (int index = rules.Count - 1; index >= 0; index--) {
                if (rules[index] == rule) continue;

                if (rules[index].LowerYear > year || rules[index].HighYear < bestyear) {
                    continue;
                }

                int yref = (rules[index].HighYear > year) ? year : rules[index].HighYear;

                if (yref == year && rules[index].AtKind == rule.AtKind &&
                    (rules[index].Month > rule.Month || (rules[index].Month == rule.Month && rules[index].Day.DayWork == DayWorkKind.Dom && rule.Day.DayWork == DayWorkKind.Dom && rules[index].Day.DayOfMonth > rule.Day.DayOfMonth))) {
                    if (yref > rules[index].LowerYear)
                        yref--;
                    else
                        continue;
                }

                for (; yref >= rules[index].LowerYear; yref--) {
                    if (!TzUtilities.IsYearType(yref, rules[index].YearType)) continue;

                    DateTime precedent;
                    DateTime current;

                    // On compare la date avec la date limite de zone
                    if (rules[index].AtKind == TimeKind.LocalWallTime) {
                        precedent = TzUtilities.GetDateTime(rules[index], yref, gmtOffset, TimeSpan.Zero, DateTimeKind.Local);
                        if (zoneDate.ToLocalTime() > precedent)
                            break;
                        // On exprime la date courante de la règle à vérifier en local
                        current = TzUtilities.GetDateTime(rule, year, gmtOffset, rules[index].StandardOffset, DateTimeKind.Local);
                    }
                    else {
                        precedent = TzUtilities.GetDateTime(rules[index], yref, gmtOffset, TimeSpan.Zero, DateTimeKind.Utc);
                        if (zoneDate.UtcDate > precedent)
                            break;
                        // On exprime la date courante de la règle à vérifier en utc
                        current = TzUtilities.GetDateTime(rule, year, gmtOffset, rules[index].StandardOffset, DateTimeKind.Utc);
                    }

                    if (precedent > current) {
                        continue;
                    }
                    else {
                        TimeSpan diff = current - precedent;
                        if (range > diff) {
                            stdoff = rules[index].StandardOffset;
                            range = diff;
                            bestyear = precedent.Year;
                        }
                        break;
                    }
                }
            }

            return stdoff;
        }
Beispiel #2
0
        /// <summary>
        /// Obtient une règle en fonction de sa description
        /// </summary>
        /// <param name="ruleDescription"></param>
        /// <returns>
        /// # Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
        /// </returns>
        public static Rule GetRule(List<string> ruleDescription)
        {
            Rule r = new Rule();

            Debug.Assert(ruleDescription.Count == 10);
            Debug.Assert(ruleDescription[0] == "Rule");

            r.Name = ruleDescription[1];
            r.StandardOffset = GetHMS(ruleDescription[8]);
            r.Letter = ruleDescription[9];

            string loyearp = ruleDescription[2];
            string hiyearp = ruleDescription[3];
            string typep = ruleDescription[4];

            // Year work
            // Min Year (FROM)
            IEnumerable<string> by =
                BeginYears.Where(e => itsabbr(loyearp, e));
            if (by.Count() == 0) {
                r.LowerYear = Int32.Parse(loyearp);
            }
            else if (by.Count() == 1) {
                if (by.ElementAt(0) == BeginYears[0])
                    r.LowerYear = DateTime.MinValue.Year;
                else
                    r.LowerYear = DateTime.MaxValue.Year;
            }
            else {
                throw new ArgumentException("Multiple inexact match", loyearp);
            }

            // Max Year (TO)
            by = EndYears.Where(e => itsabbr(hiyearp, e));
            if (by.Count() == 0) {
                r.HighYear = Int32.Parse(hiyearp);
            }
            else if (by.Count() == 1) {
                if (by.ElementAt(0) == EndYears[0])
                    r.HighYear = DateTime.MinValue.Year;
                else if (by.ElementAt(0) == EndYears[1])
                    r.HighYear = DateTime.MaxValue.Year;
                else
                    r.HighYear = r.LowerYear;
            }
            else {
                throw new ArgumentException("Multiple inexact match", hiyearp);
            }

            if (r.LowerYear > r.HighYear)
                throw new ArgumentException("Starting year greater than ending year");

            // Type (TYPE)
            switch (typep) {
                case "":
                case "-":
                    r.YearType = YearType.none;
                    break;
                case "even":
                    r.YearType = YearType.even;
                    break;
                case "odd":
                    r.YearType = YearType.odd;
                    break;
                case "uspres":
                    r.YearType = YearType.uspres;
                    break;
                case "nonpres":
                    r.YearType = YearType.nonpres;
                    break;
                case "nonuspres":
                    r.YearType = YearType.nonuspres;
                    break;
                default:
                    throw new ArgumentException("Unknown type " + typep);
            }

            SetRuleSub(r, ruleDescription[5], ruleDescription[6], ruleDescription[7]);

            return r;
        }