public static int FormatPart(this DateTimeFormatInfo result, string part, int current, bool isDateOnly, bool throwException = true)
        {
            if (part.Contains('d'))
            {
                result.SetDayFormat(part, current++, throwException);

                return(current);
            }

            if (part.Contains('M'))
            {
                result.SetMonthFormat(part, current++, throwException);

                return(current);
            }

            if (part.Contains('y'))
            {
                result.SetYearFormat(part, current++, throwException);

                return(current);
            }

            if (isDateOnly && part.IsDateTimeFormatPart())
            {
                result.SetFormatError("Format string is incorrect. Time fields are not expected", throwException);
            }

            if (part.Contains('h') || part.Contains('H'))
            {
                result.SetHourFormat(part, current++, throwException);

                return(current);
            }

            if (part.Contains('m'))
            {
                result.SetMinuteFormat(part, current++, throwException);

                return(current);
            }

            if (part.Contains('s'))
            {
                result.SetSecondFormat(part, current++, throwException);

                return(current);
            }

            if (part.Contains('t'))
            {
                result.SetAmPmFormat(part, current++, throwException);

                return(current);
            }

            result.SetSeparator(part, current);

            return(current);
        }
        public static void SetSecondFormat(this DateTimeFormatInfo formatInfo, string part, int position, bool throwException = true)
        {
            Argument.IsNotNull(() => formatInfo);
            Argument.IsNotNull(() => part);

            if (formatInfo.SecondFormat is not null)
            {
                formatInfo.SetFormatError("Format string is incorrect. Second field can not be specified more than once", throwException);
            }

            if (part.Length > 2)
            {
                formatInfo.SetFormatError("Format string is incorrect. Second field must be in one of formats: 's' or 'ss'", throwException);
            }

            formatInfo.SecondFormat   = part;
            formatInfo.SecondPosition = position;
        }
        public static void SetAmPmFormat(this DateTimeFormatInfo formatInfo, string part, int position, bool throwException = true)
        {
            Argument.IsNotNull(() => formatInfo);
            Argument.IsNotNull(() => part);

            if (formatInfo.AmPmFormat is not null)
            {
                formatInfo.SetFormatError("Format string is incorrect. AM/PM designator field can not be specified more than once", throwException);
            }

            if (part.Length > 2)
            {
                formatInfo.SetFormatError("Format string is incorrect. AM/PM designator field must be in one of formats: 't' or 'tt'", throwException);
            }

            formatInfo.AmPmFormat   = part;
            formatInfo.AmPmPosition = position;

            formatInfo.IsAmPmShortFormat = part.Length < 2;
        }
        public static void SetYearFormat(this DateTimeFormatInfo formatInfo, string part, int position, bool throwException = true)
        {
            Argument.IsNotNull(() => formatInfo);
            Argument.IsNotNull(() => part);

            if (formatInfo.YearFormat is not null)
            {
                formatInfo.SetFormatError("Format string is incorrect. Year field can not be specified more than once", throwException);
            }

            if (part.Length > 5)
            {
                formatInfo.SetFormatError("Format string is incorrect. Year field must be in one of formats: 'y' or 'yy' or 'yyy' or 'yyyy' or 'yyyyy'", throwException);
            }

            formatInfo.YearFormat   = part;
            formatInfo.YearPosition = position;

            formatInfo.IsYearShortFormat = part.Length < 3;
        }
        public static void SetHourFormat(this DateTimeFormatInfo formatInfo, string part, int position, bool throwException = true)
        {
            Argument.IsNotNull(() => formatInfo);
            Argument.IsNotNull(() => part);

            if (formatInfo.HourFormat is not null)
            {
                var errorMessage = part == formatInfo.HourFormat
                    ? "Format string is incorrect. Hour field can not be specified more than once"
                    : "Format string is incorrect. Hour field must be 12 hour or 24 hour format, but no both";

                formatInfo.SetFormatError(errorMessage, throwException);
            }

            if (part.Length > 2)
            {
                formatInfo.SetFormatError("Format string is incorrect. Hour field must be in one of formats: 'h' or 'H' or 'hh' or 'HH'", throwException);
            }

            formatInfo.HourFormat   = part;
            formatInfo.HourPosition = position;

            formatInfo.IsHour12Format = part.Contains('h');
        }