Пример #1
0
        public void ReadImpliedRelativeTimeSpan(ref DateTime baseTime, NumberToken num, TimeUnitToken units)
        {
            var number = num.Value;

            if (_tokeniser.ContainsToken <RelativeToken>(c => c.RelativeType == RelativeType.Ago))
            {
                number *= -1;
            }
            try
            {
                baseTime = units.Unit switch
                {
                    TimeUnit.Day => baseTime.AddDays(number),
                    TimeUnit.Month => baseTime.AddMonths(number),
                    TimeUnit.Week => baseTime.AddDays(7 * number),
                    TimeUnit.Year => baseTime.AddYears(number),
                    TimeUnit.Minute => baseTime.AddMinutes(number),
                    TimeUnit.Second => baseTime.AddSeconds(number),
                    TimeUnit.Hour => baseTime.AddHours(number),
                    TimeUnit.Millisecond => baseTime.AddMilliseconds(number),
                    _ => throw new ParseException(ParseFailReason.InvalidUnit, $"Invalid unit following '{num.Value}'.")
                };
            } catch (ArgumentOutOfRangeException)
            {
                throw new ParseException(ParseFailReason.InvalidUnit, "Cannot add that much time to the current date.");
            }
        }
Пример #2
0
        public void ReadRelativeDayTime(ref DateTime date, NumberToken firstNumberToken, TriviaToken specifierToken)
        {
            var hours   = firstNumberToken.Value;
            var minutes = 0;
            var seconds = 0;

            switch (specifierToken.TriviaType)
            {
            case TriviaType.Am:
                if (hours == 12)
                {
                    hours = 0;                  // 12 AM == 0000 hours
                }
                break;

            case TriviaType.Pm:
                if (hours != 12)
                {
                    hours += 12;                  // 12 PM = 1200 hours
                }
                break;

            case TriviaType.Colon:
                if (!_tokeniser.MoveNext())
                {
                    throw new ParseException(ParseFailReason.NumberExpected, $"Expected a minute specifier to follow after a colon.");
                }
                if (!(_tokeniser.Current is NumberToken num))
                {
                    throw new ParseException(ParseFailReason.InvalidUnit, $"Expected a number to follow the colon.");
                }
                minutes = num.Value;

                if (_tokeniser.PeekNext() != null && _tokeniser.PeekNext() is TriviaToken t && t.TriviaType == TriviaType.Colon)
                {
                    _tokeniser.MoveNext();
                    if (!_tokeniser.MoveNext())
                    {
                        throw new ParseException(ParseFailReason.NumberExpected, $"Expected a second specifier to follow the colon.");
                    }
                    if (!(_tokeniser.Current is NumberToken msNum))
                    {
                        throw new ParseException(ParseFailReason.InvalidUnit, "Expected a number to follow the colon.");
                    }
                    seconds = msNum.Value;
                }

                if (!_tokeniser.MoveNext() || !(_tokeniser.Current is TriviaToken t0))
                {
                    throw new ParseException(ParseFailReason.UnitExpected, "Expected an AM or PM specifier.");
                }
                switch (t0.TriviaType)
                {
                case TriviaType.Am:
                    if (hours == 12)
                    {
                        hours = 0;                      // 12 AM == 0000 hours
                    }
                    break;

                case TriviaType.Pm:
                    if (hours != 12)
                    {
                        hours += 12;                      // 12 PM = 1200 hours
                    }
                    break;

                default:
                    throw new ParseException(ParseFailReason.InvalidUnit, $"Invalid unit '{t0.TriviaType.ToString()}', expected AM or PM.");
                }
                break;

            default:
                throw new ParseException(ParseFailReason.InvalidUnit, $"Invalid unit '{specifierToken.TriviaType.ToString()}', expected AM or PM.");
            }
            if (hours >= 24 || minutes >= 60 || seconds >= 60)
            {
                throw new ParseException(ParseFailReason.InvalidUnit, $"Not a valid time.");
            }
            date = new DateTime(date.Year, date.Month, date.Day, hours, minutes, seconds);
        }