@@ -9,16 +9,14 @@ namespace Aspire.Dashboard.ConsoleLogs;
99
1010internal static partial class TimestampParser
1111{
12- private static readonly Regex s_rfc3339RegEx = GenerateRfc3339RegEx ( ) ;
13-
1412 public static bool TryParseConsoleTimestamp ( string text , [ NotNullWhen ( true ) ] out TimestampParserResult ? result )
1513 {
16- var match = s_rfc3339RegEx . Match ( text ) ;
14+ // Regex is cached inside the method.
15+ var match = GenerateRfc3339RegEx ( ) . Match ( text ) ;
1716
1817 if ( match . Success )
1918 {
2019 var span = text . AsSpan ( ) ;
21- var timestamp = span [ match . Index ..( match . Index + match . Length ) ] ;
2220
2321 ReadOnlySpan < char > content ;
2422 if ( match . Index + match . Length >= span . Length )
@@ -36,6 +34,7 @@ public static bool TryParseConsoleTimestamp(string text, [NotNullWhen(true)] out
3634 }
3735 }
3836
37+ var timestamp = match . ValueSpan ;
3938 result = new ( content . ToString ( ) , DateTimeOffset . Parse ( timestamp . ToString ( ) , CultureInfo . InvariantCulture ) ) ;
4039 return true ;
4140 }
@@ -45,34 +44,24 @@ public static bool TryParseConsoleTimestamp(string text, [NotNullWhen(true)] out
4544 }
4645
4746 // Regular Expression for an RFC3339 timestamp, including RFC3339Nano
48- //
49- // Example timestamps:
50- // 2023-10-02T12:56:35.123456789Z
51- // 2023-10-02T13:56:35.123456789+10:00
52- // 2023-10-02T13:56:35.123456789-10:00
53- // 2023-10-02T13:56:35.123456789Z10:00
54- // 2023-10-02T13:56:35.123456Z
55- // 2023-10-02T13:56:35Z
56- //
57- // Explanation:
58- // ^ - Starts the string
59- // (?:\\d{4}) - Four digits for the year
60- // - - Separator for the date
61- // (?:0[1-9]|1[0-2]) - Two digits for the month, restricted to 01-12
62- // - - Separator for the date
63- // (?:0[1-9]|[12][0-9]|3[01]) - Two digits for the day, restricted to 01-31
64- // [T ] - Literal, separator between date and time, either a T or a space
65- // (?:[01][0-9]|2[0-3]) - Two digits for the hour, restricted to 00-23
66- // : - Separator for the time
67- // (?:[0-5][0-9]) - Two digits for the minutes, restricted to 00-59
68- // : - Separator for the time
69- // (?:[0-5][0-9]) - Two digits for the seconds, restricted to 00-59
70- // (?:\\.\\d{1,9}) - A period and up to nine digits for the partial seconds
71- // Z - Literal, same as +00:00
72- // (?:[Z+-](?:[01][0-9]|2[0-3]):(?:[0-5][0-9])) - Time Zone offset, in the form ZHH:MM or +HH:MM or -HH:MM
73- //
74- // Note: (?:) is a non-capturing group, since we don't care about the values, we are just interested in whether or not there is a match
75- [ GeneratedRegex ( "^(?:\\ d{4})-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])T(?:[01][0-9]|2[0-3]):(?:[0-5][0-9]):(?:[0-5][0-9])(?:\\ .\\ d{1,9})?(?:Z|(?:[Z+-](?:[01][0-9]|2[0-3]):(?:[0-5][0-9])))?" ) ]
47+ [ GeneratedRegex ( """
48+ ^ # Starts the string
49+ \d{4} # Four digits for the year
50+ - # Separator for the date
51+ (0[1-9]|1[0-2]) # Two digits for the month, restricted to 01-12
52+ - # Separator for the date
53+ (0[1-9]|[12][0-9]|3[01]) # Two digits for the day, restricted to 01-31
54+ [T ] # Literal, separator between date and time, either a T or a space
55+ ([01][0-9]|2[0-3]) # Two digits for the hour, restricted to 00-23
56+ : # Separator for the time
57+ ([0-5][0-9]) # Two digits for the minutes, restricted to 00-59
58+ : # Separator for the time
59+ [0-5][0-9] # Two digits for the seconds, restricted to 00-59
60+ \.\d{1,9} # A period and up to nine digits for the partial seconds
61+ Z # Literal, same as +00:00
62+ [Z+-]([01][0-9]|2[0-3]):[0-5][0-9] # Time Zone offset, in the form ZHH:MM or +HH:MM or -HH:MM
63+ """ ,
64+ RegexOptions . ExplicitCapture | RegexOptions . CultureInvariant | RegexOptions . IgnorePatternWhitespace ) ]
7665 private static partial Regex GenerateRfc3339RegEx ( ) ;
7766
7867 public readonly record struct TimestampParserResult ( string ModifiedText , DateTimeOffset Timestamp ) ;
0 commit comments