Java时间戳接受短划线

时间:2018-01-31 19:32:02

标签: java regex timestamp simpledateformat datetime-parsing

我为HHMMSS.FFFFF格式化了一个正则表达式: ^([0-1] \ d | 2 [0-3])。([0-5] \ d)([0-5] \ d)(\ d {5})

以前用来创建SimpleDateFormat

 String format = "HHMMSS.FFFFF";
 SimpleDateFormat sdf = new SimpleDateFormat(format);

然后尝试使用以下数据创建时间戳

new Timestamp(sdf.parse("1-1212.00000).getTime());

使用

121212.00000

按预期好了。 然后尝试用这样的

来做
1-1212.00000

它仍然没有抛出异常。 在regex101上测试正则表达式时,短划线无效。

为什么Timestamp接受带有该正则表达式的破折号?

2 个答案:

答案 0 :(得分:3)

格式"HHMMSS.FFFFF"是:
HH =一天中的小时(0-23)
MM =一年中的月份 SS =毫秒
FFFFF =月中的某一天(DoWiM)

我不认为这是你的意思。但是,让我们继续吧。

请记住,所有其他字段都是默认字段,即
年= 1970年 DayOfMonth = 1
DayOfWeek =星期日
分钟= 0
秒= 0

输入000100.00001解析为1970-01-04 00:00:00.0,因为1/4/1970是第一个(DoWiM = 1)星期日(默认为DayOfWeek) 1月(月= 1)午夜(小时= 0,毫米= 0)
这是你的基准。

输入121212.00000会解析为1970-11-29 12:00:00.012,因为Month=12会使1970-12-06成为1970年12月的第一个星期日,而FFFFF=0则会在此之前一周。

输入1-1212.00000解析为1969-10-26 01:00:00.212,因为它解析为H=1, M=-1, S=212, F=0,即M=-1是1月前的2个月,1969-11-02是11月的第一个星期日1969年,而1969-10-26是在此之前的一周。

答案 1 :(得分:1)

  

我知道我没有问过这个但是HHmmss.SSSSS我应该使用什么?

你现在问了,谢谢你的询问。

    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HHmmss.SSSSS");
    String timeString = "121212.00000";
    LocalTime time = LocalTime.parse(timeString, dtf);
    System.out.println(time);

打印

12:12:12
来自LocalTime

java.time具有纳秒精度(秒数最多9位小数),但如果它为零,则toString方法不打印分数。例如,121212.34567被解析为12:12:12.345670。让我们用破折号尝试你的字符串,1-1212.00000。它会产生java.time.format.DateTimeParseException: Text '1-1212.00000' could not be parsed at index 0。正如您所料,格式化程序拒绝解析第二个数字是破折号时的小时数。这也意味着你在解析中有很好的验证,所以你不再需要任何正则表达式(正则表达式)。

TimestampSimpleDateFormat类都已经过时了,尽管后者是两者中比较麻烦的。同样SimpleDateFormat仅支持毫秒精度,它无法正确解析5位小数的秒数。在java.time包中找到现代替代品。使用DateTimeFormatter进行解析。我假设您想将没有日期的时间保存到SQL数据库中。如果是这样,请在Java中使用timeLocalTime的SQL数据类型。 PreparedStatement.setObject()会接受LocalTime保存。如果您的数据库列的类型为timestamp且无法更改,请改用LocalDateTime

虽然Andreas在评论中解释了为什么您建议的格式模式字符串HHmmss.SSSSS无法与SimpleDateFormat一起使用,但 DateTimeFormatter一起使用。这里大写S表示秒的分数,因此SSSSS表示五位小数(否则许多格式模式字母对两个格式化程序具有相同的含义,而不是全部)。

问题:我可以在Java 6中使用java.time吗?

是的,上面的大部分内容都适用于您的JavaSE 1.6,而不是PreparedStatement.setObject()。您需要将ThreeTen Backport添加到项目中。这是java.time向Java 6和7的后端(“ThreeTen”因为java.time在JSR-310中首次描述)。请参阅以下链接。

要保存到SQL数据库,您需要转换为旧式java.sql.Timestampjava.sql.Time。对于时间戳,您还需要一个日期。例如:

    LocalDate epochDate = LocalDate.ofEpochDay(0);
    Timestamp timeToSave 
            = DateTimeUtils.toSqlTimestamp(LocalDateTime.of(epochDate, time));

我参加了1970年1月1日的纪元日期,因为这也是你的时间字符串到Timestamp的正确解析所给你的。我认为你的DICOM可能会给你一个你想要使用的日期。 DateTimeUtils也有[{1}}方法将toSqlTime转换为LocalTime。链接到下面的文档。

链接