88using System . Runtime . CompilerServices ;
99using System . Numerics ;
1010using Parquet . Data ;
11+ using System . Collections . Generic ;
1112
1213namespace Parquet . File . Values
1314{
@@ -81,7 +82,7 @@ private static void ReadPlainBoolean(byte[] data, IList destination, long maxVal
8182 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
8283 private static void ReadInt32 ( byte [ ] data , SchemaElement schema , IList destination )
8384 {
84- if ( schema . Thrift . Converted_type == Thrift . ConvertedType . DATE )
85+ if ( schema . IsAnnotatedWith ( Thrift . ConvertedType . DATE ) )
8586 {
8687 for ( int i = 0 ; i < data . Length ; i += 4 )
8788 {
@@ -112,10 +113,23 @@ private static void ReadFloat(byte[] data, SchemaElement schema, IList destinati
112113 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
113114 private static void ReadLong ( byte [ ] data , SchemaElement schema , IList destination )
114115 {
115- for ( int i = 0 ; i < data . Length ; i += 8 )
116+ if ( schema . IsAnnotatedWith ( Thrift . ConvertedType . TIMESTAMP_MILLIS ) )
116117 {
117- long lv = BitConverter . ToInt64 ( data , i ) ;
118- destination . Add ( lv ) ;
118+ var lst = ( List < DateTimeOffset > ) destination ;
119+
120+ for ( int i = 0 ; i < data . Length ; i += 8 )
121+ {
122+ long lv = BitConverter . ToInt64 ( data , i ) ;
123+ lst . Add ( lv . FromUnixTime ( ) ) ;
124+ }
125+ }
126+ else
127+ {
128+ for ( int i = 0 ; i < data . Length ; i += 8 )
129+ {
130+ long lv = BitConverter . ToInt64 ( data , i ) ;
131+ destination . Add ( lv ) ;
132+ }
119133 }
120134 }
121135
@@ -134,7 +148,7 @@ private static void ReadFixedLenByteArray(byte[] data, SchemaElement schema, ILi
134148 {
135149 for ( int i = 0 ; i < data . Length ; i += schema . Thrift . Type_length )
136150 {
137- if ( schema . Thrift . Converted_type != Thrift . ConvertedType . DECIMAL ) continue ;
151+ if ( ! schema . IsAnnotatedWith ( Thrift . ConvertedType . DECIMAL ) ) continue ;
138152 // go from data - decimal needs to be 16 bytes but not from Spark - variable fixed nonsense
139153 byte [ ] dataNew = new byte [ schema . Thrift . Type_length ] ;
140154 Array . Copy ( data , i , dataNew , 0 , schema . Thrift . Type_length ) ;
@@ -169,7 +183,7 @@ private static void ReadInt96(byte[] data, SchemaElement schema, IList destinati
169183 byte [ ] nanos = new byte [ 8 ] ;
170184 Array . Copy ( data , i + 8 , v96 , 0 , 4 ) ;
171185 Array . Copy ( data , i , nanos , 0 , 8 ) ;
172- var bi = BitConverter . ToInt32 ( v96 , 0 ) . JulianToDateTime ( ) ;
186+ DateTime bi = BitConverter . ToInt32 ( v96 , 0 ) . JulianToDateTime ( ) ;
173187 long nanosToInt64 = BitConverter . ToInt64 ( nanos , 0 ) ;
174188 double millis = ( double ) nanosToInt64 / 1000000D ;
175189 bi = bi . AddMilliseconds ( millis ) ;
@@ -185,8 +199,8 @@ private void ReadByteArray(byte[] data, SchemaElement schemaElement, IList desti
185199 // Both UTF8 and JSON are stored as binary data (byte_array) which allows annotations to be used either UTF8 and JSON
186200 // They should be treated in the same way as Strings
187201 // need to find a better implementation for this but date strings are always broken here because of the type mismatch
188- if ( schemaElement . Thrift . __isset . converted_type ||
189- schemaElement . Thrift . Converted_type == Thrift . ConvertedType . UTF8 || schemaElement . Thrift . Converted_type == Thrift . ConvertedType . JSON ||
202+ if ( schemaElement . IsAnnotatedWith ( Thrift . ConvertedType . UTF8 ) ||
203+ schemaElement . IsAnnotatedWith ( Thrift . ConvertedType . JSON ) ||
190204 _options . TreatByteArrayAsString )
191205 {
192206 for ( int i = 0 ; i < data . Length ; )
0 commit comments