@@ -13,10 +13,6 @@ internal static class DateTimeParse
13
13
{
14
14
internal const int MaxDateTimeNumberDigits = 8 ;
15
15
16
- internal delegate bool MatchNumberDelegate ( ref __DTString str , int digitLen , out int result ) ;
17
-
18
- private static readonly MatchNumberDelegate s_hebrewNumberParser = new MatchNumberDelegate ( MatchHebrewDigits ) ;
19
-
20
16
internal static DateTime ParseExact ( ReadOnlySpan < char > s , ReadOnlySpan < char > format , DateTimeFormatInfo dtfi , DateTimeStyles style )
21
17
{
22
18
DateTimeResult result = default ; // The buffer to store the parsing result.
@@ -3071,7 +3067,7 @@ private static bool ParseISO8601(scoped ref DateTimeRawInfo raw, ref __DTString
3071
3067
//
3072
3068
////////////////////////////////////////////////////////////////////////
3073
3069
3074
- internal static bool MatchHebrewDigits ( ref __DTString str , int digitLen , out int number )
3070
+ internal static bool MatchHebrewDigits ( ref __DTString str , out int number )
3075
3071
{
3076
3072
number = 0 ;
3077
3073
@@ -3919,12 +3915,21 @@ private static string ExpandPredefinedFormat(ReadOnlySpan<char> format, scoped r
3919
3915
case 's' : // Sortable format (in local time)
3920
3916
case 'o' :
3921
3917
case 'O' : // Round Trip Format
3922
- ConfigureFormatOS ( ref dtfi , ref parseInfo ) ;
3918
+ parseInfo . calendar = GregorianCalendar . GetDefaultInstance ( ) ;
3919
+ dtfi = DateTimeFormatInfo . InvariantInfo ;
3923
3920
break ;
3921
+
3924
3922
case 'r' :
3925
3923
case 'R' : // RFC 1123 Standard. (in Universal time)
3926
- ConfigureFormatR ( ref dtfi , ref parseInfo , ref result ) ;
3924
+ parseInfo . calendar = GregorianCalendar . GetDefaultInstance ( ) ;
3925
+ dtfi = DateTimeFormatInfo . InvariantInfo ;
3926
+
3927
+ if ( ( result . flags & ParseFlags . CaptureOffset ) != 0 )
3928
+ {
3929
+ result . flags |= ParseFlags . Rfc1123Pattern ;
3930
+ }
3927
3931
break ;
3932
+
3928
3933
case 'u' : // Universal time format in sortable format.
3929
3934
parseInfo . calendar = GregorianCalendar . GetDefaultInstance ( ) ;
3930
3935
dtfi = DateTimeFormatInfo . InvariantInfo ;
@@ -3934,6 +3939,7 @@ private static string ExpandPredefinedFormat(ReadOnlySpan<char> format, scoped r
3934
3939
result . flags |= ParseFlags . UtcSortPattern ;
3935
3940
}
3936
3941
break ;
3942
+
3937
3943
case 'U' : // Universal time format with culture-dependent format.
3938
3944
parseInfo . calendar = GregorianCalendar . GetDefaultInstance ( ) ;
3939
3945
result . flags |= ParseFlags . TimeZoneUsed ;
@@ -3971,22 +3977,6 @@ private static bool ParseJapaneseEraStart(ref __DTString str, DateTimeFormatInfo
3971
3977
return true ;
3972
3978
}
3973
3979
3974
- private static void ConfigureFormatR ( scoped ref DateTimeFormatInfo dtfi , scoped ref ParsingInfo parseInfo , scoped ref DateTimeResult result )
3975
- {
3976
- parseInfo . calendar = GregorianCalendar . GetDefaultInstance ( ) ;
3977
- dtfi = DateTimeFormatInfo . InvariantInfo ;
3978
- if ( ( result . flags & ParseFlags . CaptureOffset ) != 0 )
3979
- {
3980
- result . flags |= ParseFlags . Rfc1123Pattern ;
3981
- }
3982
- }
3983
-
3984
- private static void ConfigureFormatOS ( scoped ref DateTimeFormatInfo dtfi , scoped ref ParsingInfo parseInfo )
3985
- {
3986
- parseInfo . calendar = GregorianCalendar . GetDefaultInstance ( ) ;
3987
- dtfi = DateTimeFormatInfo . InvariantInfo ;
3988
- }
3989
-
3990
3980
// Given a specified format character, parse and update the parsing result.
3991
3981
//
3992
3982
private static bool ParseByFormat (
@@ -4025,9 +4015,9 @@ private static bool ParseByFormat(
4025
4015
}
4026
4016
parseResult = ParseDigits ( ref str , tokenLen , out tempYear ) ;
4027
4017
}
4028
- if ( ! parseResult && parseInfo . fCustomNumberParser )
4018
+ if ( ! parseResult && parseInfo . fUseHebrewNumberParser )
4029
4019
{
4030
- parseResult = parseInfo . parseNumberDelegate ( ref str , tokenLen , out tempYear ) ;
4020
+ parseResult = MatchHebrewDigits ( ref str , out tempYear ) ;
4031
4021
}
4032
4022
if ( ! parseResult )
4033
4023
{
@@ -4045,8 +4035,8 @@ private static bool ParseByFormat(
4045
4035
{
4046
4036
if ( ! ParseDigits ( ref str , tokenLen , out tempMonth ) )
4047
4037
{
4048
- if ( ! parseInfo . fCustomNumberParser ||
4049
- ! parseInfo . parseNumberDelegate ( ref str , tokenLen , out tempMonth ) )
4038
+ if ( ! parseInfo . fUseHebrewNumberParser ||
4039
+ ! MatchHebrewDigits ( ref str , out tempMonth ) )
4050
4040
{
4051
4041
result . SetBadDateTimeFailure ( ) ;
4052
4042
return false ;
@@ -4087,8 +4077,8 @@ private static bool ParseByFormat(
4087
4077
4088
4078
if ( ! ParseDigits ( ref str , tokenLen , out tempDay ) )
4089
4079
{
4090
- if ( ! parseInfo . fCustomNumberParser ||
4091
- ! parseInfo . parseNumberDelegate ( ref str , tokenLen , out tempDay ) )
4080
+ if ( ! parseInfo . fUseHebrewNumberParser ||
4081
+ ! MatchHebrewDigits ( ref str , out tempDay ) )
4092
4082
{
4093
4083
result . SetBadDateTimeFailure ( ) ;
4094
4084
return false ;
@@ -4583,10 +4573,7 @@ private static bool DoStrictParse(
4583
4573
DateTimeFormatInfo dtfi ,
4584
4574
scoped ref DateTimeResult result )
4585
4575
{
4586
- ParsingInfo parseInfo = default ;
4587
- parseInfo . Init ( ) ;
4588
-
4589
- parseInfo . calendar = dtfi . Calendar ;
4576
+ var parseInfo = new ParsingInfo ( dtfi . Calendar ) ;
4590
4577
parseInfo . fAllowInnerWhite = ( ( styles & DateTimeStyles . AllowInnerWhite ) != 0 ) ;
4591
4578
parseInfo . fAllowTrailingWhite = ( ( styles & DateTimeStyles . AllowTrailingWhite ) != 0 ) ;
4592
4579
@@ -4597,17 +4584,13 @@ private static bool DoStrictParse(
4597
4584
// Fast-paths for common and important formats/configurations.
4598
4585
if ( styles == DateTimeStyles . None )
4599
4586
{
4600
- switch ( formatParamChar )
4587
+ switch ( formatParamChar | 0x20 )
4601
4588
{
4602
- case 'R' :
4603
4589
case 'r' :
4604
- ConfigureFormatR ( ref dtfi , ref parseInfo , ref result ) ;
4605
- return ParseFormatR ( s , ref parseInfo , ref result ) ;
4590
+ return TryParseFormatR ( s , ref result ) ;
4606
4591
4607
- case 'O' :
4608
4592
case 'o' :
4609
- ConfigureFormatOS ( ref dtfi , ref parseInfo ) ;
4610
- return ParseFormatO ( s , ref result ) ;
4593
+ return TryParseFormatO ( s , ref result ) ;
4611
4594
}
4612
4595
}
4613
4596
@@ -4623,11 +4606,7 @@ private static bool DoStrictParse(
4623
4606
4624
4607
result . calendar = parseInfo . calendar ;
4625
4608
4626
- if ( parseInfo . calendar . ID == CalendarId . HEBREW )
4627
- {
4628
- parseInfo . parseNumberDelegate = s_hebrewNumberParser ;
4629
- parseInfo . fCustomNumberParser = true ;
4630
- }
4609
+ parseInfo . fUseHebrewNumberParser = parseInfo . calendar . ID == CalendarId . HEBREW ;
4631
4610
4632
4611
// Reset these values to negative one so that we could throw exception
4633
4612
// if we have parsed every item twice.
@@ -4787,7 +4766,7 @@ private static bool DoStrictParse(
4787
4766
return DetermineTimeZoneAdjustments ( ref result , styles , bTimeOnly ) ;
4788
4767
}
4789
4768
4790
- private static bool ParseFormatR ( ReadOnlySpan < char > source , scoped ref ParsingInfo parseInfo , scoped ref DateTimeResult result )
4769
+ private static bool TryParseFormatR ( ReadOnlySpan < char > source , scoped ref DateTimeResult result )
4791
4770
{
4792
4771
// Example:
4793
4772
// Tue, 03 Jan 2017 08:08:05 GMT
@@ -4965,8 +4944,8 @@ private static bool ParseFormatR(ReadOnlySpan<char> source, scoped ref ParsingIn
4965
4944
return false ;
4966
4945
}
4967
4946
4968
- // Validate that the parsed date is valid according to the calendar .
4969
- if ( ! parseInfo . calendar . TryToDateTime ( year , month , day , hour , minute , second , 0 , 0 , out result . parsedDate ) )
4947
+ // Validate that the parsed date is valid.
4948
+ if ( ! DateTime . TryCreate ( year , month , day , hour , minute , second , 0 , out result . parsedDate ) )
4970
4949
{
4971
4950
result . SetFailure ( ParseFailureKind . Format_BadDateTimeCalendar ) ;
4972
4951
return false ;
@@ -4982,7 +4961,7 @@ private static bool ParseFormatR(ReadOnlySpan<char> source, scoped ref ParsingIn
4982
4961
return true ;
4983
4962
}
4984
4963
4985
- private static bool ParseFormatO ( ReadOnlySpan < char > source , scoped ref DateTimeResult result )
4964
+ private static bool TryParseFormatO ( ReadOnlySpan < char > source , scoped ref DateTimeResult result )
4986
4965
{
4987
4966
// Examples:
4988
4967
// 2017-06-12T05:30:45.7680000 (interpreted as local time wrt to current time zone)
@@ -6186,11 +6165,11 @@ internal struct ParsingInfo
6186
6165
internal bool fUseTwoDigitYear ;
6187
6166
internal bool fAllowInnerWhite ;
6188
6167
internal bool fAllowTrailingWhite ;
6189
- internal bool fCustomNumberParser ;
6190
- internal DateTimeParse . MatchNumberDelegate parseNumberDelegate ;
6168
+ internal bool fUseHebrewNumberParser ;
6191
6169
6192
- internal void Init ( )
6170
+ public ParsingInfo ( Calendar calendar )
6193
6171
{
6172
+ this . calendar = calendar ;
6194
6173
dayOfWeek = - 1 ;
6195
6174
timeMark = DateTimeParse . TM . NotSet ;
6196
6175
}
0 commit comments