繁体   English   中英

用于解析人类可读算术计算的日期库

[英]Date library for parsing human readable arithmetic calculations

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

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

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

我如何在 Java 中编写此代码? 或者是否有一些已经存在的库我应该使用而不是试图重新发明轮子?

这是一个起点。 我猜你会想进一步阐述它。

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 进一步的正则表达式将在最终解析为Period之前将其转换为8d
  • 禁止模棱两可的2m强制用户指定例如2m0d (2 个月 0 天)或2m0s (2 分 0 秒)。 或者强制大写M几个月,小写m分钟。
  • 复杂的部分:为无法解析的字符串提供有用的错误消息。

我认为几乎不可能(或至少很难)将每个可能的 String 输入转换为有效日期。 它甚至可能需要一些智能的自然语言处理。

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

Java的日期套餐是非常有用的,有方法的加和减天的给定数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM