///|
priv struct ParserFields {
mut year : Int32?
mut month : Int32?
mut day : Int32?
mut weekday : Int32?
mut hour : Int32?
mut minute : Int32?
mut second : Int32?
mut microsecond : Int32?
mut tzname : String?
mut tzoffset : Int32?
mut ampm : Int32?
mut century : Bool
}
///|
fn parser_fields() -> ParserFields {
{
year: None,
month: None,
day: None,
weekday: None,
hour: None,
minute: None,
second: None,
microsecond: None,
tzname: None,
tzoffset: None,
ampm: None,
century: false,
}
}
///|
fn parser_jump(text : String) -> Bool {
[
" ", ".", ",", ";", "-", "/", "'", "at", "on", "and", "ad", "m", "t", "of", "st",
"nd", "rd", "th",
].contains(text.to_lower())
}
///|
fn parser_month(text : String) -> Int32? {
let text = text.to_lower()
if text == "sept" {
return Some(9)
}
for index in 0..<12 {
if text == month_short[index].to_lower() ||
text == month_long[index].to_lower() {
return Some(index + 1)
}
}
None
}
///|
fn parser_weekday(text : String) -> Int32? {
let text = text.to_lower()
for index in 0..<7 {
if text == weekday_short[index].to_lower() ||
text == weekday_long[index].to_lower() {
return Some(index)
}
}
None
}
///|
fn parser_hms(text : String) -> Int32? {
match text.to_lower() {
"h" | "hour" | "hours" => Some(0)
"m" | "minute" | "minutes" => Some(1)
"s" | "second" | "seconds" => Some(2)
_ => None
}
}
///|
fn parser_ampm(text : String) -> Int32? {
match text.to_lower() {
"am" | "a" => Some(0)
"pm" | "p" => Some(1)
_ => None
}
}
///|
fn parser_utc(text : String) -> Bool {
["utc", "gmt", "z"].contains(text.to_lower())
}
///|
fn parser_convert_year(
year : Int32,
century : Bool,
reference : Int32,
) -> Int32 {
if year >= 100 || century {
return year
}
let candidate = year + reference / 100 * 100
if candidate >= reference + 50 {
candidate - 100
} else if candidate < reference - 50 {
candidate + 100
} else {
candidate
}
}
///|
fn parser_adjust_ampm(hour : Int32, ampm : Int32) -> Int32 {
if hour < 12 && ampm == 1 {
hour + 12
} else if hour == 12 && ampm == 0 {
0
} else {
hour
}
}
///|
fn ParserFields::could_be_tzname(
self : ParserFields,
token : String,
ignore_offset~ : Bool = false,
) -> Bool {
self.hour is Some(_) &&
self.tzname is None &&
(ignore_offset || self.tzoffset is None) &&
token.to_array().length() <= 5 &&
(
token.to_array().iter().all(char => char >= 'A' && char <= 'Z') ||
["UTC", "GMT", "Z", "z"].contains(token)
)
}