You are viewing a plain text version of this content. The canonical link for it is here.
Posted to github@arrow.apache.org by GitBox <gi...@apache.org> on 2021/04/14 11:45:57 UTC

[GitHub] [arrow] alamb commented on a change in pull request #9993: ARROW-12317: [Rust] JSON writer support for time, duration and date

alamb commented on a change in pull request #9993:
URL: https://github.com/apache/arrow/pull/9993#discussion_r613173769



##########
File path: rust/arrow/src/json/writer.rs
##########
@@ -660,6 +765,138 @@ mod tests {
         );
     }
 
+    #[test]
+    fn write_dates() {
+        let ts_string = "2018-11-13T17:11:10.011375885995";
+        let ts_millis = ts_string
+            .parse::<chrono::NaiveDateTime>()
+            .unwrap()
+            .timestamp_millis();
+
+        let arr_date32 = Date32Array::from(vec![
+            Some(i32::try_from(ts_millis / 1000 / (60 * 60 * 24)).unwrap()),
+            None,
+        ]);
+        let arr_date64 = Date64Array::from(vec![Some(ts_millis), None]);
+        let arr_names = StringArray::from(vec![Some("a"), Some("b")]);
+
+        let schema = Schema::new(vec![
+            Field::new("date32", arr_date32.data_type().clone(), false),
+            Field::new("date64", arr_date64.data_type().clone(), false),
+            Field::new("name", arr_names.data_type().clone(), false),
+        ]);
+        let schema = Arc::new(schema);
+
+        let batch = RecordBatch::try_new(
+            schema,
+            vec![
+                Arc::new(arr_date32),
+                Arc::new(arr_date64),
+                Arc::new(arr_names),
+            ],
+        )
+        .unwrap();
+
+        let mut buf = Vec::new();
+        {
+            let mut writer = LineDelimitedWriter::new(&mut buf);
+            writer.write_batches(&[batch]).unwrap();
+        }
+
+        assert_eq!(
+            String::from_utf8(buf).unwrap(),
+            r#"{"date32":"2018-11-13","date64":"2018-11-13","name":"a"}
+{"name":"b"}
+"#
+        );
+    }
+
+    #[test]
+    fn write_times() {
+        let arr_time32sec = Time32SecondArray::from(vec![Some(120), None]);
+        let arr_time32msec = Time32MillisecondArray::from(vec![Some(120), None]);
+        let arr_time64usec = Time64MicrosecondArray::from(vec![Some(120), None]);
+        let arr_time64nsec = Time64NanosecondArray::from(vec![Some(120), None]);
+        let arr_names = StringArray::from(vec![Some("a"), Some("b")]);
+
+        let schema = Schema::new(vec![
+            Field::new("time32sec", arr_time32sec.data_type().clone(), false),
+            Field::new("time32msec", arr_time32msec.data_type().clone(), false),
+            Field::new("time64usec", arr_time64usec.data_type().clone(), false),
+            Field::new("time64nsec", arr_time64nsec.data_type().clone(), false),
+            Field::new("name", arr_names.data_type().clone(), false),
+        ]);
+        let schema = Arc::new(schema);
+
+        let batch = RecordBatch::try_new(
+            schema,
+            vec![
+                Arc::new(arr_time32sec),
+                Arc::new(arr_time32msec),
+                Arc::new(arr_time64usec),
+                Arc::new(arr_time64nsec),
+                Arc::new(arr_names),
+            ],
+        )
+        .unwrap();
+
+        let mut buf = Vec::new();
+        {
+            let mut writer = LineDelimitedWriter::new(&mut buf);
+            writer.write_batches(&[batch]).unwrap();
+        }
+
+        assert_eq!(
+            String::from_utf8(buf).unwrap(),
+            r#"{"time32sec":"00:02:00","time32msec":"00:00:00.120","time64usec":"00:00:00.000120","time64nsec":"00:00:00.000000120","name":"a"}
+{"name":"b"}
+"#
+        );
+    }
+
+    #[test]
+    fn write_durations() {
+        let arr_durationsec = DurationSecondArray::from(vec![Some(120), None]);
+        let arr_durationmsec = DurationMillisecondArray::from(vec![Some(120), None]);
+        let arr_durationusec = DurationMicrosecondArray::from(vec![Some(120), None]);
+        let arr_durationnsec = DurationNanosecondArray::from(vec![Some(120), None]);
+        let arr_names = StringArray::from(vec![Some("a"), Some("b")]);
+
+        let schema = Schema::new(vec![
+            Field::new("duration_sec", arr_durationsec.data_type().clone(), false),
+            Field::new("duration_msec", arr_durationmsec.data_type().clone(), false),
+            Field::new("duration_usec", arr_durationusec.data_type().clone(), false),
+            Field::new("duration_nsec", arr_durationnsec.data_type().clone(), false),
+            Field::new("name", arr_names.data_type().clone(), false),
+        ]);
+        let schema = Arc::new(schema);
+
+        let batch = RecordBatch::try_new(
+            schema,
+            vec![
+                Arc::new(arr_durationsec),
+                Arc::new(arr_durationmsec),
+                Arc::new(arr_durationusec),
+                Arc::new(arr_durationnsec),
+                Arc::new(arr_names),
+            ],
+        )
+        .unwrap();
+
+        let mut buf = Vec::new();
+        {
+            let mut writer = LineDelimitedWriter::new(&mut buf);
+            writer.write_batches(&[batch]).unwrap();
+        }
+
+        assert_eq!(
+            String::from_utf8(buf).unwrap(),
+            r#"{"duration_sec":"PT120S","duration_msec":"PT0.120S","duration_usec":"PT0.000120S","duration_nsec":"PT0.000000120S","name":"a"}

Review comment:
       I am not familiar with the `"PT120S"` string representation of a duration (perhaps this is some Chrono thing)?
   
   I would have expected durations to have the same format as Time (probably) so instead of `PT120S` something more like `00:02:00` and instead of `PT0.120S` it would be `00:00:00.120`
   
   What do you think?
   

##########
File path: rust/arrow/src/array/array_primitive.rs
##########
@@ -227,6 +245,13 @@ where
     pub fn value_as_time(&self, i: usize) -> Option<NaiveTime> {
         as_time::<T>(i64::from(self.value(i)))
     }
+
+    /// Returns a value as a chrono `Duration`
+    ///
+    /// If a data type cannot be converted to `Duration`, a `None` is returned

Review comment:
       👍 




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org