33using System . Globalization ;
44using System . Text ;
55using MySql . Data . MySqlClient ;
6+ using MySql . Data . Types ;
67using MySqlConnector . Protocol ;
78using MySqlConnector . Protocol . Serialization ;
89using MySqlConnector . Utilities ;
@@ -315,6 +316,14 @@ public double GetDouble(int ordinal)
315316
316317 public float GetFloat ( int ordinal ) => ( float ) GetValue ( ordinal ) ;
317318
319+ public MySqlDateTime GetMySqlDateTime ( int ordinal )
320+ {
321+ var value = GetValue ( ordinal ) ;
322+ if ( value is DateTime dateTime )
323+ return new MySqlDateTime ( dateTime ) ;
324+ return ( MySqlDateTime ) value ;
325+ }
326+
318327 public int GetValues ( object [ ] values )
319328 {
320329 int count = Math . Min ( values . Length , ResultSet . ColumnDefinitions . Length ) ;
@@ -451,7 +460,7 @@ private static void CheckBufferArguments<T>(long dataOffset, T[] buffer, int buf
451460 throw new ArgumentException ( "bufferOffset + length cannot exceed buffer.Length" , nameof ( length ) ) ;
452461 }
453462
454- private DateTime ParseDateTime ( ReadOnlySpan < byte > value )
463+ private object ParseDateTime ( ReadOnlySpan < byte > value )
455464 {
456465 if ( ! Utf8Parser . TryParse ( value , out int year , out var bytesConsumed ) || bytesConsumed != 4 )
457466 goto InvalidDateTime ;
@@ -468,36 +477,52 @@ private DateTime ParseDateTime(ReadOnlySpan<byte> value)
468477 {
469478 if ( Connection . ConvertZeroDateTime )
470479 return DateTime . MinValue ;
480+ if ( Connection . AllowZeroDateTime )
481+ return new MySqlDateTime ( ) ;
471482 throw new InvalidCastException ( "Unable to convert MySQL date/time to System.DateTime." ) ;
472483 }
473484
485+ int hour , minute , second , microseconds ;
474486 if ( value . Length == 10 )
475- return new DateTime ( year , month , day , 0 , 0 , 0 , Connection . DateTimeKind ) ;
476-
477- if ( value [ 10 ] != 32 )
478- goto InvalidDateTime ;
479- if ( ! Utf8Parser . TryParse ( value . Slice ( 11 ) , out int hour , out bytesConsumed ) || bytesConsumed != 2 )
480- goto InvalidDateTime ;
481- if ( value . Length < 14 || value [ 13 ] != 58 )
482- goto InvalidDateTime ;
483- if ( ! Utf8Parser . TryParse ( value . Slice ( 14 ) , out int minute , out bytesConsumed ) || bytesConsumed != 2 )
484- goto InvalidDateTime ;
485- if ( value . Length < 17 || value [ 16 ] != 58 )
486- goto InvalidDateTime ;
487- if ( ! Utf8Parser . TryParse ( value . Slice ( 17 ) , out int second , out bytesConsumed ) || bytesConsumed != 2 )
488- goto InvalidDateTime ;
489-
490- if ( value . Length == 19 )
491- return new DateTime ( year , month , day , hour , minute , second , Connection . DateTimeKind ) ;
492- if ( value [ 19 ] != 46 )
493- goto InvalidDateTime ;
487+ {
488+ hour = 0 ;
489+ minute = 0 ;
490+ second = 0 ;
491+ microseconds = 0 ;
492+ }
493+ else
494+ {
495+ if ( value [ 10 ] != 32 )
496+ goto InvalidDateTime ;
497+ if ( ! Utf8Parser . TryParse ( value . Slice ( 11 ) , out hour , out bytesConsumed ) || bytesConsumed != 2 )
498+ goto InvalidDateTime ;
499+ if ( value . Length < 14 || value [ 13 ] != 58 )
500+ goto InvalidDateTime ;
501+ if ( ! Utf8Parser . TryParse ( value . Slice ( 14 ) , out minute , out bytesConsumed ) || bytesConsumed != 2 )
502+ goto InvalidDateTime ;
503+ if ( value . Length < 17 || value [ 16 ] != 58 )
504+ goto InvalidDateTime ;
505+ if ( ! Utf8Parser . TryParse ( value . Slice ( 17 ) , out second , out bytesConsumed ) || bytesConsumed != 2 )
506+ goto InvalidDateTime ;
507+
508+ if ( value . Length == 19 )
509+ {
510+ microseconds = 0 ;
511+ }
512+ else
513+ {
514+ if ( value [ 19 ] != 46 )
515+ goto InvalidDateTime ;
494516
495- if ( ! Utf8Parser . TryParse ( value . Slice ( 20 ) , out int microseconds , out bytesConsumed ) || bytesConsumed != value . Length - 20 )
496- goto InvalidDateTime ;
497- for ( ; bytesConsumed < 6 ; bytesConsumed ++ )
498- microseconds *= 10 ;
517+ if ( ! Utf8Parser . TryParse ( value . Slice ( 20 ) , out microseconds , out bytesConsumed ) || bytesConsumed != value . Length - 20 )
518+ goto InvalidDateTime ;
519+ for ( ; bytesConsumed < 6 ; bytesConsumed ++ )
520+ microseconds *= 10 ;
521+ }
522+ }
499523
500- return new DateTime ( year , month , day , hour , minute , second , microseconds / 1000 , Connection . DateTimeKind ) . AddTicks ( microseconds % 1000 * 10 ) ;
524+ var dt = new DateTime ( year , month , day , hour , minute , second , microseconds / 1000 , Connection . DateTimeKind ) . AddTicks ( microseconds % 1000 * 10 ) ;
525+ return Connection . AllowZeroDateTime ? ( object ) new MySqlDateTime ( dt ) : dt ;
501526
502527InvalidDateTime :
503528 throw new FormatException ( "Couldn't interpret '{0}' as a valid DateTime" . FormatInvariant ( Encoding . UTF8 . GetString ( value ) ) ) ;
0 commit comments