是否有一个很好的Java日期解析器?

时间:2008-10-21 15:13:55

标签: java date parsing

有没有人知道不同语言/区域设置的好日期解析器。 Java(SimpleDateFormat)的内置解析器非常严格。它应该用当前日期完成缺失的部分。

例如

  • 如果我不输入年份(仅限日期和月份),则应使用当前年份。
  • 如果年份为08,则不应解析0008,因为当前年份模式有4位数。

编辑:我想解析用户的输入。例如,如果用户的区域设置日期格式为“dd.mm.yyyy”,并且用户仅键入“12.11”。那么解析器应该接受它作为值为“12.11.2008”的有效日期。目标是良好的可用性。

11 个答案:

答案 0 :(得分:23)

检查Joda时间及其怪异Formatters

Java 8 includes JSR-310所以这也是一个解决方案。

答案 1 :(得分:13)

来自43642,但不一定是重复:

请参阅Apache Commons'DateUtils。有一种parseDate方法可以让您String和多种模式尝试并吐出Date个实例。

答案 2 :(得分:8)

(为清晰起见而编辑)。

就个人而言,我认为严格是好的。许多不同的情况需要围绕宽松解析的不同规则,所以不可能将它全面地放入公共库中。

但是,我彻底推荐Joda Time而不是内置的日期/时间类。他们的格式化程序和解析器是线程安全的和不可变的,这也有帮助。 Joda Time对轻松解析提供了一些支持,如另一个答案中所示,但您应该自己必须提供一些规则。

答案 3 :(得分:3)

如果你正在寻找可以解析自然“模糊”人类输入日期的东西,我会说JChronic

我已经使用了JChronic和Chronic(最初的Ruby版本)并取得了巨大的成功。

答案 4 :(得分:3)

TL;博士

java.time.format.DateTimeFormatterBuilder::parseDefaulting

java.time

DateTimeFormatter类将字符串解析为日期时间对象。

您可以使用DateTimeFormatter类创建DateTimeFormatterBuilder的自定义实例。该构建器类使您可以为输入字符串的缺失组件指定默认值。

DateTimeFormatter f =
        new DateTimeFormatterBuilder()
                .appendPattern( "MM-dd" )
                .parseDefaulting(
                        ChronoField.YEAR ,
                        ZonedDateTime.now( ZoneId.of( "America/Montreal" ) ).getYear()
                )
                .toFormatter() ;

String input = "01-23" ;
LocalDate ld = LocalDate.parse( input , f ) ;

System.out.println( ld ) ;
  

ld.toString():2018-01-23

另见DateTimeFormatterBuilder with specified parseDefaulting conflicts for YEAR field

关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 5 :(得分:2)

SourceForge上的POJava项目有一个DateTime对象,可以解析多种语言的日期(当月份被指定为名称时),并且可以在MM-DD-YYYY和DD-MM-YYYY之间进行配置。它启发式地解析日期,挑选最可能的年,月,日,小时,分钟,秒和时区,而不是支持预定义的格式。 jar文件大小约为60K。

对于像“10-08”这样的日期的解释存在模糊性,因为它可以作为“2008-10-08”或“2008年10月”的简写。如果您接受在示例中给出的那种速记,您可以自己附加年份。

Proj:POJava 文档:HOWTO use DateTime

答案 6 :(得分:2)

您的第一个要求answered by Basil Bourque

<块引用>
  • 如果我不输入年份(只有日和月),则应使用当前年份。
  • 如果年份是 08,则不应解析 0008,因为当前年份模式有 4 位数字。

DateTimeFormatter 允许我们在方括号内指定可选模式。对于第二个要求,您可以在构建 [.[uuuu][uu]] 时指定可选模式 DateTimeFormatter

演示:

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Locale;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        // Replace JVM's ZoneId, ZoneId.systemDefault() with the applicable one e.g.
        // ZoneId.of("Europe/Berlin")
        int defaultYear = LocalDate.now(ZoneId.systemDefault()).getYear();

        DateTimeFormatter dtf = new DateTimeFormatterBuilder()
                                .appendPattern("dd.MM[.[uuuu][uu]]")
                                .parseDefaulting(ChronoField.YEAR, defaultYear)
                                .toFormatter(Locale.ENGLISH);
        
        // Test
        Stream.of(
                    "12.11",
                    "12.11.21",
                    "12.11.2021"
        ).forEach(s -> System.out.println(LocalDate.parse(s, dtf)));        
    }
}

输出:

2021-11-12
2021-11-12
2021-11-12

ONLINE DEMO

Trail: Date Time 了解有关现代 Date-Time API 的更多信息。


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 & 7. 如果您正在为 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

答案 7 :(得分:1)

使用DateFormat ...当前的标准,直到Joda的欢迎喘息。

答案 8 :(得分:1)

Calendar通常是要走的路,但要明白,如果您希望正确完成,大多数Java Date管理都将在您处理。如果您必须管理国际/跨区域信息,Timezone是一件好事。 Joda Time也是一个很好的东西,是JSR 310中添加到Java中的新建议的日期/时间概念背后的灵感。

希望这有用。

答案 9 :(得分:1)

我尝试在Java in this answer中实现可扩展的PHP strtotime

答案 10 :(得分:0)

我不得不为JodaTime说+1。除了解析之外,Joda还可以更好地完成与日期相关的所有操作。