/// <summary>
        /// Initializes this transition group based on the specified asjustment rule.
        /// </summary>
        /// <param name="adjustmentRule">The adjustment rule to initialize from.</param>
        /// <param name="standardPeriod">A reference to the pre-created standard period.</param>
        internal virtual void InitializeFromAdjustmentRule(TimeZoneInfo.AdjustmentRule adjustmentRule, TimeZonePeriod standardPeriod)
        {
            TimeZonePeriod daylightPeriod = new TimeZonePeriod();

            // Generate an Id of the form "Daylight/2008"
            daylightPeriod.Id = string.Format(
                "{0}/{1}",
                TimeZonePeriod.DaylightPeriodId,
                adjustmentRule.DateStart.Year);
            daylightPeriod.Name = TimeZonePeriod.DaylightPeriodName;
            daylightPeriod.Bias = standardPeriod.Bias - adjustmentRule.DaylightDelta;

            this.timeZoneDefinition.Periods.Add(daylightPeriod.Id, daylightPeriod);

            this.transitionToDaylight = TimeZoneTransition.CreateTimeZoneTransition(
                this.timeZoneDefinition,
                daylightPeriod,
                adjustmentRule.DaylightTransitionStart);

            this.transitionToStandard = TimeZoneTransition.CreateTimeZoneTransition(
                this.timeZoneDefinition,
                standardPeriod,
                adjustmentRule.DaylightTransitionEnd);

            this.transitions.Add(this.transitionToDaylight);
            this.transitions.Add(this.transitionToStandard);
        }
        /// <summary>
        /// Loads from json.
        /// </summary>
        /// <param name="jsonProperty">The json property.</param>
        /// <param name="service">The service.</param>
        internal override void LoadFromJson(JsonObject jsonProperty, ExchangeService service)
        {
            base.LoadFromJson(jsonProperty, service);

            foreach (string key in jsonProperty.Keys)
            {
                switch (key)
                {
                case XmlAttributeNames.Id:
                    this.id = jsonProperty.ReadAsString(key);
                    break;

                case XmlElementNames.Transition:

                    foreach (object uncastJsonTransition in jsonProperty.ReadAsArray(key))
                    {
                        JsonObject         jsonTransition = uncastJsonTransition as JsonObject;
                        TimeZoneTransition transition     = TimeZoneTransition.Create(this.timeZoneDefinition, jsonTransition.ReadTypeString());

                        transition.LoadFromJson(jsonTransition, service);

                        this.transitions.Add(transition);
                    }
                    break;
                }
            }
        }
Example #3
0
        /// <summary>
        /// Initializes this transition group based on the specified asjustment rule.
        /// </summary>
        /// <param name="adjustmentRule">The adjustment rule to initialize from.</param>
        /// <param name="standardPeriod">A reference to the pre-created standard period.</param>
        internal virtual void InitializeFromAdjustmentRule(TimeZoneInfo.AdjustmentRule adjustmentRule, TimeZonePeriod standardPeriod)
        {
            if (adjustmentRule.DaylightDelta.TotalSeconds == 0)
            {
                // If the time zone info doesn't support Daylight Saving Time, we just need to
                // create one transition to one group with one transition to the standard period.
                TimeZonePeriod standardPeriodToSet = new TimeZonePeriod();
                standardPeriodToSet.Id = string.Format(
                    "{0}/{1}",
                    standardPeriod.Id,
                    adjustmentRule.DateStart.Year);
                standardPeriodToSet.Name = standardPeriod.Name;
                standardPeriodToSet.Bias = standardPeriod.Bias;

                // this.timeZoneDefinition.Periods.Add(standardPeriodToSet.Id, standardPeriodToSet);
                this.timeZoneDefinition.Periods[standardPeriodToSet.Id] = standardPeriodToSet;

                this.transitionToStandard = new TimeZoneTransition(this.timeZoneDefinition, standardPeriodToSet);
                this.transitions.Add(this.transitionToStandard);
            }
            else
            {
                TimeZonePeriod daylightPeriod = new TimeZonePeriod();

                // Generate an Id of the form "Daylight/2008"
                daylightPeriod.Id = string.Format(
                    "{0}/{1}",
                    TimeZonePeriod.DaylightPeriodId,
                    adjustmentRule.DateStart.Year);
                daylightPeriod.Name = TimeZonePeriod.DaylightPeriodName;
                daylightPeriod.Bias = standardPeriod.Bias - adjustmentRule.DaylightDelta;

                // this.timeZoneDefinition.Periods.Add(daylightPeriod.Id, daylightPeriod);
                this.timeZoneDefinition.Periods[daylightPeriod.Id] = daylightPeriod;

                this.transitionToDaylight = TimeZoneTransition.CreateTimeZoneTransition(
                    this.timeZoneDefinition,
                    daylightPeriod,
                    adjustmentRule.DaylightTransitionStart);

                TimeZonePeriod standardPeriodToSet = new TimeZonePeriod();
                standardPeriodToSet.Id = string.Format(
                    "{0}/{1}",
                    standardPeriod.Id,
                    adjustmentRule.DateStart.Year);
                standardPeriodToSet.Name = standardPeriod.Name;
                standardPeriodToSet.Bias = standardPeriod.Bias;
                //  this.timeZoneDefinition.Periods.Add(standardPeriodToSet.Id, standardPeriodToSet);
                this.timeZoneDefinition.Periods[standardPeriodToSet.Id] = standardPeriodToSet;

                this.transitionToStandard = TimeZoneTransition.CreateTimeZoneTransition(
                    this.timeZoneDefinition,
                    standardPeriodToSet,
                    adjustmentRule.DaylightTransitionEnd);

                this.transitions.Add(this.transitionToDaylight);
                this.transitions.Add(this.transitionToStandard);
            }
        }
Example #4
0
        /// <summary>
        /// Tries to read element from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns>True if element was read.</returns>
        internal override bool TryReadElementFromXml(EwsServiceXmlReader reader)
        {
            switch (reader.LocalName)
            {
            case XmlElementNames.Periods:
                do
                {
                    reader.Read();

                    if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.Period))
                    {
                        TimeZonePeriod period = new TimeZonePeriod();
                        period.LoadFromXml(reader);

                        this.periods.Add(period.Id, period);
                    }
                }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.Periods));

                return(true);

            case XmlElementNames.TransitionsGroups:
                do
                {
                    reader.Read();

                    if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.TransitionsGroup))
                    {
                        TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this);

                        transitionGroup.LoadFromXml(reader);

                        this.transitionGroups.Add(transitionGroup.Id, transitionGroup);
                    }
                }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.TransitionsGroups));

                return(true);

            case XmlElementNames.Transitions:
                do
                {
                    reader.Read();

                    if (reader.IsStartElement())
                    {
                        TimeZoneTransition transition = TimeZoneTransition.Create(this, reader.LocalName);

                        transition.LoadFromXml(reader);

                        this.transitions.Add(transition);
                    }
                }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.Transitions));

                return(true);

            default:
                return(false);
            }
        }
Example #5
0
        /// <summary>
        /// Adds a transition group with a single transition to the specified period.
        /// </summary>
        /// <param name="timeZonePeriod">The time zone period.</param>
        /// <returns>A TimeZoneTransitionGroup.</returns>
        private TimeZoneTransitionGroup CreateTransitionGroupToPeriod(TimeZonePeriod timeZonePeriod)
        {
            TimeZoneTransition transitionToPeriod = new TimeZoneTransition(this, timeZonePeriod);

            TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this, this.transitionGroups.Count.ToString());

            transitionGroup.Transitions.Add(transitionToPeriod);

            this.transitionGroups.Add(transitionGroup.Id, transitionGroup);

            return(transitionGroup);
        }
Example #6
0
        /// <summary>
        /// Tries to read element from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns>True if element was read.</returns>
        internal override bool TryReadElementFromXml(EwsServiceXmlReader reader)
        {
            reader.EnsureCurrentNodeIsStartElement();

            TimeZoneTransition transition = TimeZoneTransition.Create(this.timeZoneDefinition, reader.LocalName);

            transition.LoadFromXml(reader);

            EwsUtilities.Assert(
                transition.TargetPeriod != null,
                "TimeZoneTransitionGroup.TryReadElementFromXml",
                "The transition's target period is null.");

            this.transitions.Add(transition);

            return(true);
        }
Example #7
0
        /// <summary>
        /// Compares the transitions.
        /// </summary>
        /// <param name="x">The first transition.</param>
        /// <param name="y">The second transition.</param>
        /// <returns>A negative number if x is less than y, 0 if x and y are equal, a positive number if x is greater than y.</returns>
        private int CompareTransitions(TimeZoneTransition x, TimeZoneTransition y)
        {
            if (x == y)
            {
                return(0);
            }
            else if (x.GetType() == typeof(TimeZoneTransition))
            {
                return(-1);
            }
            else if (y.GetType() == typeof(TimeZoneTransition))
            {
                return(1);
            }
            else
            {
                AbsoluteDateTransition firstTransition  = (AbsoluteDateTransition)x;
                AbsoluteDateTransition secondTransition = (AbsoluteDateTransition)y;

                return(DateTime.Compare(firstTransition.DateTime, secondTransition.DateTime));
            }
        }
        /// <summary>
        /// Compares the transitions.
        /// </summary>
        /// <param name="x">The first transition.</param>
        /// <param name="y">The second transition.</param>
        /// <returns>A negative number if x is less than y, 0 if x and y are equal, a positive number if x is greater than y.</returns>
        private int CompareTransitions(TimeZoneTransition x, TimeZoneTransition y)
        {
            if (x == y)
            {
                return 0;
            }
            else if (x.GetType() == typeof(TimeZoneTransition))
            {
                return -1;
            }
            else if (y.GetType() == typeof(TimeZoneTransition))
            {
                return 1;
            }
            else
            {
                AbsoluteDateTransition firstTransition = (AbsoluteDateTransition)x;
                AbsoluteDateTransition secondTransition = (AbsoluteDateTransition)y;

                return DateTime.Compare(firstTransition.DateTime, secondTransition.DateTime);
            }
        }
Example #9
0
        /// <summary>
        /// Initializes the private members holding references to the transitions to the Daylight
        /// and Standard periods.
        /// </summary>
        private void InitializeTransitions()
        {
            if (this.transitionToStandard == null)
            {
                foreach (TimeZoneTransition transition in this.transitions)
                {
                    if (transition.TargetPeriod.IsStandardPeriod || (this.transitions.Count == 1))
                    {
                        this.transitionToStandard = transition;
                    }
                    else
                    {
                        this.transitionToDaylight = transition;
                    }
                }
            }

            // If we didn't find a Standard period, this is an invalid time zone group.
            if (this.transitionToStandard == null)
            {
                throw new ServiceLocalException(Strings.InvalidOrUnsupportedTimeZoneDefinition);
            }
        }
        /// <summary>
        /// Loads from json.
        /// </summary>
        /// <param name="jsonProperty">The json property.</param>
        /// <param name="service">The service.</param>
        internal override void LoadFromJson(JsonObject jsonProperty, ExchangeService service)
        {
            base.LoadFromJson(jsonProperty, service);

            foreach (string key in jsonProperty.Keys)
            {
                switch (key)
                {
                case XmlAttributeNames.Name:
                    this.name = jsonProperty.ReadAsString(key);
                    break;

                case XmlAttributeNames.Id:
                    this.id = jsonProperty.ReadAsString(key);
                    break;

                case XmlElementNames.Periods:
                    foreach (object jsonPeriod in jsonProperty.ReadAsArray(key))
                    {
                        TimeZonePeriod period = new TimeZonePeriod();
                        period.LoadFromJson(jsonPeriod as JsonObject, service);

                        // OM:1648848 Bad timezone data from clients can include duplicate rules
                        // for one year, with duplicate ID. In that case, let the first one win.
                        if (!this.periods.ContainsKey(period.Id))
                        {
                            this.periods.Add(period.Id, period);
                        }
                        else
                        {
                            service.TraceMessage(
                                TraceFlags.EwsTimeZones,
                                string.Format(
                                    "An entry with the same key (Id) '{0}' already exists in Periods. Cannot add another one. Existing entry: [Name='{1}', Bias='{2}']. Entry to skip: [Name='{3}', Bias='{4}'].",
                                    period.Id,
                                    this.Periods[period.Id].Name,
                                    this.Periods[period.Id].Bias,
                                    period.Name,
                                    period.Bias));
                        }
                    }

                    break;

                case XmlElementNames.TransitionsGroups:
                    foreach (object arrayOfTransitionsTypeInstance in jsonProperty.ReadAsArray(key))
                    {
                        TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this);
                        transitionGroup.LoadFromJson(arrayOfTransitionsTypeInstance as JsonObject, service);

                        this.transitionGroups.Add(transitionGroup.Id, transitionGroup);
                    }

                    break;

                case XmlElementNames.Transitions:
                    JsonObject arrayOfTransitionsType = jsonProperty.ReadAsJsonObject(key);

                    foreach (object uncastJsonTransition in arrayOfTransitionsType.ReadAsArray(XmlElementNames.Transition))
                    {
                        JsonObject         jsonTransition = uncastJsonTransition as JsonObject;
                        TimeZoneTransition transition     = TimeZoneTransition.Create(this, jsonTransition.ReadTypeString());

                        transition.LoadFromJson(jsonTransition, service);

                        this.transitions.Add(transition);
                    }

                    break;

                default:
                    break;
                }
            }

            // EWS can return a TimeZone definition with no Id. Generate a new Id in this case.
            if (string.IsNullOrEmpty(this.id))
            {
                string nameValue = string.IsNullOrEmpty(this.Name) ? string.Empty : this.Name;
                this.Id = NoIdPrefix + Math.Abs(nameValue.GetHashCode()).ToString();
            }

            this.transitions.Sort(this.CompareTransitions);
        }
        /// <summary>
        /// Initializes the private members holding references to the transitions to the Daylight
        /// and Standard periods.
        /// </summary>
        private void InitializeTransitions()
        {
            if (this.transitionToStandard == null)
            {
                foreach (TimeZoneTransition transition in this.transitions)
                {
                    if (transition.TargetPeriod.IsStandardPeriod || (this.transitions.Count == 1))
                    {
                        this.transitionToStandard = transition;
                    }
                    else
                    {
                        this.transitionToDaylight = transition;
                    }
                }
            }

            // If we didn't find a Standard period, this is an invalid time zone group.
            if (this.transitionToStandard == null)
            {
                throw new ServiceLocalException(Strings.InvalidOrUnsupportedTimeZoneDefinition);
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="TimeZoneDefinition"/> class.
        /// </summary>
        /// <param name="timeZoneInfo">The time zone info used to initialize this definition.</param>
        internal TimeZoneDefinition(TimeZoneInfo timeZoneInfo)
            : this()
        {
            this.Id = timeZoneInfo.Id;
            this.Name = timeZoneInfo.DisplayName;

            // TimeZoneInfo only supports one standard period, which bias is the time zone's base
            // offset to UTC.
            TimeZonePeriod standardPeriod = new TimeZonePeriod();
            standardPeriod.Id = TimeZonePeriod.StandardPeriodId;
            standardPeriod.Name = TimeZonePeriod.StandardPeriodName;
            standardPeriod.Bias = -timeZoneInfo.BaseUtcOffset;
            
            TimeZoneInfo.AdjustmentRule[] adjustmentRules = timeZoneInfo.GetAdjustmentRules();

            TimeZoneTransition transitionToStandardPeriod = new TimeZoneTransition(this, standardPeriod);

            if (adjustmentRules.Length == 0)
            {
                this.periods.Add(standardPeriod.Id, standardPeriod);

                // If the time zone info doesn't support Daylight Saving Time, we just need to
                // create one transition to one group with one transition to the standard period.
                TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this, "0");
                transitionGroup.Transitions.Add(transitionToStandardPeriod);

                this.transitionGroups.Add(transitionGroup.Id, transitionGroup);

                TimeZoneTransition initialTransition = new TimeZoneTransition(this, transitionGroup);

                this.transitions.Add(initialTransition);
            }
            else
            {
                for (int i = 0; i < adjustmentRules.Length; i++)
                {
                    TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this, this.transitionGroups.Count.ToString());
                    transitionGroup.InitializeFromAdjustmentRule(adjustmentRules[i], standardPeriod);

                    this.transitionGroups.Add(transitionGroup.Id, transitionGroup);

                    TimeZoneTransition transition;

                    if (i == 0)
                    {
                        // If the first adjustment rule's start date in not undefined (DateTime.MinValue)
                        // we need to add a dummy group with a single, simple transition to the Standard
                        // period and a group containing the transitions mapping to the adjustment rule.
                        if (adjustmentRules[i].DateStart > DateTime.MinValue.Date)
                        {
                            TimeZoneTransition transitionToDummyGroup = new TimeZoneTransition(
                                this,
                                this.CreateTransitionGroupToPeriod(standardPeriod));

                            this.transitions.Add(transitionToDummyGroup);

                            AbsoluteDateTransition absoluteDateTransition = new AbsoluteDateTransition(this, transitionGroup);
                            absoluteDateTransition.DateTime = adjustmentRules[i].DateStart;

                            transition = absoluteDateTransition;
                            this.periods.Add(standardPeriod.Id, standardPeriod);
                        }
                        else
                        {
                            transition = new TimeZoneTransition(this, transitionGroup);
                        }
                    }
                    else
                    {
                        AbsoluteDateTransition absoluteDateTransition = new AbsoluteDateTransition(this, transitionGroup);
                        absoluteDateTransition.DateTime = adjustmentRules[i].DateStart;

                        transition = absoluteDateTransition;
                    }

                    this.transitions.Add(transition);
                }

                // If the last adjustment rule's end date is not undefined (DateTime.MaxValue),
                // we need to create another absolute date transition that occurs the date after
                // the last rule's end date. We target this additional transition to a group that
                // contains a single simple transition to the Standard period.
                DateTime lastAdjustmentRuleEndDate = adjustmentRules[adjustmentRules.Length - 1].DateEnd;

                if (lastAdjustmentRuleEndDate < DateTime.MaxValue.Date)
                {
                    AbsoluteDateTransition transitionToDummyGroup = new AbsoluteDateTransition(
                        this,
                        this.CreateTransitionGroupToPeriod(standardPeriod));
                    transitionToDummyGroup.DateTime = lastAdjustmentRuleEndDate.AddDays(1);

                    this.transitions.Add(transitionToDummyGroup);
                }
            }
        }
        /// <summary>
        /// Adds a transition group with a single transition to the specified period.
        /// </summary>
        /// <param name="timeZonePeriod">The time zone period.</param>
        /// <returns>A TimeZoneTransitionGroup.</returns>
        private TimeZoneTransitionGroup CreateTransitionGroupToPeriod(TimeZonePeriod timeZonePeriod)
        {
            TimeZoneTransition transitionToPeriod = new TimeZoneTransition(this, timeZonePeriod);

            TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this, this.transitionGroups.Count.ToString());
            transitionGroup.Transitions.Add(transitionToPeriod);

            this.transitionGroups.Add(transitionGroup.Id, transitionGroup);

            return transitionGroup;
        }
Example #14
0
        /// <summary>
        /// Tries to read element from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns>True if element was read.</returns>
        internal override bool TryReadElementFromXml(EwsServiceXmlReader reader)
        {
            switch (reader.LocalName)
            {
            case XmlElementNames.Periods:
                do
                {
                    reader.Read();

                    if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.Period))
                    {
                        TimeZonePeriod period = new TimeZonePeriod();
                        period.LoadFromXml(reader);

                        // OM:1648848 Bad timezone data from clients can include duplicate rules
                        // for one year, with duplicate ID. In that case, let the first one win.
                        if (!this.periods.ContainsKey(period.Id))
                        {
                            this.periods.Add(period.Id, period);
                        }
                        else
                        {
                            reader.Service.TraceMessage(
                                TraceFlags.EwsTimeZones,
                                string.Format(
                                    "An entry with the same key (Id) '{0}' already exists in Periods. Cannot add another one. Existing entry: [Name='{1}', Bias='{2}']. Entry to skip: [Name='{3}', Bias='{4}'].",
                                    period.Id,
                                    this.Periods[period.Id].Name,
                                    this.Periods[period.Id].Bias,
                                    period.Name,
                                    period.Bias));
                        }
                    }
                }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.Periods));

                return(true);

            case XmlElementNames.TransitionsGroups:
                do
                {
                    reader.Read();

                    if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.TransitionsGroup))
                    {
                        TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this);

                        transitionGroup.LoadFromXml(reader);

                        this.transitionGroups.Add(transitionGroup.Id, transitionGroup);
                    }
                }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.TransitionsGroups));

                return(true);

            case XmlElementNames.Transitions:
                do
                {
                    reader.Read();

                    if (reader.IsStartElement())
                    {
                        TimeZoneTransition transition = TimeZoneTransition.Create(this, reader.LocalName);

                        transition.LoadFromXml(reader);

                        this.transitions.Add(transition);
                    }
                }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.Transitions));

                return(true);

            default:
                return(false);
            }
        }
Example #15
0
        /// <summary>
        /// Initializes a new instance of the <see cref="TimeZoneDefinition"/> class.
        /// </summary>
        /// <param name="timeZoneInfo">The time zone info used to initialize this definition.</param>
        internal TimeZoneDefinition(TimeZoneInfo timeZoneInfo)
            : this()
        {
            this.Id   = timeZoneInfo.Id;
            this.Name = timeZoneInfo.DisplayName;

            // TimeZoneInfo only supports one standard period, which bias is the time zone's base
            // offset to UTC.
            TimeZonePeriod standardPeriod = new TimeZonePeriod();

            standardPeriod.Id   = TimeZonePeriod.StandardPeriodId;
            standardPeriod.Name = TimeZonePeriod.StandardPeriodName;
            standardPeriod.Bias = -timeZoneInfo.BaseUtcOffset;

            this.periods.Add(standardPeriod.Id, standardPeriod);

            TimeZoneInfo.AdjustmentRule[] adjustmentRules = timeZoneInfo.GetAdjustmentRules();

            TimeZoneTransition transitionToStandardPeriod = new TimeZoneTransition(this, standardPeriod);

            if (adjustmentRules.Length == 0)
            {
                // If the time zone info doesn't support Daylight Saving Time, we just need to
                // create one transition to one group with one transition to the standard period.
                TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this, "0");
                transitionGroup.Transitions.Add(transitionToStandardPeriod);

                this.transitionGroups.Add(transitionGroup.Id, transitionGroup);

                TimeZoneTransition initialTransition = new TimeZoneTransition(this, transitionGroup);

                this.transitions.Add(initialTransition);
            }
            else
            {
                for (int i = 0; i < adjustmentRules.Length; i++)
                {
                    TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this, this.transitionGroups.Count.ToString());
                    transitionGroup.InitializeFromAdjustmentRule(adjustmentRules[i], standardPeriod);

                    this.transitionGroups.Add(transitionGroup.Id, transitionGroup);

                    TimeZoneTransition transition;

                    if (i == 0)
                    {
                        // If the first adjustment rule's start date in not undefined (DateTime.MinValue)
                        // we need to add a dummy group with a single, simple transition to the Standard
                        // period and a group containing the transitions mapping to the adjustment rule.
                        if (adjustmentRules[i].DateStart > DateTime.MinValue.Date)
                        {
                            TimeZoneTransition transitionToDummyGroup = new TimeZoneTransition(
                                this,
                                this.CreateTransitionGroupToPeriod(standardPeriod));

                            this.transitions.Add(transitionToDummyGroup);

                            AbsoluteDateTransition absoluteDateTransition = new AbsoluteDateTransition(this, transitionGroup);
                            absoluteDateTransition.DateTime = adjustmentRules[i].DateStart;

                            transition = absoluteDateTransition;
                        }
                        else
                        {
                            transition = new TimeZoneTransition(this, transitionGroup);
                        }
                    }
                    else
                    {
                        AbsoluteDateTransition absoluteDateTransition = new AbsoluteDateTransition(this, transitionGroup);
                        absoluteDateTransition.DateTime = adjustmentRules[i].DateStart;

                        transition = absoluteDateTransition;
                    }

                    this.transitions.Add(transition);
                }

                // If the last adjustment rule's end date is not undefined (DateTime.MaxValue),
                // we need to create another absolute date transition that occurs the date after
                // the last rule's end date. We target this additional transition to a group that
                // contains a single simple transition to the Standard period.
                DateTime lastAdjustmentRuleEndDate = adjustmentRules[adjustmentRules.Length - 1].DateEnd;

                if (lastAdjustmentRuleEndDate < DateTime.MaxValue.Date)
                {
                    AbsoluteDateTransition transitionToDummyGroup = new AbsoluteDateTransition(
                        this,
                        this.CreateTransitionGroupToPeriod(standardPeriod));
                    transitionToDummyGroup.DateTime = lastAdjustmentRuleEndDate.AddDays(1);

                    this.transitions.Add(transitionToDummyGroup);
                }
            }
        }
        /// <summary>
        /// Initializes this transition group based on the specified asjustment rule.
        /// </summary>
        /// <param name="adjustmentRule">The adjustment rule to initialize from.</param>
        /// <param name="standardPeriod">A reference to the pre-created standard period.</param>
        internal virtual void InitializeFromAdjustmentRule(TimeZoneInfo.AdjustmentRule adjustmentRule, TimeZonePeriod standardPeriod)
        {
            TimeZonePeriod daylightPeriod = new TimeZonePeriod();

            // Generate an Id of the form "Daylight/2008"
            daylightPeriod.Id = string.Format(
                "{0}/{1}",
                TimeZonePeriod.DaylightPeriodId,
                adjustmentRule.DateStart.Year);
            daylightPeriod.Name = TimeZonePeriod.DaylightPeriodName;
            daylightPeriod.Bias = standardPeriod.Bias - adjustmentRule.DaylightDelta;

            this.timeZoneDefinition.Periods.Add(daylightPeriod.Id, daylightPeriod);

            this.transitionToDaylight = TimeZoneTransition.CreateTimeZoneTransition(
                this.timeZoneDefinition,
                daylightPeriod,
                adjustmentRule.DaylightTransitionStart);

            TimeZonePeriod standardPeriodToSet = new TimeZonePeriod();
            standardPeriodToSet.Id = string.Format(
                "{0}/{1}",
                standardPeriod.Id,
                adjustmentRule.DateStart.Year);
            standardPeriodToSet.Name = standardPeriod.Name;
            standardPeriodToSet.Bias = standardPeriod.Bias;
            this.timeZoneDefinition.Periods.Add(standardPeriodToSet.Id, standardPeriodToSet);

            this.transitionToStandard = TimeZoneTransition.CreateTimeZoneTransition(
                this.timeZoneDefinition,
                standardPeriodToSet,
                adjustmentRule.DaylightTransitionEnd);

            this.transitions.Add(this.transitionToDaylight);
            this.transitions.Add(this.transitionToStandard);
        }
Example #17
0
        /// <summary>
        /// Loads from json.
        /// </summary>
        /// <param name="jsonProperty">The json property.</param>
        /// <param name="service">The service.</param>
        internal override void LoadFromJson(JsonObject jsonProperty, ExchangeService service)
        {
            base.LoadFromJson(jsonProperty, service);

            foreach (string key in jsonProperty.Keys)
            {
                switch (key)
                {
                case XmlAttributeNames.Name:
                    this.name = jsonProperty.ReadAsString(key);
                    break;

                case XmlAttributeNames.Id:
                    this.id = jsonProperty.ReadAsString(key);
                    break;

                case XmlElementNames.Periods:
                    foreach (object jsonPeriod in jsonProperty.ReadAsArray(key))
                    {
                        TimeZonePeriod period = new TimeZonePeriod();
                        period.LoadFromJson(jsonPeriod as JsonObject, service);

                        this.periods.Add(period.Id, period);
                    }

                    break;

                case XmlElementNames.TransitionsGroups:
                    foreach (object arrayOfTransitionsTypeInstance in jsonProperty.ReadAsArray(key))
                    {
                        TimeZoneTransitionGroup transitionGroup = new TimeZoneTransitionGroup(this);
                        transitionGroup.LoadFromJson(arrayOfTransitionsTypeInstance as JsonObject, service);

                        this.transitionGroups.Add(transitionGroup.Id, transitionGroup);
                    }

                    break;

                case XmlElementNames.Transitions:
                    JsonObject arrayOfTransitionsType = jsonProperty.ReadAsJsonObject(key);

                    foreach (object uncastJsonTransition in arrayOfTransitionsType.ReadAsArray(XmlElementNames.Transition))
                    {
                        JsonObject         jsonTransition = uncastJsonTransition as JsonObject;
                        TimeZoneTransition transition     = TimeZoneTransition.Create(this, jsonTransition.ReadTypeString());

                        transition.LoadFromJson(jsonTransition, service);

                        this.transitions.Add(transition);
                    }

                    break;

                default:
                    break;
                }
            }

            // EWS can return a TimeZone definition with no Id. Generate a new Id in this case.
            if (string.IsNullOrEmpty(this.id))
            {
                string nameValue = string.IsNullOrEmpty(this.Name) ? string.Empty : this.Name;
                this.Id = NoIdPrefix + Math.Abs(nameValue.GetHashCode()).ToString();
            }

            this.transitions.Sort(this.CompareTransitions);
        }