NodaTime.DurationPattern无分隔符解析HHmm时长失败求助
如何用NodaTime.DurationPattern解析无分隔符的HHmm格式时长?
我需要用HHmm格式(无分隔符的四位数字,前两位小时、后两位分钟)表示时长,根据NodaTime文档,该格式应该可以被DurationPattern解析且被列为可用示例,但实际测试发现必须在小时和分钟间添加分隔符(如HH|mm)才能正常解析,无分隔符的HHmm格式解析失败。
测试代码如下:
public void ConvertWithPattern() { var result1 = DurationPattern.CreateWithInvariantCulture("HH mm").Parse("12 13"); var result2 = DurationPattern.CreateWithInvariantCulture("HHmm").Parse("1213"); Assert.True(result1.Success); Assert.Equal(12, result1.Value.Hours); Assert.Equal(13, result1.Value.Minutes); Assert.True(result2.Success); // 此处断言失败 Assert.Equal(result1, result2); }
失败时返回UnparsableValueException,错误信息为:
The value string does not match the required number from the format
string "mm". Value being parsed: '1213^'. (^ indicates error
position.)
解决方案:使用带显式宽度限定的格式字符串
默认的HHmm格式字符串无法正常解析,是因为NodaTime的DurationPattern在处理无分隔符的数字组件时,无法自动区分不同字段的边界——它会尝试把整个字符串匹配给第一个数字字段,导致后续字段没有剩余字符可解析。
要解决这个问题,需要在格式字符串中为每个数字组件显式指定宽度,告诉解析器每个字段占用的字符数:
var pattern = DurationPattern.CreateWithInvariantCulture("%2H%2m"); var result = pattern.Parse("1213"); Assert.True(result.Success); Assert.Equal(12, result.Value.Hours); Assert.Equal(13, result.Value.Minutes);
原理说明
%2H表示匹配固定2位的小时数(范围00-99)%2m表示匹配固定2位的分钟数(范围00-59)
通过显式指定宽度,解析器就能准确拆分1213为前两位的12(小时)和后两位的13(分钟),完成正确解析。
备选方案:手动拆分字符串后构造Duration
如果不想使用自定义格式字符串,也可以手动拆分输入字符串,再直接构造Duration对象:
var input = "1213"; int hours = int.Parse(input.Substring(0, 2)); int minutes = int.Parse(input.Substring(2, 2)); var duration = Duration.FromHours(hours) + Duration.FromMinutes(minutes);
内容的提问来源于stack exchange,提问作者mcwyrm
相关产品推荐
相关产品推荐

