/// <summary>
 /// Handle a leading "%" which acts as a pseudo-escape - it's mostly used to allow format strings such as "%H" to mean
 /// "use a custom format string consisting of H instead of a standard pattern H".
 /// </summary>
 internal static void HandlePercent(PatternCursor pattern, SteppedPatternBuilder <TResult, TBucket> builder)
 {
     if (pattern.HasMoreCharacters)
     {
         if (pattern.PeekNext() != '%')
         {
             // Handle the next character as normal
             return;
         }
         throw new InvalidPatternException(TextErrorMessages.PercentDoubled);
     }
     throw new InvalidPatternException(TextErrorMessages.PercentAtEndOfString);
 }
Exemple #2
0
        /// <summary>
        /// Handles date, time and date/time embedded patterns.
        /// </summary>
        internal void AddEmbeddedLocalPartial(
            PatternCursor pattern,
            Func <TBucket, LocalDatePatternParser.LocalDateParseBucket> dateBucketExtractor,
            Func <TBucket, LocalTimePatternParser.LocalTimeParseBucket> timeBucketExtractor,
            Func <TResult, LocalDate> dateExtractor,
            Func <TResult, LocalTime> timeExtractor,
            // null if date/time embedded patterns are invalid
            Func <TResult, LocalDateTime>?dateTimeExtractor)
        {
            // This will be d (date-only), t (time-only), or < (date and time)
            // If it's anything else, we'll see the problem when we try to get the pattern.
            var patternType = pattern.PeekNext();

            if (patternType == 'd' || patternType == 't')
            {
                pattern.MoveNext();
            }
            string embeddedPatternText = pattern.GetEmbeddedPattern();

            switch (patternType)
            {
            case '<':
            {
                var sampleBucket = CreateSampleBucket();
                var templateTime = timeBucketExtractor(sampleBucket).TemplateValue;
                var templateDate = dateBucketExtractor(sampleBucket).TemplateValue;
                if (dateTimeExtractor is null)
                {
                    throw new InvalidPatternException(TextErrorMessages.InvalidEmbeddedPatternType);
                }
                AddField(PatternFields.EmbeddedDate, 'l');
                AddField(PatternFields.EmbeddedTime, 'l');
                AddEmbeddedPattern(
                    LocalDateTimePattern.Create(embeddedPatternText, FormatInfo, templateDate + templateTime).UnderlyingPattern,
                    (bucket, value) =>
                    {
                        var dateBucket                = dateBucketExtractor(bucket);
                        var timeBucket                = timeBucketExtractor(bucket);
                        dateBucket.Calendar           = value.Calendar;
                        dateBucket.Year               = value.Year;
                        dateBucket.MonthOfYearNumeric = value.Month;
                        dateBucket.DayOfMonth         = value.Day;
                        timeBucket.Hours24            = value.Hour;
                        timeBucket.Minutes            = value.Minute;
                        timeBucket.Seconds            = value.Second;
                        timeBucket.FractionalSeconds  = value.NanosecondOfSecond;
                    },
                    dateTimeExtractor);
                break;
            }

            case 'd':
                AddEmbeddedDatePattern('l', embeddedPatternText, dateBucketExtractor, dateExtractor);
                break;

            case 't':
                AddEmbeddedTimePattern('l', embeddedPatternText, timeBucketExtractor, timeExtractor);
                break;

            default:
                throw new InvalidOperationException("Bug in Noda Time: embedded pattern type wasn't date, time, or date+time");
            }
        }