Fixed `%.[369]f` on the whole seconds and misleading docs.

Fixes #71.
This commit is contained in:
Kang Seonghoon 2016-04-22 00:47:01 +09:00
parent d869643a33
commit 66d5856354
3 changed files with 34 additions and 25 deletions

View File

@ -375,29 +375,17 @@ pub fn format<'a, I>(w: &mut fmt::Formatter, date: Option<&NaiveDate>, time: Opt
Nanosecond3 => Nanosecond3 =>
time.map(|t| { time.map(|t| {
let nano = t.nanosecond() % 1_000_000_000; let nano = t.nanosecond() % 1_000_000_000;
if nano == 0 { write!(w, ".{:03}", nano / 1_000_000)
write!(w, ".000")
} else {
write!(w, ".{:03}", nano / 1_000_000)
}
}), }),
Nanosecond6 => Nanosecond6 =>
time.map(|t| { time.map(|t| {
let nano = t.nanosecond() % 1_000_000_000; let nano = t.nanosecond() % 1_000_000_000;
if nano == 0 { write!(w, ".{:06}", nano / 1_000)
write!(w, ".000")
} else {
write!(w, ".{:06}", nano / 1_000)
}
}), }),
Nanosecond9 => Nanosecond9 =>
time.map(|t| { time.map(|t| {
let nano = t.nanosecond() % 1_000_000_000; let nano = t.nanosecond() % 1_000_000_000;
if nano == 0 { write!(w, ".{:09}", nano)
write!(w, ".000")
} else {
write!(w, ".{:09}", nano)
}
}), }),
TimezoneName => TimezoneName =>
off.map(|&(ref name, _)| write!(w, "{}", *name)), off.map(|&(ref name, _)| write!(w, "{}", *name)),
@ -420,7 +408,7 @@ pub fn format<'a, I>(w: &mut fmt::Formatter, date: Option<&NaiveDate>, time: Opt
} else { } else {
None None
}, },
RFC3339 => // (almost) same to `%Y-%m-%dT%H:%M:%S.%f%z` RFC3339 => // same to `%Y-%m-%dT%H:%M:%S%.f%:z`
if let (Some(d), Some(t), Some(&(_, off))) = (date, time, off) { if let (Some(d), Some(t), Some(&(_, off))) = (date, time, off) {
// reuse `Debug` impls which already print ISO 8601 format. // reuse `Debug` impls which already print ISO 8601 format.
// this is faster in this way. // this is faster in this way.

View File

@ -110,8 +110,13 @@ Notes:
It accounts for leap seconds, so `60` is possible. It accounts for leap seconds, so `60` is possible.
6. `%+`: 6. `%+`:
This one is close to, but not identical to, `%Y-%m-%dT%H:%M:%S%.f%z`. Same to `%Y-%m-%dT%H:%M:%S%.f%:z`,
The main differences are a colon in `%z`. i.e. 0, 3, 6 or 9 fractional digits for seconds and colons in the time zone offset.
The typical `strftime` implementations have
different (and locale-dependent) formats for this specifier.
While Chrono's format for `%+` is far more stable,
it is best to avoid this specifier if you want to control the exact output.
7. `%s`: 7. `%s`:
This is not padded and can be negative. This is not padded and can be negative.
@ -123,17 +128,20 @@ Notes:
The default `%f` is right-aligned and always zero-padded to 9 digits The default `%f` is right-aligned and always zero-padded to 9 digits
for the compatibility with glibc and others, for the compatibility with glibc and others,
so it always counts the number of nanoseconds since the last whole second. so it always counts the number of nanoseconds since the last whole second.
E.g. 7ms after the last second will print `007000000`, and parsing `7000000` will yield the same. E.g. 7ms after the last second will print `007000000`,
and parsing `7000000` will yield the same.
The variant `%.f` is left-aligned and print 0, 3, 6 or 9 fractional digits The variant `%.f` is left-aligned and print 0, 3, 6 or 9 fractional digits
according to the precision. E.g. 70ms after the last second under `%.f` will print `.070` according to the precision.
(note: not `.07`), and parsing `.07`, `.070000` etc. will yield the same. E.g. 70ms after the last second under `%.f` will print `.070` (note: not `.07`),
and parsing `.07`, `.070000` etc. will yield the same.
Note that they can print or read nothing if the fractional part is zero or Note that they can print or read nothing if the fractional part is zero or
the next character is not `.`. the next character is not `.`.
The variant `%.3f`, `%.3f` and `%.3f` are left-aligned and print 3, 6 or 9 fractional digits The variant `%.3f`, `%.6f` and `%.9f` are left-aligned and print 3, 6 or 9 fractional digits
according to the number preceding `f`. E.g. 70ms after the last second under `%.3f` will print `.070` according to the number preceding `f`.
(note: not `.07`), and parsing `.07`, `.070000` etc. will yield the same. E.g. 70ms after the last second under `%.3f` will print `.070` (note: not `.07`),
and parsing `.07`, `.070000` etc. will yield the same.
Note that they can read nothing if the fractional part is zero or Note that they can read nothing if the fractional part is zero or
the next character is not `.` however will print with the specified length. the next character is not `.` however will print with the specified length.

View File

@ -787,12 +787,25 @@ mod tests {
let t = NaiveTime::from_hms_nano(3, 5, 7, 98765432); let t = NaiveTime::from_hms_nano(3, 5, 7, 98765432);
assert_eq!(t.format("%H,%k,%I,%l,%P,%p").to_string(), "03, 3,03, 3,am,AM"); assert_eq!(t.format("%H,%k,%I,%l,%P,%p").to_string(), "03, 3,03, 3,am,AM");
assert_eq!(t.format("%M").to_string(), "05"); assert_eq!(t.format("%M").to_string(), "05");
assert_eq!(t.format("%S,%f").to_string(), "07,098765432"); assert_eq!(t.format("%S,%f,%.f").to_string(), "07,098765432,.098765432");
assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".098,.098765,.098765432");
assert_eq!(t.format("%R").to_string(), "03:05"); assert_eq!(t.format("%R").to_string(), "03:05");
assert_eq!(t.format("%T,%X").to_string(), "03:05:07,03:05:07"); assert_eq!(t.format("%T,%X").to_string(), "03:05:07,03:05:07");
assert_eq!(t.format("%r").to_string(), "03:05:07 AM"); assert_eq!(t.format("%r").to_string(), "03:05:07 AM");
assert_eq!(t.format("%t%n%%%n%t").to_string(), "\t\n%\n\t"); assert_eq!(t.format("%t%n%%%n%t").to_string(), "\t\n%\n\t");
let t = NaiveTime::from_hms_micro(3, 5, 7, 432100);
assert_eq!(t.format("%S,%f,%.f").to_string(), "07,432100000,.432100");
assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".432,.432100,.432100000");
let t = NaiveTime::from_hms_milli(3, 5, 7, 210);
assert_eq!(t.format("%S,%f,%.f").to_string(), "07,210000000,.210");
assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".210,.210000,.210000000");
let t = NaiveTime::from_hms(3, 5, 7);
assert_eq!(t.format("%S,%f,%.f").to_string(), "07,000000000,");
assert_eq!(t.format("%.3f,%.6f,%.9f").to_string(), ".000,.000000,.000000000");
// corner cases // corner cases
assert_eq!(NaiveTime::from_hms(13, 57, 9).format("%r").to_string(), "01:57:09 PM"); assert_eq!(NaiveTime::from_hms(13, 57, 9).format("%r").to_string(), "01:57:09 PM");
assert_eq!(NaiveTime::from_hms_milli(23, 59, 59, 1_000).format("%X").to_string(), assert_eq!(NaiveTime::from_hms_milli(23, 59, 59, 1_000).format("%X").to_string(),