parquet 0.0.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,85 @@
1
+ use super::*;
2
+
3
+ pub fn parse_zoned_timestamp(value: &ParquetValue) -> jiff::Timestamp {
4
+ let (ts, tz) = match value {
5
+ ParquetValue::TimestampSecond(ts, tz) => (jiff::Timestamp::from_second(*ts).unwrap(), tz),
6
+ ParquetValue::TimestampMillis(ts, tz) => {
7
+ (jiff::Timestamp::from_millisecond(*ts).unwrap(), tz)
8
+ }
9
+ ParquetValue::TimestampMicros(ts, tz) => {
10
+ (jiff::Timestamp::from_microsecond(*ts).unwrap(), tz)
11
+ }
12
+ ParquetValue::TimestampNanos(ts, tz) => {
13
+ (jiff::Timestamp::from_nanosecond(*ts as i128).unwrap(), tz)
14
+ }
15
+ _ => panic!("Invalid timestamp value"),
16
+ };
17
+
18
+ // If timezone is provided, convert to zoned timestamp
19
+ if let Some(tz) = tz {
20
+ // Handle fixed offset timezones like "+09:00" first
21
+ if tz.starts_with('+') || tz.starts_with('-') {
22
+ // Parse the offset string into hours and minutes
23
+ let (hours, minutes) = if tz.len() >= 5 && tz.contains(':') {
24
+ // Format: "+09:00" or "-09:00"
25
+ let h = tz[1..3].parse::<i32>().unwrap_or(0);
26
+ let m = tz[4..6].parse::<i32>().unwrap_or(0);
27
+ (h, m)
28
+ } else if tz.len() >= 3 {
29
+ // Format: "+09" or "-09"
30
+ let h = tz[1..3].parse::<i32>().unwrap_or(0);
31
+ (h, 0)
32
+ } else {
33
+ (0, 0)
34
+ };
35
+
36
+ // Apply sign
37
+ let total_minutes = if tz.starts_with('-') {
38
+ -(hours * 60 + minutes)
39
+ } else {
40
+ hours * 60 + minutes
41
+ };
42
+
43
+ // Create fixed timezone
44
+ let tz = jiff::tz::TimeZone::fixed(jiff::tz::offset((total_minutes / 60) as i8));
45
+ ts.to_zoned(tz).timestamp()
46
+ } else {
47
+ // Try IANA timezone
48
+ match ts.intz(&tz) {
49
+ Ok(zoned) => zoned.timestamp(),
50
+ Err(_) => ts, // Fall back to UTC if timezone is invalid
51
+ }
52
+ }
53
+ } else {
54
+ // No timezone provided - treat as UTC
55
+ ts
56
+ }
57
+ }
58
+
59
+ // Macro for handling timestamp conversions
60
+ #[macro_export]
61
+ macro_rules! impl_timestamp_conversion {
62
+ ($value:expr, $unit:ident, $handle:expr) => {{
63
+ match $value {
64
+ ParquetValue::$unit(ts, tz) => {
65
+ let ts = parse_zoned_timestamp(&ParquetValue::$unit(ts, tz));
66
+ let time_class = $handle.class_time();
67
+ time_class
68
+ .funcall::<_, _, Value>("parse", (ts.to_string(),))
69
+ .unwrap()
70
+ .into_value_with($handle)
71
+ }
72
+ _ => panic!("Invalid timestamp type"),
73
+ }
74
+ }};
75
+ }
76
+
77
+ // Macro for handling date conversions
78
+ #[macro_export]
79
+ macro_rules! impl_date_conversion {
80
+ ($value:expr, $handle:expr) => {{
81
+ let ts = jiff::Timestamp::from_second(($value as i64) * 86400).unwrap();
82
+ let formatted = ts.strftime("%Y-%m-%d").to_string();
83
+ formatted.into_value_with($handle)
84
+ }};
85
+ }