Java:自定义时间戳格式:验证格式为microsec精度

时间:2013-09-16 03:50:56

标签: java timestamp

我的目标是 创建一个可以处理以下两个要求的java类

(A)1。验证时间戳的格式是否与预期格式匹配。
CCYY-MM-DD'T'hh:MM:ss'.0000000000 +“恩:嗯”
例如:预期的格式不是静态的。

可能是其中之一     “2013-09-10T18:30:20.123456 + 10:00”或     “2013-09-10T18:30:20.123 + 10:00”。
我对此并不感到困扰     精度和价值。只有格式很重要。

(B)2。验证时间戳是否在某个范围内。
例如:验证时间戳是否在     在“2013-09-10 18:27”和“2013-09-10 18:33”之间。 (验证仅达到微小级精度)(可能是+或 - 2min的增量)


  

正如其中一位成员所建议的那样,我已经编辑了这个目标   一个具体的问题。

问题:

如何使用JAVA类验证自定义时间戳达到微精度?

这个类的两个参数将是

1)预期格式为字符串

2)时间戳值为String

根据各种搜索结果的分析,以下是我的理解:

  1. Java(默认情况下)不解析/格式化微秒级别的时间戳(我使用的是SimpleDateFormat)
  2. 如果以毫秒为单位给出6位数,则会将该值重新计算为秒,并且将更新dateformat,新的dateformat将具有3位精确的毫秒数。
  3. 我还看到了一个建议使用java.sql.Timestamp的线程。
  4. 尝试过这种方法,但没有奏效。 我无法将strTimestamp 2013-09-10T18:30:20.123456 + 10:00转换为Timestamp对象。

    Timestamp ts = Timestamp.valueOf(strTimestamp); 
    java.lang.IllegalArgumentException: 
     Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]
    

    我无法将输入格式转换为Timestamp对象。


    我有一个使用正则表达式验证的解决方法:

    2013-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T(0[0-9]|1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9]):(0[0-9]|[1-5][0-9]).[0-9][0-9][0-9][0-9][0-9][0-9]\+10:00
    

    此注册表的问题在于,我预期的时间戳格式不是静态的。所以我必须为每种模式使用正则表达式。

    所以我想弄清楚java中是否有任何强大的解决方案,即使预期的格式发生变化也可以自给自足。

3 个答案:

答案 0 :(得分:0)

java.sql.Timestamp无法帮助您,因为 java.util.Date

代码非常简单,如果你使用正确格式的字符串SimpleDateFormat,那么你就可以轻松解决问题。这是一个完整的工作解决方案:

public static boolean isNear(String timestamp, int microPlaces, Date near, int minutes) {
    if (!timestamp.matches(".*\\.\\d{" + microPlaces + "}\\D.*") {
        return false;
    }
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSSSSZ");
    try {
        Date date = sdf.parse(timestamp.replaceAll(":(?=\\d\\d$)", ""));
        return Math.abs(date.getTime() - near.getTime()) <= minutes * 60000;
    } catch (ParseException ignore) {
        return false; // string was not of correct format
    }
}

这可能与您的想法不完全相同 - 如果没有,您应该能够将其作为您想要的基础。关键点是:

  • S格式字符串表示“微秒”,并且不需要所有数字 - 因此您的时间戳可以包含任意数字
  • Java 6需要从时区删除冒号。 Java 7不需要这样 - 使用X格式字符串而不是Z
  • 无法从输入中解析日期会引发ParseException - 使用此事件执行您想要的操作
  • 我选择让API给出范围的中心日期和+/-分钟值。您可能需要通过两个日期 - 由您决定。如果您这样做,请使用Date.before()Date.after()进行比较。

以下是测试您的示例和一些边缘情况的测试代码:

public static void main(String[] args) throws Exception {
    Date near = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm").parse("2013-09-10T18:32");
    System.out.println(isNear("2013-09-10T18:30:20.123456+10:00", near, 2));
    System.out.println(isNear("2013-09-10T18:30:20.123+10:00", near, 2));
    System.out.println(isNear("2013-09-10T18:10:20.123+10:00", near, 1));
    System.out.println(isNear("XXXX-09-10T18:10:20.123+10:00", near, 1));
}

输出:

true
true
false
false

答案 1 :(得分:0)

我真的想找到这个问题的答案。因为我没有能力为波西米亚的答案添加评论。我想提一下,SimpleDateFormat中的'S'模式不是用于微秒,而是用于毫秒。这意味着对于模式“yyyy-MM-dd'T'hh:mm:ss.SSSSSSZ”,字符串中的微秒数字将被解析为毫秒。 所以前三个数字将作为XXX秒传递,它们的值将被添加到日期。所以我们可以在16分钟内收到错误。

答案 2 :(得分:0)

Java 8中的java.time

JSR 310java.time package中定义了新的Java 8。它的日期时间类解析为纳秒。这给你小数点后的9位数。

java.time包的灵感来自Joda-Time,但完全重新构建。概念很相似。

与Joda-Time一样,java.time包使用ISO 8601格式作为解析和格式化的默认值。因此,您可以输入或输出2013-09-10T18:30:20.123456789+10:00等字符串。

Java 8的早期版本现已上市。官方发布应该是本月。

正在将这个包反向移植到早期版本的Java的项目正在进行中。我不知道它目前的状况或成功。 backport项目独立于Oracle和OpenJDK项目。

毫秒

旧的捆绑类,java.util.Date&amp; .Calendar,使用毫秒精度。

同样适用于优秀的Joda-Time库,精确度为毫秒。

因此,在小数秒内没有足够的数字来满足您的需求。