// Note: public to implement the interface. It does no harm, and it's simpler than using explicit
        // interface implementation.
        public IPattern <LocalDate> ParsePattern(string patternText, NodaFormatInfo formatInfo)
        {
            // Nullity check is performed in LocalDatePattern.
            if (patternText.Length == 0)
            {
                throw new InvalidPatternException(Messages.Parse_FormatStringEmpty);
            }

            if (patternText.Length == 1)
            {
                char patternCharacter = patternText[0];
                patternText = ExpandStandardFormatPattern(patternCharacter, formatInfo);
                if (patternText == null)
                {
                    throw new InvalidPatternException(Messages.Parse_UnknownStandardFormat, patternCharacter, typeof(LocalDate));
                }
            }

            var patternBuilder = new SteppedPatternBuilder <LocalDate, LocalDateParseBucket>(formatInfo,
                                                                                             () => new LocalDateParseBucket(templateValue));

            patternBuilder.ParseCustomPattern(patternText, PatternCharacterHandlers);
            patternBuilder.ValidateUsedFields();
            return(patternBuilder.Build());
        }
        // Note: public to implement the interface. It does no harm, and it's simpler than using explicit
        // interface implementation.
        public IPattern <OffsetDateTime> ParsePattern(string patternText, NodaFormatInfo formatInfo)
        {
            // Nullity check is performed in OffsetDateTimePattern.
            if (patternText.Length == 0)
            {
                throw new InvalidPatternException(Messages.Parse_FormatStringEmpty);
            }

            // Handle standard patterns
            if (patternText.Length == 1)
            {
                switch (patternText[0])
                {
                case 'G':
                    return(OffsetDateTimePattern.Patterns.GeneralIsoPatternImpl);

                case 'o':
                    return(OffsetDateTimePattern.Patterns.ExtendedIsoPatternImpl);

                case 'r':
                    return(OffsetDateTimePattern.Patterns.FullRoundtripPatternImpl);

                default:
                    throw new InvalidPatternException(Messages.Parse_UnknownStandardFormat, patternText[0], typeof(OffsetDateTime));
                }
            }

            var patternBuilder = new SteppedPatternBuilder <OffsetDateTime, OffsetDateTimeParseBucket>(formatInfo, () => new OffsetDateTimeParseBucket(templateValue));

            patternBuilder.ParseCustomPattern(patternText, PatternCharacterHandlers);
            patternBuilder.ValidateUsedFields();
            // Need to reconstruct the template value from the bits...
            return(patternBuilder.Build(templateValue));
        }
Ejemplo n.º 3
0
        // Note: public to implement the interface. It does no harm, and it's simpler than using explicit
        // interface implementation.
        public IPattern <Duration> ParsePattern([NotNull] string patternText, NodaFormatInfo formatInfo)
        {
            Preconditions.CheckNotNull(patternText, nameof(patternText));
            if (patternText.Length == 0)
            {
                throw new InvalidPatternException(TextErrorMessages.FormatStringEmpty);
            }

            // The sole standard pattern...
            if (patternText.Length == 1)
            {
                switch (patternText[0])
                {
                case 'o':
                    return(DurationPattern.Patterns.RoundtripPatternImpl);

                default:
                    throw new InvalidPatternException(TextErrorMessages.UnknownStandardFormat, patternText[0], typeof(Duration));
                }
            }

            var patternBuilder = new SteppedPatternBuilder <Duration, DurationParseBucket>(formatInfo,
                                                                                           () => new DurationParseBucket());

            patternBuilder.ParseCustomPattern(patternText, PatternCharacterHandlers);
            // Somewhat random sample, admittedly...
            return(patternBuilder.Build(Duration.FromHours(1) + Duration.FromMinutes(30) + Duration.FromSeconds(5) + Duration.FromMilliseconds(500)));
        }
Ejemplo n.º 4
0
        // Note: public to implement the interface. It does no harm, and it's simpler than using explicit
        // interface implementation.
        public IPattern <AnnualDate> ParsePattern(string patternText, NodaFormatInfo formatInfo)
        {
            // Nullity check is performed in AnnualDatePattern.
            if (patternText.Length == 0)
            {
                throw new InvalidPatternException(TextErrorMessages.FormatStringEmpty);
            }

            if (patternText.Length == 1)
            {
                switch (patternText[0])
                {
                case 'G':
                    return(AnnualDatePattern.Iso);

                default:
                    throw new InvalidPatternException(TextErrorMessages.UnknownStandardFormat, patternText, typeof(AnnualDate));
                }
            }

            var patternBuilder = new SteppedPatternBuilder <AnnualDate, AnnualDateParseBucket>(formatInfo,
                                                                                               () => new AnnualDateParseBucket(templateValue));

            patternBuilder.ParseCustomPattern(patternText, PatternCharacterHandlers);
            patternBuilder.ValidateUsedFields();
            return(patternBuilder.Build(templateValue));
        }
Ejemplo n.º 5
0
        // Note: public to implement the interface. It does no harm, and it's simpler than using explicit
        // interface implementation.
        public IPattern <LocalTime> ParsePattern(string patternText, NodaFormatInfo formatInfo)
        {
            // Nullity check is performed in LocalTimePattern.
            if (patternText.Length == 0)
            {
                throw new InvalidPatternException(TextErrorMessages.FormatStringEmpty);
            }

            if (patternText.Length == 1)
            {
                patternText = patternText[0] switch
                {
                    't' => formatInfo.DateTimeFormat.ShortTimePattern,
                    'T' => formatInfo.DateTimeFormat.LongTimePattern,
                    'r' => "HH:mm:ss.FFFFFFFFF",
                    _ => throw new InvalidPatternException(TextErrorMessages.UnknownStandardFormat, patternText, typeof(LocalTime))
                };
            }

            var patternBuilder = new SteppedPatternBuilder <LocalTime, LocalTimeParseBucket>(formatInfo,
                                                                                             () => new LocalTimeParseBucket(templateValue));

            patternBuilder.ParseCustomPattern(patternText, PatternCharacterHandlers);
            patternBuilder.ValidateUsedFields();
            return(patternBuilder.Build(templateValue));
        }
Ejemplo n.º 6
0
        // Note: public to implement the interface. It does no harm, and it's simpler than using explicit
        // interface implementation.
        public IPattern <Duration> ParsePattern(string patternText, NodaFormatInfo formatInfo)
        {
            Preconditions.CheckNotNull(patternText, "patternText");
            if (patternText.Length == 0)
            {
                throw new InvalidPatternException(Messages.Parse_FormatStringEmpty);
            }

            // The sole standard pattern...
            if (patternText.Length == 1)
            {
                switch (patternText[0])
                {
                case 'o':
                    return(DurationPattern.Patterns.RoundtripPatternImpl);

                default:
                    throw new InvalidPatternException(Messages.Parse_UnknownStandardFormat, patternText[0], typeof(Duration));
                }
            }

            var patternBuilder = new SteppedPatternBuilder <Duration, DurationParseBucket>(formatInfo,
                                                                                           () => new DurationParseBucket());

            patternBuilder.ParseCustomPattern(patternText, PatternCharacterHandlers);
            return(patternBuilder.Build());
        }
Ejemplo n.º 7
0
        // Note: public to implement the interface. It does no harm, and it's simpler than using explicit
        // interface implementation.
        public IPattern <ZonedDateTime> ParsePattern(string patternText, NodaFormatInfo formatInfo)
        {
            // Nullity check is performed in ZonedDateTimePattern.
            if (patternText.Length == 0)
            {
                throw new InvalidPatternException(Messages.Parse_FormatStringEmpty);
            }

            // Handle standard patterns
            if (patternText.Length == 1)
            {
                switch (patternText[0])
                {
                case 'G':
                    return(ZonedDateTimePattern.Patterns.GeneralFormatOnlyPatternImpl);

                case 'F':
                    return(ZonedDateTimePattern.Patterns.ExtendedFormatOnlyPatternImpl);

                default:
                    throw new InvalidPatternException(Messages.Parse_UnknownStandardFormat, patternText[0], typeof(ZonedDateTime));
                }
            }

            var patternBuilder = new SteppedPatternBuilder <ZonedDateTime, ZonedDateTimeParseBucket>(formatInfo,
                                                                                                     () => new ZonedDateTimeParseBucket(templateValueDate, templateValueTime, templateValueZone, resolver, zoneProvider));

            if (zoneProvider == null)
            {
                patternBuilder.SetFormatOnly();
            }
            patternBuilder.ParseCustomPattern(patternText, PatternCharacterHandlers);
            patternBuilder.ValidateUsedFields();
            return(patternBuilder.Build());
        }
        // Note: public to implement the interface. It does no harm, and it's simpler than using explicit
        // interface implementation.
        public IPattern <LocalDateTime> ParsePattern(string patternText, NodaFormatInfo formatInfo)
        {
            // Nullity check is performed in LocalDateTimePattern.
            if (patternText.Length == 0)
            {
                throw new InvalidPatternException(TextErrorMessages.FormatStringEmpty);
            }

            if (patternText.Length == 1)
            {
                switch (patternText[0])
                {
                // Invariant standard patterns return cached implementations.
                case 'o':
                case 'O':
                    return(LocalDateTimePattern.Patterns.BclRoundtripPatternImpl);

                case 'r':
                    return(LocalDateTimePattern.Patterns.FullRoundtripPatternImpl);

                case 'R':
                    return(LocalDateTimePattern.Patterns.FullRoundtripWithoutCalendarImpl);

                case 's':
                    return(LocalDateTimePattern.Patterns.GeneralIsoPatternImpl);

                // Other standard patterns expand the pattern text to the appropriate custom pattern.
                case 'f':
                    patternText = formatInfo.DateTimeFormat.LongDatePattern + " " + formatInfo.DateTimeFormat.ShortTimePattern;
                    break;

                case 'F':
                    patternText = formatInfo.DateTimeFormat.FullDateTimePattern;
                    break;

                case 'g':
                    patternText = formatInfo.DateTimeFormat.ShortDatePattern + " " + formatInfo.DateTimeFormat.ShortTimePattern;
                    break;

                case 'G':
                    patternText = formatInfo.DateTimeFormat.ShortDatePattern + " " + formatInfo.DateTimeFormat.LongTimePattern;
                    break;

                // Unknown standard patterns fail.
                default:
                    throw new InvalidPatternException(TextErrorMessages.UnknownStandardFormat, patternText, typeof(LocalDateTime));
                }
            }

            var patternBuilder = new SteppedPatternBuilder <LocalDateTime, LocalDateTimeParseBucket>(formatInfo,
                                                                                                     () => new LocalDateTimeParseBucket(templateValueDate, templateValueTime));

            patternBuilder.ParseCustomPattern(patternText, PatternCharacterHandlers);
            patternBuilder.ValidateUsedFields();
            return(patternBuilder.Build(templateValueDate.At(templateValueTime)));
        }
Ejemplo n.º 9
0
        private IPartialPattern <Offset> ParsePartialPattern(string patternText, NodaFormatInfo formatInfo)
        {
            // Nullity check is performed in OffsetPattern.
            if (patternText.Length == 0)
            {
                throw new InvalidPatternException(Messages.Parse_FormatStringEmpty);
            }

            if (patternText.Length == 1)
            {
                switch (patternText)
                {
                case "g":
                    return(CreateGeneralPattern(formatInfo));

                case "G":
                    return(new ZPrefixPattern(CreateGeneralPattern(formatInfo)));

                case "l":
                    patternText = formatInfo.OffsetPatternLong;
                    break;

                case "m":
                    patternText = formatInfo.OffsetPatternMedium;
                    break;

                case "s":
                    patternText = formatInfo.OffsetPatternShort;
                    break;

                default:
                    throw new InvalidPatternException(Messages.Parse_UnknownStandardFormat, patternText, typeof(Offset));
                }
            }
            // This is the only way we'd normally end up in custom parsing land for Z on its own.
            if (patternText == "%Z")
            {
                throw new InvalidPatternException(Messages.Parse_EmptyZPrefixedOffsetPattern);
            }

            // Handle Z-prefix by stripping it, parsing the rest as a normal pattern, then building a special pattern
            // which decides whether or not to delegate.
            bool zPrefix = patternText.StartsWith("Z");

            var patternBuilder = new SteppedPatternBuilder <Offset, OffsetParseBucket>(formatInfo, () => new OffsetParseBucket());

            patternBuilder.ParseCustomPattern(zPrefix ? patternText.Substring(1) : patternText, PatternCharacterHandlers);
            // No need to validate field combinations here, but we do need to do something a bit special
            // for Z-handling.
            IPartialPattern <Offset> pattern = patternBuilder.Build(Offset.FromHoursAndMinutes(5, 30));

            return(zPrefix ? new ZPrefixPattern(pattern) : pattern);
        }
Ejemplo n.º 10
0
        private IPartialPattern <Offset> ParsePartialPattern(string patternText, NodaFormatInfo formatInfo)
        {
            // Nullity check is performed in OffsetPattern.
            if (patternText.Length == 0)
            {
                throw new InvalidPatternException(Messages.Parse_FormatStringEmpty);
            }

            if (patternText.Length == 1)
            {
                char patternCharacter = patternText[0];
                if (patternCharacter == 'n')
                {
                    return(new NumberPattern(formatInfo));
                }
                if (patternCharacter == 'g')
                {
                    return(CreateGeneralPattern(formatInfo));
                }
                if (patternCharacter == 'G')
                {
                    return(new ZPrefixPattern(CreateGeneralPattern(formatInfo)));
                }
                patternText = ExpandStandardFormatPattern(patternCharacter, formatInfo);
                if (patternText == null)
                {
                    throw new InvalidPatternException(Messages.Parse_UnknownStandardFormat, patternCharacter, typeof(Offset));
                }
            }
            // This is the only way we'd normally end up in custom parsing land for Z on its own.
            if (patternText == "%Z")
            {
                throw new InvalidPatternException(Messages.Parse_EmptyZPrefixedOffsetPattern);
            }

            // Handle Z-prefix by stripping it, parsing the rest as a normal pattern, then building a special pattern
            // which decides whether or not to delegate.
            bool zPrefix = patternText.StartsWith("Z");

            var patternBuilder = new SteppedPatternBuilder <Offset, OffsetParseBucket>(formatInfo, () => new OffsetParseBucket());

            patternBuilder.ParseCustomPattern(zPrefix ? patternText.Substring(1) : patternText, PatternCharacterHandlers);
            // No need to validate field combinations here, but we do need to do something a bit special
            // for Z-handling.
            IPartialPattern <Offset> pattern = patternBuilder.Build();

            return(zPrefix ? new ZPrefixPattern(pattern) : pattern);
        }
Ejemplo n.º 11
0
        public void FormatOnly_ParsingFails()
        {
            var builder = new SteppedPatternBuilder <LocalDate, SampleBucket>(
                NodaFormatInfo.InvariantInfo, () => new SampleBucket());

            builder.AddFormatAction((date, sb) => sb.Append("Formatted"));
            builder.SetFormatOnly();
            var pattern = builder.Build(LocalDate.MinIsoValue);

            var value  = new ValueCursor("xyz");
            var result = pattern.ParsePartial(value);

            Assert.AreEqual(ParseResult <LocalDate> .FormatOnlyPattern, result);
            result = pattern.Parse("xyz");
            Assert.AreEqual(ParseResult <LocalDate> .FormatOnlyPattern, result);
        }
Ejemplo n.º 12
0
        // Note: public to implement the interface. It does no harm, and it's simpler than using explicit
        // interface implementation.
        public IPattern <LocalDateTime> ParsePattern(string patternText, NodaFormatInfo formatInfo)
        {
            // Nullity check is performed in LocalDateTimePattern.
            if (patternText.Length == 0)
            {
                throw new InvalidPatternException(TextErrorMessages.FormatStringEmpty);
            }

            if (patternText.Length == 1)
            {
                char patternCharacter = patternText[0];
                if (patternCharacter == 'o' || patternCharacter == 'O')
                {
                    return(LocalDateTimePattern.Patterns.BclRoundtripPatternImpl);
                }
                if (patternCharacter == 'r')
                {
                    return(LocalDateTimePattern.Patterns.FullRoundtripPatternImpl);
                }
                if (patternCharacter == 'R')
                {
                    return(LocalDateTimePattern.Patterns.FullRoundtripWithoutCalendarImpl);
                }
                if (patternCharacter == 's')
                {
                    return(LocalDateTimePattern.Patterns.GeneralIsoPatternImpl);
                }
                patternText = ExpandStandardFormatPattern(patternCharacter, formatInfo);
                if (patternText is null)
                {
                    throw new InvalidPatternException(TextErrorMessages.UnknownStandardFormat, patternCharacter, typeof(LocalDateTime));
                }
            }

            var patternBuilder = new SteppedPatternBuilder <LocalDateTime, LocalDateTimeParseBucket>(formatInfo,
                                                                                                     () => new LocalDateTimeParseBucket(templateValueDate, templateValueTime));

            patternBuilder.ParseCustomPattern(patternText, PatternCharacterHandlers);
            patternBuilder.ValidateUsedFields();
            return(patternBuilder.Build(templateValueDate.At(templateValueTime)));
        }
Ejemplo n.º 13
0
        private IPartialPattern <Offset> ParsePartialPattern(string patternText, NodaFormatInfo formatInfo)
        {
            // Nullity check is performed in OffsetPattern.
            if (patternText.Length == 0)
            {
                throw new InvalidPatternException(TextErrorMessages.FormatStringEmpty);
            }

            if (patternText.Length == 1)
            {
                switch (patternText[0])
                {
                case 'g':
                    return(new CompositePatternBuilder <Offset>
                    {
                        { ParsePartialPattern(formatInfo.OffsetPatternLong, formatInfo), offset => true },
                        { ParsePartialPattern(formatInfo.OffsetPatternMedium, formatInfo), HasZeroSeconds },
                        { ParsePartialPattern(formatInfo.OffsetPatternShort, formatInfo), HasZeroSecondsAndMinutes },
                    }.BuildAsPartial());

                case 'G':
                    return(new ZPrefixPattern(ParsePartialPattern("g", formatInfo)));

                case 'i':
                    return(new CompositePatternBuilder <Offset>
                    {
                        { ParsePartialPattern(formatInfo.OffsetPatternLongNoPunctuation, formatInfo), offset => true },
                        { ParsePartialPattern(formatInfo.OffsetPatternMediumNoPunctuation, formatInfo), HasZeroSeconds },
                        { ParsePartialPattern(formatInfo.OffsetPatternShortNoPunctuation, formatInfo), HasZeroSecondsAndMinutes },
                    }.BuildAsPartial());

                case 'I':
                    return(new ZPrefixPattern(ParsePartialPattern("i", formatInfo)));

                case 'l':
                    patternText = formatInfo.OffsetPatternLong;
                    break;

                case 'm':
                    patternText = formatInfo.OffsetPatternMedium;
                    break;

                case 's':
                    patternText = formatInfo.OffsetPatternShort;
                    break;

                case 'L':
                    patternText = formatInfo.OffsetPatternLongNoPunctuation;
                    break;

                case 'M':
                    patternText = formatInfo.OffsetPatternMediumNoPunctuation;
                    break;

                case 'S':
                    patternText = formatInfo.OffsetPatternShortNoPunctuation;
                    break;

                default:
                    throw new InvalidPatternException(TextErrorMessages.UnknownStandardFormat, patternText, typeof(Offset));
                }
            }
            // This is the only way we'd normally end up in custom parsing land for Z on its own.
            if (patternText == "%Z")
            {
                throw new InvalidPatternException(TextErrorMessages.EmptyZPrefixedOffsetPattern);
            }

            // Handle Z-prefix by stripping it, parsing the rest as a normal pattern, then building a special pattern
            // which decides whether or not to delegate.
            bool zPrefix = patternText.StartsWith("Z");

            var patternBuilder = new SteppedPatternBuilder <Offset, OffsetParseBucket>(formatInfo, () => new OffsetParseBucket());

            patternBuilder.ParseCustomPattern(zPrefix ? patternText.Substring(1) : patternText, PatternCharacterHandlers);
            // No need to validate field combinations here, but we do need to do something a bit special
            // for Z-handling.
            IPartialPattern <Offset> pattern = patternBuilder.Build(Offset.FromHoursAndMinutes(5, 30));

            return(zPrefix ? new ZPrefixPattern(pattern) : pattern);
        }