当前位置: 首页 > news >正文

DateTime::ToString 日期时间文本格式化深度解析(C++)

⚙️ DateTime::ToString 日期时间文本格式化深度解析(C++)

——结构、流程、原理与完整实现

引用

  1. ppp/DateTime.cpp#L139
  2. 家山别矣 想念天涯子 怅然老矣 我共二三子 惶然梦矣 梦也徘徊起
  3. 暮暮朝朝 老去吟游 离魂无据 梦里痴痴语
🏗️ 一、整体结构
DateTime
-int year
-int month
-int day
-int hour
-int minute
-int second
-int millisecond
-int64_t microseconds
-int64_t total_hours
+ToString(const char* format, bool fixed) : noexcept
#PaddingLeft()

组成模块

  1. 格式解析器:扫描格式字符串,识别yMdHmsfuT格式符
  2. 状态追踪器:使用symbolsymbol_size跟踪当前格式组
  3. 组件处理器:将时间分量转换为字符串
  4. 宽度控制器:实现fixed模式下的截断/补零
  5. 字符串构建器:拼接最终结果

🔄 二、处理流程
非空
相同
不同
循环
循环
开始
format
非空?
返回空字符串
初始化状态
遍历格式字符串
读取字符ch
是否格式符?
与当前
symbol相同?
增加symbol_size
处理当前组
设置新symbol
ProcessGroup
添加字面字符
结束?
返回结果
⏱️ 三、格式处理原理

关键算法

while (*format) {ch = *format++;if (是格式符(ch)) {if (symbol != 0 && symbol != ch) {symbol_exec(0); // 提交当前组}symbol = ch;        // 设置新符号symbol_size++;      // 增加计数} else {symbol_exec(ch);    // 提交组并添加字面值}
}
symbol_exec(0); // 处理剩余组

符号处理器行为

000001010202030304获取分量值 fixed宽度调整 添加字面字符 重置状态 处理流程symbol_exec处理流程

🛠️ 四、完整代码实现
ppp::string DateTime::ToString(const char* format, bool fixed) noexcept {ppp::string result;if (NULL == format || *format == '\x0') {return result;}char symbol = 0;int symbol_size = 0;auto symbol_exec = int ch noexcept {ppp::string seg;switch (symbol) {case 'y': seg = stl::to_string<ppp::string>(Year()); break;case 'M': seg = stl::to_string<ppp::string>(Month()); break;case 'd': seg = stl::to_string<ppp::string>(Day()); break;case 'H': seg = stl::to_string<ppp::string>(Hour()); break;case 'm': seg = stl::to_string<ppp::string>(Minute()); break;case 's': seg = stl::to_string<ppp::string>(Second()); break;case 'f': seg = stl::to_string<ppp::string>(Millisecond()); break;case 'u': seg = stl::to_string<ppp::string>(Microseconds()); break;case 'T': seg = stl::to_string<ppp::string>((int64_t)TotalHours()); break;}if (fixed && symbol != 0) {int64_t seg_size = seg.size();if (seg_size > symbol_size) {seg = seg.substr(seg_size - symbol_size);} else if (seg_size < symbol_size) {seg = PaddingLeft(seg, symbol_size, '0');}}if (ch != 0) {seg.append(1, ch);}result += seg;symbol = 0;symbol_size = 0;};const char* p = format;while (*p) {char ch = *p++;if (ch == 'y' || ch == 'M' || ch == 'd' || ch == 'H' || ch == 'm' || ch == 's' || ch == 'f' || ch == 'u' || ch == 'T') {if (symbol != 0 && symbol != ch) {symbol_exec(0);}symbol = ch;symbol_size++;} else {symbol_exec(ch);}}symbol_exec(0);return result;
}template <typename _Ty>
_Ty DateTime::PaddingLeft(const _Ty& s, int count, char padding_char) noexcept {int string_length = static_cast<int>(s.size());if (count < 1 || count <= string_length) {return s;}_Ty r = s;for (int i = 0; i < count - string_length; i++) {r = _Ty(1ul, padding_char) + r;}return r;
}

🔍 五、核心机制剖析
1. 格式符处理矩阵
输入当前状态动作
新符号symbol相同symbol_size++
新符号symbol不同提交旧组,开始新组
非符号有状态提交组,添加字面值
非符号无状态直接添加字面值
2. fixed模式控制逻辑
直接输出
seg.size > symbol_size
seg.size < symbol_size
CheckLength
过长
截断方向
低位
过短
填充方向
左侧
填充字符
'0'
相等
3. 时间分量映射关系
y
年份
M
月份
d
日期
H
小时
m
分钟
s
秒钟
f
毫秒
u
微秒
T
总小时数

💡 六、应用场景示例

1. 标准日期格式

// 输出:2025-07-29
ToString("yyyy-MM-dd", true)

处理流程

格式解析器状态追踪结果生成"yyyy" → symbol='y', size=4'-' → 非符号提交组 → "2025"添加"-""MM" → symbol='M', size=2'-' → 非符号提交组 → "07"(补齐)添加"-""dd" → symbol='d', size=2提交组 → "29"格式解析器状态追踪结果生成

2. 精确时间戳

// 输出:23:38:03.000000
ToString("HH:mm:ss.ffffff", false)

3. 压缩日期格式

// 输出:25/7/29
ToString("yy/M/d", true)

📌 总结要点

  1. 状态驱动设计:双变量(symbol/size)实现高效状态跟踪
  2. 分层处理架构
    • 格式扫描 → 状态管理 → 分量转换 → 宽度控制 → 结果构建
  3. 关键处理流程
  4. 流程子图
1
格式解析
格式解析
1
识别格式符 (5%)
识别格式符 (5%)
分量获取
分量获取
1
调用成员函数 (5%)
调用成员函数 (5%)
字符串处理
字符串处理
1
fixed模式调整 (4%)
fixed模式调整 (4%)
结果构建
结果构建
1
拼接最终字符串 (4%)
拼接最终字符串 (4%)
数据转换流程
  1. 核心算法

    • 线性扫描格式字符串 O(n)
    • 状态变更触发分组处理
    • 数值到字符串的精确转换
  2. 流程子图

格式符
非格式符
过长
过短
相等
开始解析
扫描格式字符串
是否与当前
符号相同
增加计数器
提交当前组
处理字符
获取时间分量
转字符串
fixed模式?
调整宽度
加入结果
截断末尾
左侧补零
添加为字面字符
继续扫描
是否结束
提交末组
返回结果

“日期格式化是时间数据的符号化表达——状态机驱动字符串的精密重组”

http://www.dtcms.com/a/303930.html

相关文章:

  • Mysql InnoDB存储引擎
  • 2.快速开始
  • Windows下基于 SenseVoice模型的本地语音转文字工具
  • 【Linux我做主】探秘进程状态
  • 聚铭安全管家平台2.0实战解码 | 安服篇(三):配置保障 自动核查
  • 从单机架构到分布式:Redis为何成为架构升级的关键一环?
  • OpenLayers 综合案例-底图换肤(变色)
  • DevOps 详解
  • Linux -- 文件【中】
  • CVE-2022-46169漏洞复现
  • DNS污染与劫持
  • 《林景媚与命运协议》
  • 服务器数据恢复—RAID上层部署的oracle数据库数据恢复案例
  • logtrick 按位或最大的最小子数组长度
  • JavaWeb(苍穹外卖)--学习笔记15(分页查询PageHelper)
  • Unity_UI_NGUI_DrawCall
  • Mac安装Navicat步骤Navicat Premium for Mac v17.1.9【亲测】
  • 【腾讯云】EdgeOne网站安全防护的配置方法 防范盗刷流量 附恶意IP和UA黑名单
  • 学习网址备份(二)
  • Linux 启动流程、密码破解、引导修复完全手册
  • 【智能协同云图库】智能协同云图库第八弹:基于阿里云百炼大模型—实现 AI 扩图功能
  • haproxy应用详解
  • 创建型设计模式-工厂方法模式和抽象工厂方法模式
  • 云端文档管理新纪元:Paperless-ngx与cpolar打造的无边界文件生态
  • Ext JS极速项目之 Coworkee
  • 在WSL中配置VS Code C++开发环境完整教程
  • Java抽Oracle数据时编码问题
  • 百元级工业级核心板:明远智睿×瑞萨V2H,开启AIoT开发新纪元
  • 论文阅读:LMM-Det: Make Large Multimodal Models Excel in Object Detection
  • 从0到1学PHP(三):PHP 流程控制:掌控程序的走向