首页> 疑难解答
Java字符串IsValid检查
withpy
2021-06-19
简介你有没有人指出为什么下面的例子给出了一个解析异常。 IDea是找到一个无效的日期,如Feb 30 String str =“20190310022817”; SimpleDateFormat sdf = new ...
你有没有人指出为什么下面的例子给出了一个解析异常。 IDea将找到像2月30日这样的无效日期
String str = "20190310022817";
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
sdf.setLenient(false);
try {
System.out.println(sdf.parseObject(str));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
投票
tl;dr
LocalDateTime
.parse(
"20190310022817" ,
DateTimeFormatter.ofPattern( "uuuuMMddHHmmss" )
)
.atZone(
ZoneId.of( "America/Montreal" )
)
结果是凌晨3点而不是凌晨2点。调整DST的功能,而不是错误。
2019-03-10T03:28:17-04:00 [美国/蒙特利尔]
如果您的目标是拒绝这些无效输入而不是调整它们,请参阅my Answer另一个解释ResolverStyle
枚举的问题:LENIENT
,SMART
和STRICT
。
Avoid legacy date-time classes
你正在使用几年前由现代java.time类取代的糟糕的日期时间类。
Daylight Saving Time (DST)
正如Answer by rgettman所指出的那样,一些疯狂到足以参加Daylight Saving Time (DST)的司法管辖区正在3月10日凌晨2点进行“春季前进”跳跃。这种情况发生在美国和加拿大的大部分地区,也可能发生在其他地方。请参阅维基百科有关DST in the United States的信息。
在这些地方,没有凌晨2点。当时钟到达凌晨2点时,时钟立即跳到凌晨3点。两点钟从未存在过。
顺便说一句,DST不是时钟变化的唯一方案。世界各地的政治家们都表示喜欢搞乱其所在地区的UTC偏移。例如,近年来见朝鲜,委内瑞拉,土耳其和俄罗斯。而现在美国的一些州正在选择停止DST废话,尽管有些人正在考虑永久保留DST。关键是,为了有效地处理日期时间,无论当前的做法如何,您都应该始终认为政治家将在未来的某个时刻做出改变,并相应地进行编码。
您的输入无效(可能)
您使用的旧类可能会拒绝您的输入为无效,因为您的JVM当前默认时区中的DST跳转是隐式应用的,因为您没有指明区域。解析有效值的这个严格协议没有错,只是处理无效输入的一种方法。
ZonedDateTime
类默认使用另一种方法,根据需要进行调整。
ZonedDateTime
java.time.ZonedDateTime
类知道时区的特定区域人员使用的UTC偏移的过去,现在和将来的变化历史。所以课程会自动调整。请务必阅读课程文档,以便了解并同意其调整协议。
LocalDateTime
这是一些示例代码。首先,我们将您的输入解析为LocalDateTime
,因为您的输入缺少时区或从UTC偏移的任何指示。因此,LocalDateTime
不代表片刻,不是时间轴上的一个点。因此,如果已知某个时区是针对该日期和时间,我们可以应用ZoneId
来获取ZonedDateTime
。
在这个例子中,我们任意选择两个区域来应用,这样你就可以看到不同的结果。在美国,3月10日是DST跳跃的那一天。在法国这样的欧洲大部分地区,跳跃计划在3月的最后一天进行。所以凌晨2点在法国有效,但在美国没有。
String input = "20190310022817";
DateTimeFormatter f = DateTimeFormatter.ofPattern( "uuuuMMddHHmmss" ) ;
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
ZoneId zParis = ZoneId.of( "Europe/Paris" ) ;
ZonedDateTime zdtParis = ldt.atZone( zParis ) ;
ZoneId zNewYork = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdtNewYork = ldt.atZone( zNewYork ) ;
转储到控制台。
System.out.println( "ldt.toString(): " + ldt ) ;
System.out.println( "zdtParis.toString(): " + zdtParis ) ;
System.out.println( "zdtNewYork.toString(): " + zdtNewYork ) ;
跑步时看到这个code run live at IdeOne.com。注意这三个输出中的每一个的小时:
- 前两个凌晨2点
- 最后一个凌晨3点
ldt.toString():2019-03-10T02:28:17
zdtParis.toString():2019-03-10T02:28:17 + 01:00 [欧洲/巴黎]
zdtNewYork.toString():2019-03-10T03:28:17-04:00 [America / New_York]
About java.time
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,如java.util.Date
,Calendar
和SimpleDateFormat
。
要了解更多信息,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规格是JSR 310。
现在在Joda-Time的maintenance mode项目建议迁移到java.time班。
您可以直接与数据库交换java.time对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*
类。
从哪里获取java.time类?
- Java SE 8,Java SE 9,Java SE 10,Java SE 11和更高版本 - 带有捆绑实现的标准Java API的一部分。 Java 9增加了一些小功能和修复。
- Java SE 6和Java SE 7 大多数java.time功能都在ThreeTen-Backport中反向移植到Java 6和7。
- Android 更高版本的Android捆绑java.time类的实现。 对于早期的Android(<26),ThreeTenABP项目适应ThreeTen-Backport(如上所述)。见How to use ThreeTenABP…。
ThreeTen-Extra项目使用其他类扩展了java.time。该项目是未来可能添加到java.time的试验场。你可能会在这里找到一些有用的类,如Interval
,YearWeek
,YearQuarter
和more。
投票
字符串"20190310022817"
代表2019年3月10日星期日2:28:17,由于夏令时而不存在,该节目在美国于2019年3月10日星期日2:00:00生效。
这意味着2019年3月10日星期日1:59:59之后的第二个星期日是2019年3月10日星期日3:00:00,所以那天2:28:17不存在(在那个小时内也没有任何其他秒) 。
您可以调整字符串中表示的时间,也可以识别此时间间隔不存在并适当处理异常。
投票
在欧洲,输出是Sun Mar 10 02:28:17 CET 2019
,因此您应该首先设置时区。
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault())
相关文章
-
R:通过删除和添加循环变量来迭代向量
考虑一个向量:昏暗
-
映射语句集合不包含mybatis映射器的值
我是用户mybatis和spring创建一些测试网站。现在我在尝试使用mybatis xml mapper时遇到了问题。问题类似于“java.lang.IllegalArgumentException:Mapped ...
-
将8位的BitSet写入文件(C ++)
我有一个8位的BitSet。如何将这8位转换为一个字节然后写入文件?我到处寻找,只找到转换的方式。非常感谢!
-
谷歌api获得特定用户谷歌页面审查
我想在登录我的应用时获取特定用户的Google页面评论和评分,我阅读了Google Bussiness API的文档https://developers.google.com/my-business/content / ...
-
使用DoCmd.RunSQL进行INSERT和DELETE时删除确认
我正在使用DoCmd.RunSQL方法根据用户在表单中执行的操作来INSERT和DELETE记录。它工作正常,但在删除或附加记录之前要求确认。怎么样 ...
-
什么导致未定义的方法`map!'对于ActiveRecord_Relation?
我正在从Rails 3更新到Rails 4.2,当我运行我的应用程序的测试套件时,我收到以下错误:失败/错误:得到'编辑',id:@shops [3] .id NoMethodError:未定义的方法`map! ” ...