chrono
chrono copied to clipboard
Provide more ways to format the fractional portion of a second (required for X.690/ASN.1)
Hello there,
I'm currently working on a ASN.1 DER serializer. This standard has support for sub-second representation, but they (foolishly) drop significant zeros in their representation.
I currently use
let mut time = format!("{}", time.format("%Y%m%d%H%M%S%f"));
let (prefix, fraction) = time.split_at_mut(14);
let time = match fraction.as_bytes().iter().enumerate().rfind(|&(_, &x)| x != b'0') {
Some((offset, _)) => prefix.to_owned() + "." + &fraction[0..offset+1] + "Z",
None => prefix.to_owned() + "Z",
};
to generate my output (which is both ugly and inefficient). What it basically does is it prints out the "%f" (nanoseconds) and truncates its zeroes. If there's nothing left, the "." is also omitted.
TL;DR: So: I basically wonder whether it'd be possible for a (preferably more efficient) "%S" like formatter that outputs the seconds, and omits zeroes and the "." when "possible".
Can't you do something like:
if time.nanosecond() == 0 {
// fmt without frac
} else {
// fmt with frac
}
Unless I'm missing something that's what this hypothetical format specifier would do anyway, and increasing the size of the format mini-language for this use case seems like overkill.
increasing the size of the format mini-language for this use case seems like overkill.
roger that!
It's not only that though, it's also trimming the trailing zeros of the nanosecond. It's stupid, but the standard requires it.
Does the if-statement I suggested not fix your performance concerns?
Also, actually, the %.f format (note the .) should already do what you want. I just checked and this passes for me:
assert_eq!(FixedOffset::east(34200).ymd(2001, 7, 8).and_hms_nano(0, 34, 59, 0)
.format("%.f").to_string(),
"");
Otherwise I don't actually understand what you want.
Oh, wait, you want something that can result in .7 instead of currently you'd end up with .700? So, print the smallest amount possible?
If so I take it back that sounds pretty reasonable. I think maybe some sort of %.-f format would work?
This seems a reasonable request. The actual sequence is up to bikeshedding though... %#.f might work, assuming that we are willing to accept the "alternate" modifier as in the C-like formatting string.
Ah, yeah # would bring it in line with std::fmt, but - brings it in line with chrono's strftime "don't include unnecessary padding" %-? operator. Definitely bikeshedable.
That's indeed what I meant! :-)
Relatedly, would we want some things like:
%-3f: format maximum of three digits stripping zeros%Nf: Format arbitrary number of digits (0 - 9)%-Nf: Format arbitrary number of digits, stripping zeros