如何在C#只读结构体中实现带对象值的时间字符串格式化?
解决24小时制readonly struct的格式化问题
首先,你的代码存在两个核心问题:一是Hours/Minutes属性的逻辑错误,二是字符串格式化的实现方式不对。以下是修正后的完整代码及关键说明:
修正后的完整代码
using System; namespace TimeStruct { public readonly struct Time { // 存储总分钟数,统一处理时间溢出问题 private readonly int _totalMinutes; // 仅传入分钟的构造函数 public Time(int minutes) { // 总分钟数对1440(24*60)取模,确保时间在0-23:59范围内 _totalMinutes = minutes % 1440; // 处理负数时间,比如-10分钟转为23:50 if (_totalMinutes < 0) _totalMinutes += 1440; } // 传入小时和分钟的构造函数 public Time(int hours, int minutes) // 转换为总分钟数后复用上面的构造函数 : this(hours * 60 + minutes) { } // 计算24小时制的小时数 public int Hours => _totalMinutes / 60; // 计算分钟数 public int Minutes => _totalMinutes % 60; // 返回格式化的时间字符串 public string ToFormattedString() { // 字符串插值+D2格式符:确保数字为两位,不足补0 return $"{Hours:D2}:{Minutes:D2}"; } // 重写默认ToString,方便直接输出 public override string ToString() { return ToFormattedString(); } } }
关键修正说明
1. 重构内部存储逻辑
原来的代码分别存储hours2和minutes2,导致溢出处理逻辑混乱。改为存储总分钟数,通过%1440直接将时间限制在24小时范围内,简化了时分计算,避免逻辑错误。
2. 字符串格式化的正确实现
你之前尝试的"0{stringtimeobj.hours}:0{stringtimeobj.minutes}"写法错误,正确的格式化方式有两种:
- 字符串插值(推荐):
$"{Hours:D2}:{Minutes:D2}",D2表示将数字格式化为两位,自动补0(比如8→"08",45→"45")。 - string.Format:
string.Format("{0:D2}:{1:D2}", Hours, Minutes),效果与插值一致。
3. 测试示例
使用修正后的结构体验证需求:
// 测试8小时45分钟 Time time1 = new Time(8, 45); Console.WriteLine(time1.ToFormattedString()); // 输出 "08:45" // 测试25小时160分钟 Time time2 = new Time(25, 160); Console.WriteLine(time2.ToFormattedString()); // 输出 "03:40"(25h160m = 27h40m,取模24后为3h40m)
原代码的逻辑错误说明
你原来的Hours属性第一个分支错误返回this.minutes2,属于笔误;后续溢出处理逻辑复杂且易出错。通过总分钟数计算时分的方式,能彻底避免这类问题,代码更简洁可靠。
内容的提问来源于stack exchange,提问作者Akzhol
相关产品推荐
相关产品推荐

