用于解析人类可读算术计算的日期库[关闭]

问题描述 投票:1回答:2

我正在编写一个质量检查测试自动化程序,人们将使用算术运算输入具有诸如now - 5dyesterdaynow + 8 days之类值的人类可读持续时间字符串,我需要将其解析为Java 8 LocalDateTime实例。

简单地说,我需要像这样的实用程序:

LocalDateTime nowMinus5Days = DurationUtil.parseHumanReadableDuration("now - 5d")

java.time实用程序或其他实用程序是否已执行此操作,因此我不必从头开始实现某些功能?

java java.time
2个回答
1
投票
我认为几乎不可能(或至少很难)涵盖所有可能的String输入到有效日期的转换。它甚至可能需要一些智能的自然语言处理。

我建议使用一组公开的字段进行输入,并将它们convert传递给所需的对象。如果有最终用户,则可以让用户选择是要添加还是减去日期,然后显示一个文本输入框,以便在其中输入天数。您可以将“昨天”和“明天”之类的输入作为特殊输入处理。

Java的日期包非常有用,并且具有methods用于添加和减去给定的天数。


0
投票
这里是起点。我猜您将需要进一步详细说明。

private static Pattern relativeTimePattern = Pattern.compile("(\\w+)\\s*(?:([+-])\\s*(\\w+))?"); private static Map<String, Supplier<LocalDateTime>> bases = Map.of("now", () -> LocalDateTime.now(), "yesterday", () -> LocalDate.now().minusDays(1).atStartOfDay()); public static LocalDateTime parseRelativeTime(String timeString) { Matcher m = relativeTimePattern.matcher(timeString); if (m.matches()) { String baseString = m.group(1); LocalDateTime result = bases.get(baseString).get(); String signString = m.group(2); if (signString != null) { boolean subtract = signString.equals("-"); String diffString = m.group(3); TemporalAmount diff; try { diff = Period.parse("P" + diffString); } catch (DateTimeParseException dtpe) { // try a Duration instead diff = Duration.parse("PT" + diffString); } if (subtract) { result = result.minus(diff); } else { result = result.plus(diff); } } return result; } else { throw new IllegalArgumentException(); } }

让我们尝试一下:

System.out.println(parseRelativeTime("now - 5d")); System.out.println(parseRelativeTime("yesterday")); System.out.println(parseRelativeTime("now + 8d"));

我刚刚跑步时的输出:

2020-03-30T09:49:18.300731 2020-04-03T00:00 2020-04-12T09:49:18.307784
按照我的方法,它可以接受小写的nowyesterday中的任意一个,后跟一个符号(+-),并且

任一个]可以是年-月-周-天持续时间-小时-分钟-秒。后者中的每一个都必须使用一个字母缩写作为时间单位(y,m,w,d,h,m,s;当模棱两可的m单独出现时,将其视为月份)。期限或期限内不允许有空格。可以想到的进一步发展包括:

    添加更多单词:todaytomorrow;考虑允许使用大写和混合大小写。
  • [允许使用完整且有空格的单位,例如8 days。另一个正则表达式将在最终解析为8d之前将其转换为Period
  • [不允许模棱两可的2m强制用户指定例如2m0d(2个月0天)或2m0s(2分钟0秒)。或将大写字母M强制设置为几个月,将小写字母m强制设置为分钟。
  • 复杂的部分:为无法解析的字符串提供有用的错误消息。
© www.soinside.com 2019 - 2024. All rights reserved.