Exemplo n.º 1
0
        /// <summary>
        ///   Parses the date time of year.
        /// </summary>
        /// <param name="tokens">The tokens to parse.</param>
        /// <param name="forRule">True if this is for a Rule line, in which case ON/AT are mandatory;
        /// false for a Zone line, in which case it's part of "until" and they're optional</param>
        /// <returns>The DateTimeOfYear object.</returns>
        /// <remarks>
        ///   IN ON AT
        /// </remarks>
        internal ZoneYearOffset ParseDateTimeOfYear(Tokens tokens, bool forRule)
        {
            var mode      = ZoneYearOffset.StartOfYear.Mode;
            var timeOfDay = ZoneYearOffset.StartOfYear.TimeOfDay;

            int monthOfYear = NextMonth(tokens, "MonthOfYear");

            int  dayOfMonth       = 1;
            int  dayOfWeek        = 0;
            bool advanceDayOfWeek = false;
            bool addDay           = false;

            if (tokens.HasNextToken || forRule)
            {
                var on = NextString(tokens, "On");
                if (on.StartsWith("last", StringComparison.Ordinal))
                {
                    dayOfMonth = -1;
                    dayOfWeek  = ParseDayOfWeek(on.Substring(4));
                }
                else
                {
                    int index = on.IndexOf(">=", StringComparison.Ordinal);
                    if (index > 0)
                    {
                        dayOfMonth       = Int32.Parse(on.Substring(index + 2), CultureInfo.InvariantCulture);
                        dayOfWeek        = ParseDayOfWeek(on.Substring(0, index));
                        advanceDayOfWeek = true;
                    }
                    else
                    {
                        index = on.IndexOf("<=", StringComparison.Ordinal);
                        if (index > 0)
                        {
                            dayOfMonth = Int32.Parse(on.Substring(index + 2), CultureInfo.InvariantCulture);
                            dayOfWeek  = ParseDayOfWeek(on.Substring(0, index));
                        }
                        else
                        {
                            try
                            {
                                dayOfMonth = Int32.Parse(on, CultureInfo.InvariantCulture);
                                dayOfWeek  = 0;
                            }
                            catch (FormatException e)
                            {
                                throw new ArgumentException("Unparsable ON token: " + on, e);
                            }
                        }
                    }
                }

                if (tokens.HasNextToken || forRule)
                {
                    var atTime = NextString(tokens, "AT");
                    if (!string.IsNullOrEmpty(atTime))
                    {
                        if (Char.IsLetter(atTime[atTime.Length - 1]))
                        {
                            char zoneCharacter = atTime[atTime.Length - 1];
                            mode   = ZoneYearOffset.NormalizeModeCharacter(zoneCharacter);
                            atTime = atTime.Substring(0, atTime.Length - 1);
                        }
                        if (atTime == "24:00")
                        {
                            timeOfDay = LocalTime.Midnight;
                            addDay    = true;
                        }
                        else
                        {
                            // We happen to parse the time as if it's an offset...
                            Offset tickOfDay = ParserHelper.ParseOffset(atTime);
                            timeOfDay = new LocalTime(new LocalInstant(tickOfDay.Ticks));
                        }
                    }
                }
            }
            return(new ZoneYearOffset(mode, monthOfYear, dayOfMonth, dayOfWeek, advanceDayOfWeek, timeOfDay, addDay));
        }