datetime - Java 8 Vavr onFailure 连接
问题描述
我试图解析一个包含未知格式日期的字符串,而我选择的方式(不是最好的)是尝试所有可能的格式,直到正确解析。为此,我使用 Vavr 库,直到现在我已经创建了这样的东西:
// My unknown date
String date = "2020-11-12T15:15:15.345";
// Date format that works for my unknown date (just for testing)
DateTimeFormatter FORMATTER = new DateTimeFormatterBuilder()
.appendPattern("yyyy-MM-dd'T'HH:mm:ss[.SSS]")
.parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
.toFormatter();
OffsetDateTime value = OffsetDateTime.parse(date, FORMATTER); // PARSE CORRECTLY
// Try all possible formats until one works
Try<OffsetDateTime> myParsedDate = Try.of(()->date)
.map(x->OffsetDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd")))
.onFailure(x->System.out.println("NO yyyy-MM-dd"))
.map(x->OffsetDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS+HH:mm")))
.onFailure(x->System.out.println("NO yyyy-MM-dd'T'HH:mm:ss.SSS+HH:mm"))
.map(x->OffsetDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS+HH:mm")))
.onFailure(x->System.out.println("NO yyyy-MM-dd'T'HH:mm:ss.SSS+HH:mm"))
.map(x->OffsetDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")))
.onFailure(x->System.out.println("NO yyyy-MM-dd'T'HH:mm:ss.SSS"))
.map(x->OffsetDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ")))
.onFailure(x->System.out.println("NO yyyy-MM-dd'T'HH:mm:ss.SSSZ"))
.map(x->OffsetDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")))
.onFailure(x->System.out.println("NO yyyy-MM-dd'T'HH:mm:ss"))
.map(x->OffsetDateTime.parse(date, FORMATTER)) // DOSENT WORK
.onFailure(x->System.out.println("NO yyyy-MM-dd'T'HH:mm:ss[.SSS]"));
if(myParsedDate.isSuccess()) {
System.out.println("OK");
}else {
System.out.println("KO");
}
输出:
NO yyyy-MM-dd
NO yyyy-MM-dd'T'HH:mm:ss.SSS+HH:mm
NO yyyy-MM-dd'T'HH:mm:ss.SSS+HH:mm
NO yyyy-MM-dd'T'HH:mm:ss.SSS
NO yyyy-MM-dd'T'HH:mm:ss.SSSZ
NO yyyy-MM-dd'T'HH:mm:ss
NO yyyy-MM-dd'T'HH:mm:ss[.SSS]
问题是:如何连接许多 try/catch 或者在这种情况下使用 VAVR 许多动作,当一个动作失败时尝试下一个动作等等?谢谢
解决方案
用 vavr 回答
import io.vavr.collection.Iterator;
String[] patterns = new String[] {
"yyyy-MM-dd",
"yyyy-MM-dd'T'HH:mm:ss.SSS+HH:mm",
"yyyy-MM-dd'T'HH:mm:ss.SSS",
"yyyy-MM-dd'T'HH:mm:ss.SSSZ",
"yyyy-MM-dd'T'HH:mm:ss"
};
final Option<OffsetDateTime> offsetDateTimeOption =
Iterator.of(patterns) // 1
.map(DateTimeFormatter::ofPattern) // 2
.concat(Iterator.of(FORMATTER)) // 3
.map(formatter -> Try.of(() -> OffsetDateTime.parse(date, formatter))) // 4
.flatMap(Try::iterator) // 5
.headOption(); // 6
脚步
Iterator
从对模式数组的惰性开始- 转换为格式化程序
- 将后备格式化程序附加到
Iterator
- 使用格式化程序解析日期,将结果包装在
Try
- 通过
Iterator<Try<OffsetDateTime>>
从Iterator<OffsetDateTime>
每个Try
. try 上的迭代器如果成功则为单元素迭代器,如果失败则为空迭代器 - 获取结果迭代器的第一个元素,
Some
如果它不为空,则将其作为 a 返回或返回 aNone
上面的管道是惰性的,也就是说,它只尝试尽可能多的模式/格式化程序来找到第一个成功的,因为 vavrIterator
本身就是惰性的。
我的回答只关注如何在vavr首次成功之前进行惰性评估,我没有尝试纠正您的问题的其他方面,这些方面会导致您的模式与显然符合其中一些模式的日期字符串不匹配。您的问题的其他答案详细介绍了我不想在这里重复的内容。
推荐阅读
- javascript - 如何在功能完全完成之前禁用表单按钮
- cluster-computing - 从模板创建 dataproc 集群
- flutter - Flutter:'Future.wait' 并行的多个异步函数 VS 'await' 一次一个。<= 不同的结果
- javascript - 将 js 数组发布到 PHP 并在数据库查询中使用它
- python - 从 boto3 客户端获取重试次数
- outlook - 无法取消 ical 事件(可怕的“不支持的日历 message.ics”)
- r - 如何在我的 ODBC 连接对象中引用表名?
- algorithm - 求解决paint-tool-puzzle的案例数
- r - R:如何将列中的值转换为行数?
- sql - Redshift - 如何合并并沿行维度添加?