为了账号安全,请及时绑定邮箱和手机立即绑定

安全简单日期格式解析

安全简单日期格式解析

幕布斯6054654 2022-09-28 16:13:03
我有一小块代码,它从响应本身解析响应生成时间,并将其转换为日期以供将来使用。它是这样的:SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); Date responseTime = sdf.parse(RStime);它几乎像一个魅力。确切地说,它的工作时间为99.9%,但有一种情况除外:当毫秒部分是000时,服务器根本不会附加.000毫秒,因此我们有一个问题。现在,根据简单日期格式文档,如果解析失败,该函数将返回null。但是,我可能误解了它,因为它只是抛出了一个异常。我对Java和试探机制非常陌生,所以任何人都可以为处理这种情况提供一个优雅的良好实践解决方案吗?谢谢!
查看完整描述

4 回答

?
白衣非少年

TA贡献1155条经验 获得超0个赞

时间

String rsTime = "2018-04-09T10:47:16.999-02:00";

OffsetDateTime responseTime = OffsetDateTime.parse(rsTime);

System.out.println("Parsed date and time: " + responseTime);

此代码段的输出为:


解析日期和时间: 2018-04-09T10:47:16.999-02:00


它也适用于省略了000毫秒的版本:


String rsTime = "2018-04-09T10:47:16-02:00";

解析时间: 2018-04-09T10:47:16-02:00


您使用的类 和 ,设计得很差,而且已经过时了(前者尤其麻烦)。因此,我不仅在这种情况下建议使用java.time,即现代Java日期和时间API。但是,来自服务器的字符串采用ISO 8601格式,并且其他类java.time将此格式解析为其默认格式,即没有任何显式格式化程序,这已经使任务变得非常容易。此外,在标准中,秒的小数部分是可选的,这就是为什么字符串的两个变体都被解析而没有任何问题的原因。 还会从它的方法打印回ISO 8601,这就是为什么在这两种情况下都会打印与解析的字符串相同的字符串。SimpleDateFormatDateOffsetDateTimeOffsetDateTimetoString


只有在您不可避免地需要一个老式对象来制作您现在无法更改的旧版API时,请像这样转换:Date


Instant responseInstant = responseTime.toInstant();

Date oldfashionedDateObject = Date.from(responseInstant);

System.out.println("Converted to old-fashioned Date: " + oldfashionedDateObject);

我在欧洲/哥本哈根时区的计算机上的输出是:


转换为老式日期: 星期一 Apr 09 14:47:16 CEST 2018


链接: 甲骨文教程: 日期时间解释如何使用 java.时间.


查看完整回答
反对 回复 2022-09-28
?
波斯汪

TA贡献1811条经验 获得超4个赞

根据您提到的简单日期格式文档,该方法:parse


public Date parse(String text, ParsePosition pos)


抛出:


空点异常 - 如果文本或 pos 为空。


因此,一种选择是捕获该异常并在捕获中执行所需的操作,例如:


SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");

try {

  Date responseTime = sdf.parse(RStime, position);

} catch (NullPointerException e) {

  e.printStackTrace();

  //... Do extra stuff if needed

}

或者从日期格式继承的方法:


public Date parse(String source)


抛出:


解析异常 - 如果无法解析指定字符串的开头。


SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");

try {

  Date responseTime = sdf.parse(RStime);

} catch (ParseException e) {

  e.printStackTrace();

  //... Do extra stuff if needed

}


查看完整回答
反对 回复 2022-09-28
?
Helenr

TA贡献1780条经验 获得超3个赞

您可以检查点,然后使用第一种或第二种格式:


String timeString = "2018-04-09T10:47:16.999-02:00";

//String timeString = "2018-04-09T10:47:16-02:00";

String format = timeString.contains(".") ? "yyyy-MM-dd'T'HH:mm:ss.SSSXXX" : "yyyy-MM-dd'T'HH:mm:ssXXX";

Date responseTime = new SimpleDateFormat(format).parse(timeString);

System.out.println("responseTime: " + responseTime);

如果您注释掉第一行,注释第二行并再次运行它,它将打印出来:


responseTime: Mon Apr 09 14:47:16 CEST 2018

顺便一提:


Java 7(您显然使用的版本)返回一个java.text.ParseException: Unparseable date: "2018-04-09T10:47:16-02:00"


自 Java 8 起支持可选选项。


查看完整回答
反对 回复 2022-09-28
?
动漫人物

TA贡献1815条经验 获得超10个赞

这真的是一个特殊情况吗?如果不是,那么在这种情况下,您可能不应该使用异常。在我看来,时间以.000ms结束是正常的。在这种情况下,您可以检查字符串是否包含(点),如果没有,则将.000附加到末尾。.


if(!RStime.contains(".")){

    RStime+=".000";

}

编辑:我忘记了时间字符串中的时区。为此,您可能需要一些更复杂的东西。像这样的事情应该这样做:


if(!RStime.contains(".")){

    String firstPart = RStime.substring(0, 21);

    String secondPart = RStime.substring(21);

    RStime = firstPart + ".000" + secondPart;

}


查看完整回答
反对 回复 2022-09-28
  • 4 回答
  • 0 关注
  • 111 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信