private TimestampDefinition CreateTimestampFromTable(ITomlRoot root, TomlTable tomlTable)
        {
            var property = CreatePropertyFromTable(root, tomlTable);

            var timestamp = new TimestampDefinition
            {
                FixedValue   = property.FixedValue,
                ColumnHeader = property.ColumnHeader,
                ColumnIndex  = property.ColumnIndex,
                PrefaceRegex = property.PrefaceRegex,
                Alias        = property.Alias,
            };

            if (TryGetValue <TomlString>(tomlTable, nameof(TimestampDefinition.Type), out var tomlString) &&
                Enum.TryParse <TimestampType>(tomlString.Value, true, out var type))
            {
                timestamp.Type = type;
            }

            if (TryGetValue(tomlTable, nameof(TimestampDefinition.Formats), out tomlString))
            {
                timestamp.Formats = new[] { tomlString.Value };
            }
            else if (TryGetValue <TomlArray>(tomlTable, nameof(TimestampDefinition.Formats), out var tomlArray))
            {
                timestamp.Formats = tomlArray
                                    .Items
                                    .Select(item => item.Get <string>())
                                    .ToArray();
            }

            if (tomlTable.TryGetValue(nameof(TimestampDefinition.UtcOffset), out var tomlObject))
            {
                timestamp.UtcOffset = CreatePropertyFromObject(root, tomlObject);
            }

            return(timestamp);
        }
        private TimestampDefinition ParseTimestampDefinitionFromShorthand(TomlString tomlString, TimestampType defaultTimestampType)
        {
            var text = tomlString.Value;

            var match = TimestampPropertyRegex.Match(text);

            if (!match.Success)
            {
                throw new ArgumentException($"'{text}' is not a supported timestamp string syntax.");
            }

            var property = ParsePropertyDefinition(match.Groups["property"].Value);

            var timestamp = new TimestampDefinition
            {
                FixedValue   = property.FixedValue,
                ColumnHeader = property.ColumnHeader,
                ColumnIndex  = property.ColumnIndex,
                PrefaceRegex = property.PrefaceRegex,
                Alias        = property.Alias,
            };

            foreach (var capture in match.Groups["timestampOption"].Captures.Cast <Capture>())
            {
                var optionText = capture.Value.Trim();

                if (string.IsNullOrEmpty(optionText))
                {
                    continue;
                }

                if (Enum.TryParse <TimestampType>(optionText, true, out var timestampType))
                {
                    if (timestamp.Type.HasValue)
                    {
                        throw new ArgumentException($"{nameof(timestamp.Type)} is already set to {timestamp.Type} and cannot be changed to {timestampType}.");
                    }

                    timestamp.Type = timestampType;
                }
                else if (TryParseUtcOffset(optionText, out var timeSpan))
                {
                    if (timestamp.UtcOffset != null)
                    {
                        throw new ArgumentException($"{nameof(timestamp.UtcOffset)} is already set to {timestamp.UtcOffset.Name()} and cannot be changed to '{optionText}'.");
                    }

                    timestamp.UtcOffset = new PropertyDefinition
                    {
                        FixedValue = $"{timeSpan}"
                    };
                }
                else
                {
                    timestamp.Formats = new List <string>(timestamp.Formats ?? new string[0])
                                        .Concat(new[] { optionText })
                                        .ToArray();
                }
            }

            if (!timestamp.Type.HasValue)
            {
                timestamp.Type = defaultTimestampType;
            }

            return(timestamp);
        }