有没有人知道不同语言/区域设置的好日期解析器。 Java(SimpleDateFormat)的内置解析器非常严格。它应该用当前日期完成缺失的部分。
例如
编辑:我想解析用户的输入。例如,如果用户的区域设置日期格式为“dd.mm.yyyy”,并且用户仅键入“12.11”。那么解析器应该接受它作为值为“12.11.2008”的有效日期。目标是良好的可用性。
答案 0 :(得分:23)
检查Joda时间及其怪异Formatters。
Java 8 includes JSR-310所以这也是一个解决方案。
答案 1 :(得分:13)
答案 2 :(得分:8)
(为清晰起见而编辑)。
就个人而言,我认为严格是好的。许多不同的情况需要围绕宽松解析的不同规则,所以不可能将它全面地放入公共库中。
但是,我将彻底推荐Joda Time而不是内置的日期/时间类。他们的格式化程序和解析器是线程安全的和不可变的,这也有帮助。 Joda Time对轻松解析提供了一些支持,如另一个答案中所示,但您应该自己必须提供一些规则。
答案 3 :(得分:3)
如果你正在寻找可以解析自然“模糊”人类输入日期的东西,我会说JChronic。
我已经使用了JChronic和Chronic(最初的Ruby版本)并取得了巨大的成功。
答案 4 :(得分:3)
java.time.format.DateTimeFormatterBuilder::parseDefaulting
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 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和& SimpleDateFormat
现在位于Joda-Time的maintenance 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的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 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。
<块引用>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
从 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 desugaring 和 How 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还可以更好地完成与日期相关的所有操作。