mirror of
https://github.com/bspeice/dtparse
synced 2024-12-22 12:28:08 -05:00
Flesh out the rest of the methods
This commit is contained in:
parent
04421ebde0
commit
b2626d971a
77
src/lib.rs
77
src/lib.rs
@ -12,8 +12,10 @@ use chrono::DateTime;
|
|||||||
use chrono::Datelike;
|
use chrono::Datelike;
|
||||||
use chrono::FixedOffset;
|
use chrono::FixedOffset;
|
||||||
use chrono::Local;
|
use chrono::Local;
|
||||||
|
use chrono::NaiveDate;
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use chrono::NaiveTime;
|
use chrono::NaiveTime;
|
||||||
|
use chrono::Timelike;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use num_traits::cast::ToPrimitive;
|
use num_traits::cast::ToPrimitive;
|
||||||
use rust_decimal::Decimal;
|
use rust_decimal::Decimal;
|
||||||
@ -64,6 +66,9 @@ pub enum ParseError {
|
|||||||
InvalidMonth,
|
InvalidMonth,
|
||||||
UnrecognizedToken(String),
|
UnrecognizedToken(String),
|
||||||
InvalidParseResult(ParsingResult),
|
InvalidParseResult(ParsingResult),
|
||||||
|
AmPmWithoutHour,
|
||||||
|
InvalidHour,
|
||||||
|
TimezoneUnsupported,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ParseInternalError> for ParseError {
|
impl From<ParseInternalError> for ParseError {
|
||||||
@ -383,8 +388,12 @@ impl ParserInfo {
|
|||||||
self.hms.get(&name.to_lowercase()).cloned()
|
self.hms.get(&name.to_lowercase()).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_ampm(&self, name: &str) -> Option<usize> {
|
fn get_ampm(&self, name: &str) -> Option<bool> {
|
||||||
self.ampm.get(&name.to_lowercase()).cloned()
|
if let Some(v) = self.ampm.get(&name.to_lowercase()) {
|
||||||
|
Some(v.to_owned() == 1)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_pertain(&self, name: &str) -> bool {
|
fn get_pertain(&self, name: &str) -> bool {
|
||||||
@ -718,7 +727,7 @@ pub struct ParsingResult {
|
|||||||
microsecond: Option<i32>,
|
microsecond: Option<i32>,
|
||||||
tzname: Option<String>,
|
tzname: Option<String>,
|
||||||
tzoffset: Option<i32>,
|
tzoffset: Option<i32>,
|
||||||
ampm: Option<usize>,
|
ampm: Option<bool>,
|
||||||
century_specified: bool,
|
century_specified: bool,
|
||||||
any_unused_tokens: Vec<String>,
|
any_unused_tokens: Vec<String>,
|
||||||
}
|
}
|
||||||
@ -788,9 +797,7 @@ impl Parser {
|
|||||||
while i < len_l {
|
while i < len_l {
|
||||||
let value_repr = l[i].clone();
|
let value_repr = l[i].clone();
|
||||||
|
|
||||||
let value = value_repr.parse::<f32>();
|
if let Ok(v) = Decimal::from_str(&value_repr) {
|
||||||
|
|
||||||
if let Ok(v) = value {
|
|
||||||
i = self.parse_numeric_token(&l, i, &self.info, &mut ymd, &mut res, fuzzy)?;
|
i = self.parse_numeric_token(&l, i, &self.info, &mut ymd, &mut res, fuzzy)?;
|
||||||
} else if let Some(value) = self.info.get_weekday(&l[i]) {
|
} else if let Some(value) = self.info.get_weekday(&l[i]) {
|
||||||
res.weekday = Some(value != 0);
|
res.weekday = Some(value != 0);
|
||||||
@ -826,7 +833,7 @@ impl Parser {
|
|||||||
} else if let Some(value) = self.info.get_ampm(&l[i]) {
|
} else if let Some(value) = self.info.get_ampm(&l[i]) {
|
||||||
let is_ampm = self.ampm_valid(res.hour, res.ampm, fuzzy);
|
let is_ampm = self.ampm_valid(res.hour, res.ampm, fuzzy);
|
||||||
|
|
||||||
if is_ampm {
|
if is_ampm.is_ok() {
|
||||||
res.hour = Some(self.adjust_ampm(res.hour.unwrap(), value));
|
res.hour = Some(self.adjust_ampm(res.hour.unwrap(), value));
|
||||||
res.ampm = Some(value);
|
res.ampm = Some(value);
|
||||||
} else if fuzzy {
|
} else if fuzzy {
|
||||||
@ -928,15 +935,50 @@ impl Parser {
|
|||||||
tzoffset: Option<i32>,
|
tzoffset: Option<i32>,
|
||||||
token: &str,
|
token: &str,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
false
|
let all_ascii_upper = token == token.to_ascii_uppercase();
|
||||||
|
return hour.is_some() && tzname.is_none() && tzoffset.is_none() && token.len() <= 5
|
||||||
|
&& all_ascii_upper;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ampm_valid(&self, hour: Option<i32>, ampm: Option<usize>, fuzzy: bool) -> bool {
|
fn ampm_valid(&self, hour: Option<i32>, ampm: Option<bool>, fuzzy: bool) -> ParseResult<bool> {
|
||||||
false
|
if fuzzy && ampm == Some(true) {
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if hour.is_none() {
|
||||||
|
if fuzzy {
|
||||||
|
Ok(false)
|
||||||
|
} else {
|
||||||
|
Err(ParseError::AmPmWithoutHour)
|
||||||
|
}
|
||||||
|
} else if !(0 <= hour.unwrap() && hour.unwrap() <= 12) {
|
||||||
|
if fuzzy {
|
||||||
|
Ok(false)
|
||||||
|
} else {
|
||||||
|
Err(ParseError::InvalidHour)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_naive(&self, res: &ParsingResult, default: NaiveDateTime) -> NaiveDateTime {
|
fn build_naive(&self, res: &ParsingResult, default: NaiveDateTime) -> NaiveDateTime {
|
||||||
Local::now().naive_local()
|
// TODO: Change month/day to u32
|
||||||
|
let d = NaiveDate::from_ymd(
|
||||||
|
res.year.unwrap_or(default.year()),
|
||||||
|
res.month.unwrap_or(default.month() as i32) as u32,
|
||||||
|
res.day.unwrap_or(default.day() as i32) as u32,
|
||||||
|
);
|
||||||
|
|
||||||
|
let t = NaiveTime::from_hms_micro(
|
||||||
|
res.hour.unwrap_or(default.hour() as i32) as u32,
|
||||||
|
res.minute.unwrap_or(default.minute() as i32) as u32,
|
||||||
|
res.second.unwrap_or(default.second() as i32) as u32,
|
||||||
|
res.microsecond
|
||||||
|
.unwrap_or(default.timestamp_subsec_micros() as i32) as u32,
|
||||||
|
);
|
||||||
|
|
||||||
|
NaiveDateTime::new(d, t)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_tzaware(
|
fn build_tzaware(
|
||||||
@ -944,8 +986,13 @@ impl Parser {
|
|||||||
dt: &NaiveDateTime,
|
dt: &NaiveDateTime,
|
||||||
res: &ParsingResult,
|
res: &ParsingResult,
|
||||||
default: NaiveDateTime,
|
default: NaiveDateTime,
|
||||||
) -> Result<FixedOffset, ParseError> {
|
) -> ParseResult<FixedOffset> {
|
||||||
|
|
||||||
|
if res.tzname.is_none() && res.tzoffset.is_none() {
|
||||||
Ok(FixedOffset::east(0))
|
Ok(FixedOffset::east(0))
|
||||||
|
} else {
|
||||||
|
Err(ParseError::TimezoneUnsupported)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_numeric_token(
|
fn parse_numeric_token(
|
||||||
@ -1085,10 +1132,10 @@ impl Parser {
|
|||||||
Ok(idx)
|
Ok(idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn adjust_ampm(&self, hour: i32, ampm: usize) -> i32 {
|
fn adjust_ampm(&self, hour: i32, ampm: bool) -> i32 {
|
||||||
if hour < 12 && ampm == 1 {
|
if hour < 12 && ampm {
|
||||||
hour + 12
|
hour + 12
|
||||||
} else if hour == 12 && ampm == 0 {
|
} else if hour == 12 && ampm {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
hour
|
hour
|
||||||
|
Loading…
Reference in New Issue
Block a user