文件概述
这个
display.rs
文件为 ISO 8601 库中的核心类型实现了
Display
trait,提供了符合标准的人类可读格式输出功能。
核心格式化实现
1. Date 类型的显示格式化
implDisplayforDate{fnfmt(&self, f:&mutfmt::Formatter)->fmt::Result{match*self{// 格式:`2015-11-02` (年月日)Date::YMD{ year, month, day }=>write!(f,"{:04}-{:02}-{:02}", year, month, day),// 格式:`2015-W45-01` (年-周数-星期几)Date::Week{ year, ww, d }=>write!(f,"{:04}-W{:02}-{:02}", year, ww, d),// 格式:`2015-306` (年-年内第几天)Date::Ordinal{ year, ddd }=>write!(f,"{:04}-{:03}", year, ddd),}}}三种日期格式说明 :
YMD (年月日):
2024-01-15- 最常用的日历日期格式
- 4位年-2位月-2位日
Week (周日期):
2024-W03-1- 基于周数的日期表示
- 4位年-W2位周数-1位星期几(1=周一, 7=周日)
Ordinal (序数日期):
2024-015- 一年中的第几天
- 4位年-3位年内日数
2. Time 类型的显示格式化
implDisplayforTime{fnfmt(&self, f:&mutfmt::Formatter)->fmt::Result{// 格式:`16:43:16.123+00:00`write!(
f,"{:02}:{:02}:{:02}.{}+{:02}:{:02}",self.hour,self.minute,self.second,self.millisecond,self.tz_offset_hours,self.tz_offset_minutes
)}}时间格式特点 :
-
基本格式
:
HH:MM:SS.mmm -
时区信息
:
+HH:MM或-HH:MM -
完整示例
:
16:43:16.123+08:00(北京时间下午4点43分) -
固定显示毫秒
:即使毫秒为0也会显示
.000
3. DateTime 类型的显示格式化
implDisplayforDateTime{fnfmt(&self, f:&mutfmt::Formatter)->fmt::Result{// 格式:`2015-11-02T16:43:16.123+00:00`write!(f,"{}T{}",self.date,self.time)}}日期时间格式 :
-
ISO 8601 标准格式
:日期和时间用
T分隔 -
组合格式
:
<Date>T<Time> -
示例
:
2015-11-02T16:43:16.123+08:00
4. Duration 类型的显示格式化
implDisplayforDuration{fnfmt(&self, f:&mutfmt::Formatter)->fmt::Result{matchself{Duration::YMDHMS{
year, month, day,
hour, minute, second, millisecond,}=>{// 处理零持续时间特殊情况ifself.is_zero(){write!(f,"P0D")?;returnOk(());}write!(f,"P")?;// 持续时间必须以 P 开头// 日期部分(年月日)if*year >0{write!(f,"{}Y", year)?}if*month >0{write!(f,"{}M", month)?}if*day >0{write!(f,"{}D", day)?}// 时间部分(时分秒)以 T 开头if*hour >0||*minute >0||*second >0||*millisecond >0{write!(f,"T")?}if*hour >0{write!(f,"{}H", hour)?}if*minute >0{write!(f,"{}M", minute)?}// 秒和毫秒处理if*millisecond >0{write!(f,"{}.{}S", second, millisecond)?}elseif*second >0{write!(f,"{}S", second)?}Ok(())}Duration::Weeks(w)=>write!(f,"P{}W", w),}}}持续时间格式化规则
格式语法
P[nY][nM][nD][T[nH][nM][nS]]
具体格式化策略
零值特殊处理 :
-
所有单位都为0时输出
P0D - 避免空的持续时间字符串
-
所有单位都为0时输出
智能省略 :
- 只显示非零的时间单位
-
如果时间部分全部为零,则省略
T部分
时间部分分隔 :
-
日期和时间部分用
T明确分隔 -
即使日期部分为空,时间部分仍需要
T
-
日期和时间部分用
格式化示例
| 持续时间值 | 格式化输出 |
|---|---|
| 全零值 |
P0D
|
| 1年2个月 |
P1Y2M
|
| 3天4小时 |
P3DT4H
|
| 5分钟6秒 |
PT5M6S
|
| 7秒123毫秒 |
PT7.123S
|
| 复杂示例 |
P1Y2M3DT4H5M6.789S
|
| 8周 |
P8W
|
测试模块
回环测试设计
fntest_duration_reparse(duration:Duration){let serialized =format!("{}", duration);// 序列化为字符串let reparsed =parse_duration(serialized.as_bytes()).unwrap().1;// 重新解析assert_eq!(duration, reparsed);// 验证相等性}测试策略 :确保格式化输出的字符串能够被正确解析回原始值,验证双向转换的正确性。
具体测试用例
#[test]fndisplay_duration_0(){let duration =Duration::YMDHMS{
year:2021, month:11, day:16,
hour:23, minute:26, second:59, millisecond:0,};test_duration_reparse(duration);}#[test]fndisplay_duration_1(){let duration =Duration::YMDHMS{
year:2021, month:11, day:16,
hour:23, minute:26, second:59, millisecond:123,};test_duration_reparse(duration);}#[test]fndisplay_duration_2(){let duration =Duration::Weeks(50);test_duration_reparse(duration);}测试覆盖 :
- 整秒持续时间 :验证不含毫秒的格式化
- 含毫秒持续时间 :验证小数秒的格式化
- 周持续时间 :验证周格式的特殊处理
设计特点分析
符合标准性
- 严格遵循 ISO 8601 :所有输出格式都符合标准规范
-
正确的语法结构
:持续时间以
P开头,时间部分以T分隔
用户体验优化
- 简洁输出 :省略零值单位,避免冗长表示
-
特殊情形处理
:为零持续时间提供明确的
P0D表示 - 可读性 :格式清晰,易于人类阅读和理解
技术实现质量
-
模式匹配
:使用
match语句清晰处理不同变体 -
错误处理
:正确的
fmt::Result返回类型 -
格式化控制
:使用
{:04}等格式化指定符确保位数正确
可靠性保障
- 完整测试 :通过回环测试验证格式化的正确性
- 边界情况 :测试了零值、含毫秒、周数等边界情况
- 双向一致性 :确保序列化-反序列化的双向一致性
这个显示格式化模块为 ISO 8601 库提供了完整、标准兼容的输出功能,使得时间相关的数据类型可以方便地转换为人类可读的字符串表示,同时保证了与解析功能的双向一致性。


发布评论