我的目标是 创建一个可以处理以下两个要求的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
根据各种搜索结果的分析,以下是我的理解:
尝试过这种方法,但没有奏效。 我无法将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中是否有任何强大的解决方案,即使预期的格式发生变化也可以自给自足。
答案 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
格式字符串表示“微秒”,并且不需要所有数字 - 因此您的时间戳可以包含任意数字X
格式字符串而不是Z
ParseException
- 使用此事件执行您想要的操作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)
JSR 310在java.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库,精确度为毫秒。
因此,在小数秒内没有足够的数字来满足您的需求。