- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我得到了一些用户输入的日期时间格式字符串,并且需要检查我可以解析该格式数据的 java.time
时间(在合理范围内,我打算只支持更简单的目前的案例)。
与此表类似的内容:
年月日
java.time.YearMonth
月/日/年
java.time.LocalDate
yyyy:DD
java.time.LocalDate
(因为日期数据)
HH:mm:ss
java.time.LocalTime
dd 月 yyyy hh:mm:ssV
java.time.ZonedDateTime
请记住,日期格式和日期都是由用户输入的,因此这些输入格式只是示例,它们显然可以包含文字(但不是可选部分,这是一种解脱)。
到目前为止,我只能想出这种 if
的 Tornado 作为解决方案:
private static final ZonedDateTime ZDT = ZonedDateTime.of(1990, 10, 26, 14, 40, 59, 123456, ZoneId.of("Europe/Oslo"));
...
String formatted = externalFormatter.format(ZDT);
Class<?> type;
TemporalAccessor parsed = externalFormatter.parse(formatted);
if (parsed.isSupported(YEAR)) {
if (parsed.isSupported(MONTH_OF_YEAR)) {
if (parsed.query(TemporalQueries.localDate()) != null) {
if (parsed.query(TemporalQueries.localTime()) != null) {
if (parsed.query(TemporalQueries.zone()) != null) {
type = ZonedDateTime.class;
}
else if (parsed.query(TemporalQueries.offset()) != null) {
type = OffsetDateTime.class;
}
else {
type = LocalDateTime.class;
}
}
else {
type = LocalDate.class;
}
}
else {
type = YearMonth.class;
}
}
else {
type = Year.class;
}
}
else if (parsed.query(TemporalQueries.localTime()) != null) {
if (parsed.query(TemporalQueries.offset()) != null) {
type = OffsetTime.class;
}
else {
type = LocalTime.class;
}
}
当然,一定有更好的方法,至少在一定程度上是这样?我不会限制自己只使用 java.time
,我也有可用的 Joda-Time 库(尽管它在技术上处于遗留状态),而且我不会拒绝使用更简单的代码SimpleDateFormat
如果有这样的选项。
最佳答案
我相信你的话:
Keeping in mind, that both the date format and the date are entered bythe user, …
所以我假设我可以同时使用格式模式和输入的日期字符串来查看我能用它做什么。 DateTimeFormatter::parseBest()
是我们需要的方法。
public static TemporalAccessor parse(String formatPattern, String toBeParsed) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatPattern, Locale.ROOT);
return formatter.parseBest(toBeParsed, ZonedDateTime::from,
LocalDate::from, LocalTime::from, YearMonth::from);
}
为了演示上述方法的强大功能,我使用了以下辅助方法:
public static void demo(String formatPattern, String toBeParsed) {
TemporalAccessor result = parse(formatPattern, toBeParsed);
System.out.format("%-21s %s%n", formatPattern, result.getClass().getName());
}
让我们用你的例子来调用它:
demo("yyyy-MM", "2017-11");
demo("MM/dd/yyyy", "10/21/2023");
demo("yyyy:DD", "2021:303");
demo("HH:mm:ss", "23:34:45");
demo("dd MM yyyy HH:mm:ssVV", "05 09 2023 14:01:55Europe/Oslo");
我已经更正了最后一个格式模式字符串中的几个错误。输出是:
yyyy-MM java.time.YearMonth
MM/dd/yyyy java.time.LocalDate
yyyy:DD java.time.LocalDate
HH:mm:ss java.time.LocalTime
dd MM yyyy HH:mm:ssVV java.time.ZonedDateTime
在 TemporalQuery
到 parseBest()
的参数列表中,必须将包含最多信息的类放在最前面。或者你更喜欢哪些类(class),但我假设你想要尽可能多的信息。 parseBest()
使用有效的第一个 查询。因此,如果您打算支持最后三个中的任何一个,请将 ZonedDateTime
放在第一位,然后将 Year
、 Month
和 DayOfWeek
放在最后。
请记住决定您想要的语言环境。
如果您打算在没有要解析的字符串的情况下执行此操作,那么它不会更复杂。首先使用您从格式模式字符串构建的格式化程序格式化一些 ZonedDateTime
。然后使用 parseBest()
解析返回的字符串。您必须使用 ZonedDateTime
,因为它是唯一一个包含格式模式字符串中可以想象的每个字段的类,因此对于其他一些类,格式设置可能会中断。另一方面,格式化字符串中的信息受模式限制,因此在大多数情况下,您将无法解析 ZonedDateTime
。这正是我们想要的:parseBest()
将告诉我们可以解析到哪个类。
public static Class<? extends TemporalAccessor> getParseableType(String formatPattern) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatPattern, Locale.ROOT);
String example = ZonedDateTime.now(ZoneId.systemDefault()).format(formatter);
TemporalAccessor parseableTemporalAccessor = formatter.parseBest(example, ZonedDateTime::from,
LocalDate::from, LocalTime::from, YearMonth::from);
return parseableTemporalAccessor.getClass();
}
关于java - 检查给定格式字符串可用于解析的 Temporal 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69746234/
如何使用 SPListCollection.Add(String, String, String, String, Int32, String, SPListTemplate.QuickLaunchO
我刚刚开始使用 C++ 并且对 C# 有一些经验,所以我有一些一般的编程经验。然而,似乎我马上就被击落了。我试过在谷歌上寻找,以免浪费任何人的时间,但没有结果。 int main(int argc,
这个问题已经有答案了: In Java 8 how do I transform a Map to another Map using a lambda? (8 个回答) Convert a Map>
我正在使用 node + typescript 和集成的 swagger 进行 API 调用。我 Swagger 提出以下要求 http://localhost:3033/employees/sear
我是 C++ 容器模板的新手。我收集了一些记录。每条记录都有一个唯一的名称,以及一个字段/值对列表。将按名称访问记录。字段/值对的顺序很重要。因此我设计如下: typedef string
我需要这两种方法,但j2me没有,我找到了一个replaceall();但这是 replaceall(string,string,string); 第二个方法是SringBuffer但在j2me中它没
If string is an alias of String in the .net framework为什么会发生这种情况,我应该如何解释它: type JustAString = string
我有两个列表(或字符串):一个大,另一个小。 我想检查较大的(A)是否包含小的(B)。 我的期望如下: 案例 1. B 是 A 的子集 A = [1,2,3] B = [1,2] contains(A
我有一个似乎无法解决的小问题。 这里...我有一个像这样创建的输入... var input = $(''); 如果我这样做......一切都很好 $(this).append(input); 如果我
我有以下代码片段 string[] lines = objects.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.No
这可能真的很简单,但我已经坚持了一段时间了。 我正在尝试输出一个字符串,然后输出一个带有两位小数的 double ,后跟另一个字符串,这是我的代码。 System.out.printf("成本:%.2
以下是 Cloud Firestore 列表查询中的示例之一 citiesRef.where("state", ">=", "CA").where("state", "= 字符串,我们在Stack O
我正在尝试检查一个字符串是否包含在另一个字符串中。后面的代码非常简单。我怎样才能在 jquery 中做到这一点? function deleteRow(locName, locID) { if
这个问题在这里已经有了答案: How to implement big int in C++ (14 个答案) 关闭 9 年前。 我有 2 个字符串,都只包含数字。这些数字大于 uint64_t 的
我有一个带有自定义转换器的 Dozer 映射: com.xyz.Customer com.xyz.CustomerDAO customerName
这个问题在这里已经有了答案: How do I compare strings in Java? (23 个回答) 关闭 6 年前。 我想了解字符串池的工作原理以及一个字符串等于另一个字符串的规则是
我已阅读 this问题和其他一些问题。但它们与我的问题有些无关 对于 UILabel 如果你不指定 ? 或 ! 你会得到这样的错误: @IBOutlet property has non-option
这两种方法中哪一种在理论上更快,为什么? (指向字符串的指针必须是常量。) destination[count] 和 *destination++ 之间的确切区别是什么? destination[co
This question already has answers here: Closed 11 years ago. Possible Duplicates: Is String.Format a
我有一个Stream一个文件的,现在我想将相同的单词组合成 Map这很重要,这个词在 Stream 中出现的频率. 我知道我必须使用 collect(Collectors.groupingBy(..)
我是一名优秀的程序员,十分优秀!