Skip to content

Commit

Permalink
fix format
Browse files Browse the repository at this point in the history
  • Loading branch information
zhuxiujia committed Dec 18, 2023
1 parent 1bbe8d3 commit aa99077
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 31 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "fastdate"
version = "0.3.25"
version = "0.3.26"
edition = "2021"
description = "Rust fast date carte"
readme = "Readme.md"
Expand Down
10 changes: 10 additions & 0 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,13 @@ fn bench_from_timestamp_millis(b: &mut Bencher) {
});
});
}

#[bench]
fn bench_format(b: &mut Bencher) {
let dt=DateTime::from_str("1997-12-13T11:12:13.123456+09:00").unwrap();
b.iter(|| {
std::hint::black_box({
dt.format("YYYY-MM-DD/hh/mm/ss.000000");
});
});
}
90 changes: 64 additions & 26 deletions src/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,26 +162,64 @@ impl DateTime {
///
/// ```
pub fn format(&self, fmt: &str) -> String {
use std::fmt::Write;
let (mut h, mut m, _) = self.offset_hms();
let offset = self.offset();
let add_sub;
if offset > 0 {
add_sub = '+';
} else {
add_sub = '-';
h = h.abs();
m = m.abs();
let add_sub = if offset >= 0 { '+' } else { '-' };
let mut result = String::with_capacity(fmt.len());
let mut chars = fmt.chars();
while let Some(c) = chars.next() {
result.push(c);
if result.ends_with(".000000000") {
for _ in 0..".000000000".len() {
result.pop();
}
write!(result, ".{:09}", self.nano()).unwrap()
} else if result.ends_with(".000000") {
for _ in 0..".000000".len() {
result.pop();
}
write!(result, ".{:06}", self.nano() / 1000).unwrap()
} else if result.ends_with("+00:00") {
for _ in 0.."+00:00".len() {
result.pop();
}
h = h.abs();
m = m.abs();
write!(result, "{}{:02}:{:02}", add_sub, h, m).unwrap();
} else if result.ends_with("YYYY") {
for _ in 0.."YYYY".len() {
result.pop();
}
write!(result, "{:04}", self.year()).unwrap()
} else if result.ends_with("MM") {
for _ in 0.."MM".len() {
result.pop();
}
result.write_fmt(format_args!("{:02}", self.mon())).unwrap()
} else if result.ends_with("DD") {
for _ in 0.."DD".len() {
result.pop();
}
write!(result, "{:02}", self.day()).unwrap()
} else if result.ends_with("hh") {
for _ in 0.."hh".len() {
result.pop();
}
write!(result, "{:02}", self.hour()).unwrap()
} else if result.ends_with("mm") {
for _ in 0.."mm".len() {
result.pop();
}
write!(result, "{:02}", self.minute()).unwrap();
} else if result.ends_with("ss") {
for _ in 0.."ss".len() {
result.pop();
}
write!(result, "{:02}", self.sec()).unwrap();
}
}
fmt.replacen("YYYY", &self.year().to_string(), 1)
.replacen("MM", &self.mon().to_string(), 1)
.replacen("DD", &self.day().to_string(), 1)
.replacen("hh", &self.hour().to_string(), 1)
.replacen("mm", &self.minute().to_string(), 1)
.replacen("ss", &self.sec().to_string(), 1)
.replacen(".000000000", &format!(".{:09}", self.nano()), 1)
.replacen(".000000", &format!(".{:06}", self.micro()), 1)
.replacen("+00:00", &format!("{}{:02}:{:02}", add_sub, h, m), 1)
.to_string()
result
}

/// parse an string by format.
Expand Down Expand Up @@ -400,7 +438,7 @@ impl DateTime {
Self {
inner: time1::OffsetDateTime::from(s),
}
.set_offset(offset)
.set_offset(offset)
}

/// stand "0000-00-00 00:00:00.000000000"
Expand Down Expand Up @@ -611,7 +649,7 @@ impl From<Date> for DateTime {
"{:04}-{:02}-{:02} 00:00:00.000000000Z",
arg.year, arg.mon, arg.day
))
.unwrap()
.unwrap()
}
}

Expand All @@ -630,7 +668,7 @@ impl From<Time> for DateTime {
"0000-01-01 {:02}:{:02}:{:02}.{:09}Z",
arg.hour, arg.minute, arg.sec, arg.nano
))
.unwrap()
.unwrap()
}
}

Expand All @@ -640,7 +678,7 @@ impl From<(Date, Time)> for DateTime {
"{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:09}Z",
arg.0.year, arg.0.mon, arg.0.day, arg.1.hour, arg.1.minute, arg.1.sec, arg.1.nano
))
.unwrap()
.unwrap()
}
}

Expand All @@ -651,7 +689,7 @@ impl From<(Date, Time, i32)> for DateTime {
"{:04}-{:02}-{:02} {:02}:{:02}:{:02}.{:09}Z",
arg.0.year, arg.0.mon, arg.0.day, arg.1.hour, arg.1.minute, arg.1.sec, arg.1.nano
))
.unwrap();
.unwrap();
datetime = datetime.set_offset(arg.2).add_sub_sec(-arg.2 as i64);
datetime
}
Expand Down Expand Up @@ -694,8 +732,8 @@ impl PartialOrd for DateTime {

impl Serialize for DateTime {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
where
S: Serializer,
{
serializer.serialize_str(&self.to_string())
}
Expand All @@ -704,8 +742,8 @@ impl Serialize for DateTime {
#[cfg(not(tarpaulin_include))]
impl<'de> Deserialize<'de> for DateTime {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
where
D: Deserializer<'de>,
{
use serde::de::Error;
let s = String::deserialize(deserializer)?;
Expand Down
8 changes: 4 additions & 4 deletions tests/datetime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -870,9 +870,9 @@ fn test_format() {
},
));
let f = dt.format("YYYY-MM-DD/hh/mm/ss.000000");
assert_eq!(f, "2000-1-1/1/1/11.123456");
assert_eq!(f, "2000-01-01/01/01/11.123456");
let f = dt.format("YYYY-MM-DD/hh/mm/ss.000000000");
assert_eq!(f, "2000-1-1/1/1/11.123456000");
assert_eq!(f, "2000-01-01/01/01/11.123456000");
}

#[test]
Expand All @@ -893,7 +893,7 @@ fn test_format2() {
.set_offset(8 * 60 * 60);
println!("dt={}", dt.to_string());
let f = dt.format("YYYY-MM-DD/hh/mm/ss.000000/+00:00");
assert_eq!(f, "2000-1-1/9/1/11.123456/+08:00");
assert_eq!(f, "2000-01-01/09/01/11.123456/+08:00");
}

#[test]
Expand All @@ -914,7 +914,7 @@ fn test_format3() {
.set_offset(-8 * 60 * 60);
println!("dt={}", dt.to_string());
let f = dt.format("YYYY-MM-DD/hh/mm/ss.000000/+00:00");
assert_eq!(f, "1999-12-31/17/1/11.123456/-08:00");
assert_eq!(f, "1999-12-31/17/01/11.123456/-08:00");
}

#[test]
Expand Down

0 comments on commit aa99077

Please sign in to comment.