You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 04:25:06