出于某些原因,我们现在不能使用java 8 - 我们仍然坚持使用java 7.
但是,我现在想JSR-310 date/time APIs使用官方的后端ThreeTen来使用新版本.
其主页说明:
The backport is NOT an implementation of JSR-310, as that would require
jumping through lots of unnecessary hoops. Instead, this is a simple backport
intended to allow users to quickly use the JSR-310 API on Java SE 6 and 7.
Run Code Online (Sandbox Code Playgroud)
问题:
您对ThreeTen 的体验是什么?有一些缺点吗?
与官方实施相比,该项目的兼容性如何JSR-310?
从ThreeTen 迁移到官方Java 8实现需要多少工作?
是否值得现在迁移到ThreeTen,后来迁移到JSR-310 - 或者是否有人要等到java 8才能使用,这是否会跳过ThreeTen?
在大约200年将Dates 转换为LocalDates时,我得到的结果不一致.使用以下代码进行转换:
private LocalDate toLocalDate(Date localDate)
{
return LocalDateTime.ofInstant(localDate.toInstant(), ZoneId.systemDefault()).toLocalDate();
}
Run Code Online (Sandbox Code Playgroud)
我的ZoneId.systemDefault()是Africa/Harare,它与CAT测试中使用的相匹配.我运行的测试用例是
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
String dateString = "Tue Jan 01 00:00:00 CAT 200";
String dateString2 = "Tue Jan 01 00:00:00 CAT 201";
String dateString3 = "Wed Dec 31 00:00:00 CAT 200";
System.out.println(toLocalDate(simpleDateFormat.parse(dateString)));
System.out.println(toLocalDate(simpleDateFormat.parse(dateString2)));
System.out.println(toLocalDate(simpleDateFormat.parse(dateString3)));
Run Code Online (Sandbox Code Playgroud)
我的预期输出是
0200-01-01
0201-01-01
0200-12-31
Run Code Online (Sandbox Code Playgroud)
或者,如果不是这样,至少始终不正确的值.实际结果是
0199-12-31
0201-01-01
0200-12-31
Run Code Online (Sandbox Code Playgroud)
所以似乎第一个稍微回滚,可能是两个小时对应的CAT时区?但为什么这只发生在一个案例上呢?对2000年进行相同的实验不会产生相同的错误.
我需要在固定的日期时间在我的代码中安排任务.为此我正在使用ScheduledExecutorService和方法schedule(Runnable command, long delay, TimeUnit unit);
如何根据闰秒计算此延迟?
目前我使用Duration.between()但它似乎没有意识到闰秒:
ZonedDateTime date1 = ZonedDateTime.of(2015, 06, 30, 23, 59, 59, 000000, ZoneOffset.UTC);
ZonedDateTime date2 = ZonedDateTime.of(2015, 07, 01, 00, 00, 00, 000000, ZoneOffset.UTC);
ZonedDateTime date3 = ZonedDateTime.of(2015, 07, 01, 00, 00, 01, 000000, ZoneOffset.UTC);
System.out.println(Duration.between(date1, date2)); // PT1S
System.out.println(Duration.between(date2, date3)); // PT1S
Run Code Online (Sandbox Code Playgroud) 使用Java 8的新日期时间库,将字符串解析为日期的方法是使用DateTimeFormatter.LocalDate,LocalTime并且LocalDateTime都有一个静态解析方法,它接受一个String和一个格式化程序.一个潜在的问题是,如果你的DateTimeFormat不包含时间部分(或者对于DateTime,一个日期部分),即使你的模式匹配,你最终也会得到一个解析错误.
例
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY-MM-DD");
LocalDateTime dt = LocalDateTime.parse("2016-01-11", formatter);
Run Code Online (Sandbox Code Playgroud)
这将引发DateTimeParseException(如讨论这里与消息)
java.time.format.DateTimeParseException:
Text '2016-01-11' could not be parsed:
Unable to obtain LocalDateTime from TemporalAccessor
Run Code Online (Sandbox Code Playgroud)
这是一个有点无用的错误消息,因为文本可以解析,因为它匹配模式.相反,错误与它无法创建LocalDateTime的时间部分这一事实有关.将代码重构为以下代码:
LocalDateTime ldt = LocalDate.parse("2016-01-11", formatter).atStartOfDay());
Run Code Online (Sandbox Code Playgroud)
我的问题是,你说你有这样的通用方法
public static LocalDateTime getDate(String s, DateTimeFormatter format) {
...
}
Run Code Online (Sandbox Code Playgroud)
有没有办法确定需要调用哪个静态解析方法,通过应用一些默认逻辑将字符串强制转换为LocalDateTime?例如,如果日期仅使用午夜,如果时间仅使用今天,等等.
我试图使用Java 8新的日期模式而不是Joda,我有以下问题:
都
ZonedDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS Z"))
Run Code Online (Sandbox Code Playgroud)
和
LocalDateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormatter.ofPattern("dd/MM/yy HH:mm.ss.SSS Z"))
Run Code Online (Sandbox Code Playgroud)
抛出'java.time.format.DateTimeParseException'异常.而
org.joda.time.DateTime.parse("02/05/16 11:51.12.083 +04:30", DateTimeFormat.forPattern("dd/MM/yy HH:mm.ss.SSS Z"))
Run Code Online (Sandbox Code Playgroud)
工作良好.
异常的原因是:
java.time.format.DateTimeParseException:无法在索引22处解析文本'02/05/16 11:51.12.083 +04:30'
难道我做错了什么?
这样的方法是ChronoUnit.HOURS.between(start, end)返回long所以我不能从那里得到分数.
是否有一种可以返回分数的替代方法/方法?
我的代码中有"ddMMyy"模式,我使用appendValue方法指定了它:
DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder()
.appendValue(ChronoField.DAY_OF_MONTH, 2)
.appendValue(ChronoField.MONTH_OF_YEAR, 2)
.appendValue(ChronoField.YEAR_OF_ERA, 2)
.toFormatter();
System.out.println(LocalDate.parse("100199", dateTimeFormatter));
Run Code Online (Sandbox Code Playgroud)
但是这会产生"0099"年份:
0099-01-10
如果我将其更改为使用appendPattern:
DateTimeFormatter dateTimeFormatter = new DateTimeFormatterBuilder()
.appendPattern("ddMMyy")
.toFormatter();
System.out.println(LocalDate.parse("100199", dateTimeFormatter));
Run Code Online (Sandbox Code Playgroud)
我有正确的结果,一年"2099"与世纪.
2099年1月10日
代码对我来说似乎相同,为什么它不能产生相同的结果?为什么在第一种情况下缺少这个世纪?
目前,我正在学习java.time API和我注意到,多数类(例如LocalDate,OffsetDateTime在java.time)实现TemporalAdjuster接口,但ZonedDateTime没有.我只是想知道为什么会这样?为什么要排除ZonedDateTime实现TemporalAdjuster界面?
我的eta值是OffsetDateTime,我有一个DateDate类型的scheduledDate.如果没有设置eta,我想回到日期.
这个日期的一个例子是Tue Jul 21 10:32:28 PDT 2020.要转换这个问题,我想这样做:
OffsetDateTime.ofInstant(dto.getScheduledTime().ToInstant(), ZoneOffset.UTC)
感觉就像UTC偏移量是错误的,因为日期中有PDT了,但同时这也是不喜欢"美国/洛杉矶"一timezoneId.
我对如何处理这个问题感到有些困惑.
我们有一个用于生成报告的库.它从数据文件(SQL,XML,JSON等)中读取,然后可以在用户编写的等式中修改日期时间,然后将其格式化为报告输出的指定.
等式中的使用可以添加一个时间跨度,获取值的一部分,如"if date.month == 2",以及Excel中的几乎所有日期时间宏.
因为数据可以是JSON(或没有架构的XML),所以日期时间可以是"2019-01-25","2019-01-25T14:32:23","2019-01-25T14:32:23.12345"," 2019-01-25T14:32:23Z",或"2019-01-25T14:32:23Z-0500"(最后两个也可以有".12345").
如果没有时区偏移,我们假设日期时间是UTC.虽然这应该是真的,但通常它不是,它是当地时间,但它的使用方式,无关紧要.因此,除非指定时区偏移,否则将其设为UTC(到目前为止,我们已使用Date).
第一个问题 - 我应该使用什么类来保持这个值?根据我的阅读,我认为ZonedDateTime,但也许是即时?
第二个问题 - 当我必须做3天加入日期时间时,我应该在什么课上使用?
第三个问题 - 是否有一些解析器可以解析上面列出的所有不同的字符串?或者我需要调用String.contains()来确定格式,然后根据它做一个显式模式?如果是这样,使用什么类?