我正在使用SimpleDateFormat将时间的字符串类型转换为unix时间戳,但是当我将timezone设置为非法值时,我仍然可以获得正确的结果,这是SimpleDateFormat.parse()方法的定义方式吗?如果我想进行单元测试以测试失败案例,该怎么办?
String str = "2016-06-21-10-19-22";
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss");
df.setTimeZone(TimeZone.getTimeZone("fewfefewf"));
Date date = df.parse(str);
long epoch = date.getTime();
System.out.println(epoch);
答案 0 :(得分:1)
如果无法理解指定的TimeZone,是因为getTimeZone方法返回默认的GMT
区域
指定的时区,如果无法理解给定的ID,则为GMT区域。
如果建议使用TimeZone.getAvailableIDs进行验证,则可以轻松检查输入时区是否有效
Arrays.stream(TimeZone.getAvailableIDs()).anyMatch(tz->tz.equals("fewfefewf"))
最后的建议是使用j ava-8 date time api类,并开始远离SimpleDateFormat
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss"); // make sure you use H for hours in format
LocalDateTime dateTime = LocalDateTime.parse(str,formatter);
答案 1 :(得分:0)
我建议您使用java.time(现代的Java日期和时间API)进行日期和时间工作。它的许多优点之一是,在许多情况下,它比诸如TimeZone
,SimpleDateFormat
和Date
之类的旧类为您提供更好的验证。这是我的等效代码的镜头:
String str = "2016-06-21-10-19-22";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd-hh-mm-ss");
ZonedDateTime dateTime = LocalDateTime.parse(str, dtf)
.atZone(ZoneId.of("fewfefewf"));
long epoch = dateTime.toInstant().toEpochMilli();
System.out.println(epoch);
运行它会产生:
Exception in thread "main" java.time.format.DateTimeParseException: Text '2016-06-21-10-19-22' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {MicroOfSecond=0, MinuteOfHour=19, NanoOfSecond=0, MilliOfSecond=0, SecondOfMinute=22, HourOfAmPm=10},ISO resolved to 2016-06-21 of type java.time.format.Parsed at java.base/java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:2017) at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1952) at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:492) at ovv.misc.MiscTest.<init>(MiscTest.java:72) at ovv.misc.MiscTest.main(MiscTest.java:61) Caused by: java.time.DateTimeException: Unable to obtain LocalDateTime from TemporalAccessor: {MicroOfSecond=0, MinuteOfHour=19, NanoOfSecond=0, MilliOfSecond=0, SecondOfMinute=22, HourOfAmPm=10},ISO resolved to 2016-06-21 of type java.time.format.Parsed at java.base/java.time.LocalDateTime.from(LocalDateTime.java:461) at java.base/java.time.format.Parsed.query(Parsed.java:235) at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1948) ... 3 more Caused by: java.time.DateTimeException: Unable to obtain LocalTime from TemporalAccessor: {MicroOfSecond=0, MinuteOfHour=19, NanoOfSecond=0, MilliOfSecond=0, SecondOfMinute=22, HourOfAmPm=10},ISO resolved to 2016-06-21 of type java.time.format.Parsed at java.base/java.time.LocalTime.from(LocalTime.java:431) at java.base/java.time.LocalDateTime.from(LocalDateTime.java:457) ... 5 more
惊讶吗? java.time已经发现您没有问过的错误:在格式模式字符串中,您需要在00到23的一天中的大写HH
使用小写hh
来表示上午的时钟时间。或从01到12的PM。错误消息中要注意的详细信息是HourOfAmPm=10
-这不是您想要的。让我们修复并再次运行:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm-ss");
Exception in thread "main" java.time.zone.ZoneRulesException: Unknown time-zone ID: fewfefewf at java.base/java.time.zone.ZoneRulesProvider.getProvider(ZoneRulesProvider.java:279) at java.base/java.time.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:234) at java.base/java.time.ZoneRegion.ofId(ZoneRegion.java:120) at java.base/java.time.ZoneId.of(ZoneId.java:408) at java.base/java.time.ZoneId.of(ZoneId.java:356) at ovv.misc.MiscTest.<init>(MiscTest.java:73) at ovv.misc.MiscTest.main(MiscTest.java:61)
我相信这就是您要的。如果我们也修复此错误,则代码可以完美运行:
ZonedDateTime dateTime = LocalDateTime.parse(str, dtf)
.atZone(ZoneId.of("America/Eirunepe"));
1466522362000
我设置了一个随机时区,但我认为您知道您想要哪个。
其他答案已经很好地说明了您的代码出了什么问题。我不知道如何说服旧的TimeZone
类来验证时区ID字符串。
链接: Oracle tutorial: Date Time解释了如何使用java.time。