tushare_api/
custom_date_format.rs1#[cfg(feature = "chrono")]
7use crate::traits::FromTushareValueWithFormat;
8#[cfg(feature = "chrono")]
9use crate::error::TushareError;
10
11#[cfg(feature = "chrono")]
12impl FromTushareValueWithFormat for chrono::NaiveDate {
13 fn from_tushare_value_with_format(
14 value: &serde_json::Value,
15 format: &str,
16 ) -> Result<Self, TushareError> {
17 match value {
18 serde_json::Value::String(s) => {
19 chrono::NaiveDate::parse_from_str(s, format)
21 .map_err(|e| TushareError::ParseError(
22 format!("Failed to parse date '{}' with format '{}': {}", s, format, e)
23 ))
24 }
25 serde_json::Value::Number(n) => {
26 if let Some(i) = n.as_i64() {
28 let date_str = i.to_string();
29
30 if date_str.len() == 8 {
32 if let Ok(date) = chrono::NaiveDate::parse_from_str(&date_str, "%Y%m%d") {
33 return Ok(date);
34 }
35 }
36
37 chrono::NaiveDate::parse_from_str(&date_str, format)
39 .map_err(|e| TushareError::ParseError(
40 format!("Failed to parse numeric date '{}' with format '{}': {}", date_str, format, e)
41 ))
42 } else {
43 Err(TushareError::ParseError(
44 format!("Invalid numeric date value: {}", n)
45 ))
46 }
47 }
48 _ => Err(TushareError::ParseError(
49 format!("Expected string or number for date parsing, got: {:?}", value)
50 )),
51 }
52 }
53}
54
55#[cfg(feature = "chrono")]
56impl FromTushareValueWithFormat for chrono::NaiveDateTime {
57 fn from_tushare_value_with_format(
58 value: &serde_json::Value,
59 format: &str,
60 ) -> Result<Self, TushareError> {
61 match value {
62 serde_json::Value::String(s) => {
63 chrono::NaiveDateTime::parse_from_str(s, format)
65 .map_err(|e| TushareError::ParseError(
66 format!("Failed to parse datetime '{}' with format '{}': {}", s, format, e)
67 ))
68 }
69 serde_json::Value::Number(n) => {
70 let datetime_str = n.to_string();
72 chrono::NaiveDateTime::parse_from_str(&datetime_str, format)
73 .map_err(|e| TushareError::ParseError(
74 format!("Failed to parse numeric datetime '{}' with format '{}': {}", datetime_str, format, e)
75 ))
76 }
77 _ => Err(TushareError::ParseError(
78 format!("Expected string or number for datetime parsing, got: {:?}", value)
79 )),
80 }
81 }
82}
83
84#[cfg(feature = "chrono")]
85impl FromTushareValueWithFormat for chrono::DateTime<chrono::Utc> {
86 fn from_tushare_value_with_format(
87 value: &serde_json::Value,
88 format: &str,
89 ) -> Result<Self, TushareError> {
90 match value {
91 serde_json::Value::String(s) => {
92 chrono::DateTime::parse_from_str(s, format)
94 .map(|dt| dt.with_timezone(&chrono::Utc))
95 .map_err(|e| TushareError::ParseError(
96 format!("Failed to parse UTC datetime '{}' with format '{}': {}", s, format, e)
97 ))
98 }
99 serde_json::Value::Number(n) => {
100 let datetime_str = n.to_string();
102 chrono::DateTime::parse_from_str(&datetime_str, format)
103 .map(|dt| dt.with_timezone(&chrono::Utc))
104 .map_err(|e| TushareError::ParseError(
105 format!("Failed to parse numeric UTC datetime '{}' with format '{}': {}", datetime_str, format, e)
106 ))
107 }
108 _ => Err(TushareError::ParseError(
109 format!("Expected string or number for UTC datetime parsing, got: {:?}", value)
110 )),
111 }
112 }
113}