Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 验证从csv获取的正确日期时间格式_Java_Date_Validation_Datetime_Java 8 - Fatal编程技术网

Java 验证从csv获取的正确日期时间格式

Java 验证从csv获取的正确日期时间格式,java,date,validation,datetime,java-8,Java,Date,Validation,Datetime,Java 8,我需要读取一个csv文件,它在一个时间戳列中具有不同的时间格式。它可以是下面提到的5种格式中的任何一种。我需要匹配获取的日期,并对每一行进行相应的解析。 请建议如何验证广告解析它。提前谢谢 publicstaticfinalstringdefault\u DATE\u FORMAT\u PATTERN=“yyyy-MM-dd”; 公共静态最终字符串默认\u日期\u时间\u格式\u模式=“yyyy-MM-dd HH:MM:ss.SSS”; 公共静态最终字符串日期\时间\分钟\仅限\格式\模式=“y

我需要读取一个csv文件,它在一个时间戳列中具有不同的时间格式。它可以是下面提到的5种格式中的任何一种。我需要匹配获取的日期,并对每一行进行相应的解析。 请建议如何验证广告解析它。提前谢谢

publicstaticfinalstringdefault\u DATE\u FORMAT\u PATTERN=“yyyy-MM-dd”;
公共静态最终字符串默认\u日期\u时间\u格式\u模式=“yyyy-MM-dd HH:MM:ss.SSS”;
公共静态最终字符串日期\时间\分钟\仅限\格式\模式=“yyyy-MM-dd HH:MM”;
公共静态最终字符串日期\u时间\u无\u毫秒\u格式\u模式=“yyyy-MM-dd HH:MM:ss”;
毫秒纪元

暴力手段:

  • 只需尝试4种格式,一种接一种地解析传入字符串
  • 如果解析引发异常,请尝试下一个异常
  • 如果解析通过,那么格式正好匹配
当然,如果我们谈论的是更大的桌子,这是相当低效的。可能的优化:

  • 显然,不同的模式有细微的差异,因此可以先使用
    indexOf()
    检查。Like:如果要分析的值不包含
    :'
    char,那么它只能是第一个模式
  • 您可以手动查看数据,以了解所使用模式的实际分布情况。然后调整模式的顺序,以尝试在数据中使用该模式的可能性

或者:您可以定义自己的正则表达式。唯一让它有点难看的是,您的输入使用的是月份名称,而不是月份编号。但是我认为编写一个涵盖所有情况的正则表达式应该不会太难。

您需要的是一个带有可选部分的格式化程序。图案可以包含方括号来表示可选零件,例如
HH:mm[:ss]
。然后,格式化程序需要解析
HH:mm
,并尝试将以下文本解析为
:ss
,如果解析失败,则跳过它<代码>yyyy-MM-dd[HH:MM[:ss[.SSS]]]将成为模式

这里只有一个问题–当您尝试使用
LocalDateTime::parse
解析带有模式
yyyy-MM-dd
(因此没有时间部分)的字符串时,它将抛出一个
DateTimeFormatException
,消息为无法从TemporalAccessor获取LocalDateTime。显然,至少要有一个时间段才能成功

幸运的是,我们可以使用
DateTimeFormatterBuilder
构建模式,指示格式化程序在解析文本中缺少信息时使用一些默认值。这是:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .appendPattern("yyyy-MM-dd[ HH:mm[:ss[.SSS]]]")
    .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
    .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
    .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
    .toFormatter();
LocalDateTime dateTime = LocalDateTime.parse(input, formatter);
测试:

String[] inputs = {
    "2020-10-22", // OK
    "2020-10-22 14:55", // OK
    "2020-10-22T14:55", // Fails: incorrect format
    "2020-10-22 14:55:23",
    "2020-10-22 14:55:23.9", // Fails: incorrect fraction of second
    "2020-10-22 14:55:23.91", // Fails: incorrect fraction of second
    "2020-10-22 14:55:23.917", // OK
    "2020-10-22 14:55:23.9174", // Fails: incorrect fraction of second
    "2020-10-22 14:55:23.917428511" // Fails: incorrect fraction of second 
};
那以毫为单位的纪元呢? 嗯,这不能由
DateTimeFormatter
直接解析。但更重要的是:以毫为单位的纪元有一个隐含的时区:UTC。其他模式缺少时区。因此,一个时代是一条根本不同的信息。您可以做的一件事是假设输入缺少一个时区


但是,如果您仍然想解析该瞬间,可以尝试使用
long::parseLong
将其解析为
long
,如果解析失败,则尝试使用格式化程序进行解析。或者,您可以使用正则表达式(如
-?\d+
或其他什么)尝试匹配瞬间,如果匹配了,则将其解析为瞬间,如果失败,则尝试使用上述格式化程序进行解析。

是的,但我不在这里创建格式。我首先需要从输入中找到模式,这可能是5种模式中的任何一种,然后需要对其进行解析。是的@GhostCat此数据来自不同的来源,因此有多种类型。因此,有太多的帖子用于相同/类似的要求,例如:-谢谢@ArvindKumarAvinash。这些链接很有用。很好!很高兴了解
DateTimeFormatterBuilder
:)@Eklavya是的,我认为
DateTimeFormatter
及其生成器是非常强大的工具。