/// <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); }
/// <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"); } }