我正在添加这个问题,因为我是Java和Android的新手,我搜索了几个小时试图解决这个问题.答案来自相关答案的组合,所以我想我会记录我为其他可能正在努力的人学到的东西.见答案.
对于一些背景知识,我的经验主要是PHP的Web开发和一点Ruby.我唯一的操作系统是Linux(Ubuntu Studio),我(不情愿地)在Android Studio 2.1.2中开发我的第一个Android应用程序.我的Java设置如下:
>java -version
> openjdk version "1.8.0_91"
> OpenJDK Runtime Environment (build 1.8.0_91-8u91-b14-3ubuntu1~15.10.1-b14)
> OpenJDK 64-Bit Server VM (build 25.91-b14, mixed mode)
Run Code Online (Sandbox Code Playgroud) datetime android android-gradle-plugin threetenbp threetenabp
我在一些使用ThreeTenABPLocalDateTime.now()
返回的摩托罗拉设备上有一种非常奇怪的行为.0000-00-00T00:00:00.0
代码如下:
@Override
protected void onResume() {
super.onResume();
if (!TextUtils.isEmpty(timeout)) {
LocalDateTime savedTime = LocalDateTime.parse(timeout, DateTimeFormatter.ISO_DATE_TIME);
if (LocalDateTime.now().isAfter(savedTime)) {
refresh()
}
}
}
@Override
protected void onPause() {
super.onPause();
LocalDateTime currentTime = LocalDateTime.now().plus(Duration.ofMinutes(10));
timeout = currentTime.format(DateTimeFormatter.ISO_DATE_TIME);
}
Run Code Online (Sandbox Code Playgroud)
仅在这些设备上(只有3个运行6.0的Motorola设备):
我有这个崩溃:
Fatal Exception: java.lang.RuntimeException: Unable to resume activity {com.myapp/com.myapp.MainActivity}: org.threeten.bp.format.DateTimeParseException: Text '0000-00-00T00:00:00.8' could not be parsed: Invalid value for MonthOfYear (valid values 1 - 12): 0
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3121)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3152)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1398)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443) …
Run Code Online (Sandbox Code Playgroud) 我正在为我的Android项目使用ThreeTen-Backport库(因为java.time尚未在android开发中实现).
当我写LocalDate today=LocalDate.now();
或LocalTime time=LocalTime.now();
我得到以下异常时:
Caused by: org.threeten.bp.zone.ZoneRulesException:
No time-zone data files registered
at org.threeten.bp.zone.ZoneRulesProvider.getProvider(ZoneRulesProvider.java:176)
at org.threeten.bp.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:133)
at org.threeten.bp.ZoneRegion.ofId(ZoneRegion.java:143)
at org.threeten.bp.ZoneId.of(ZoneId.java:357)
at org.threeten.bp.ZoneId.of(ZoneId.java:285)
at org.threeten.bp.ZoneId.systemDefault(ZoneId.java:244)
at org.threeten.bp.Clock.systemDefaultZone(Clock.java:137)
at org.threeten.bp.LocalDate.now(LocalDate.java:165)
Run Code Online (Sandbox Code Playgroud)
相同的代码行在我使用的另一个java项目中运行良好,该项目使用本机java.time库.
我搜索了一个可能的解决方案,但找不到任何有用的东西:一个解决方案建议我需要使用另一个包含时区规则的jar,另一个建议在类路径中可能有两个或更多的ThreeTenBP库.
那些案件与我的案子不符.
在build.gradle
文件内部的依赖项部分,我尝试了一些配置:
compile 'com.jakewharton.threetenabp:threetenabp:1.0.3'
compile 'org.threeten:threetenbp:1.0.3'
compile 'org.threeten:threetenbp:1.3.1'
compile 'org.threeten:threetenbp:1.3.2'
我不知道这行代码有什么问题以及如何修复它.
该LocalDate.now()
和LocalTime.now()
方法应该工作而没有指定时区.
使用ThreeTen Android Backport库,转换ZonedDateTime
或OffsetDateTime
进入旧学校java.util.Date
实例的最简单方法是什么?
如果我拥有完整的Java 8库,那当然就是这样做的方式(如本问题所示):
Date.from(zonedDateTime.toInstant());
Run Code Online (Sandbox Code Playgroud)
但我无法在Android上使用它; 特别Date.from(Instant instant)
是缺少.
我正在使用openjdk版本1.8.0_112-release进行开发,但是也需要支持以前的JDK版本(Java-8之前版本) - 因此无法使用java.time
.
我正在编写一个简单的类来计算日期,以查看保存的日期是否在当前日期之前,这意味着它已过期.
但是,我不确定我是否以正确的方式做到了这一点.我正在LocalDate
上课来计算天数.从用户单击保存的日期和时间开始计算到期时间.该日期将被保存,并将根据此保存的日期和时间以及当前日期和时间(即用户登录时)进行检查.
这是最好的方法吗?我想继续LocalDate
上课.
import org.threeten.bp.LocalDate;
public final class Utilities {
private Utilities() {}
public static boolean hasDateExpired(int days, LocalDate savedDate, LocalDate currentDate) {
boolean hasExpired = false;
if(savedDate != null && currentDate != null) {
/* has expired if the saved date plus the specified days is still before the current date (today) */
if(savedDate.plusDays(days).isBefore(currentDate)) {
hasExpired = true;
}
}
return hasExpired;
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用这样的类:
private void showDialogToIndicateLicenseHasExpired() …
Run Code Online (Sandbox Code Playgroud) 我在一个org.threeten.bp.LocalDateTime
对象中有两个日期.我需要以天为单位找出这两个日期之间的差异.
我已经切换到三个日期时间,但我仍然有一个第三方工具,使用joda将时区写入数据库的时区,我需要从一个转换为另一个.什么是最好的方式?作为一种解决方法,我尝试了DateTime.parse(zdt.toString)但是因为joda不喜欢区域格式而失败了
格式无效:"2015-01-25T23:35:07.684Z [欧洲/伦敦]"格格不入"[欧洲/伦敦]"
注意:这已经是很好的JDK世界回答这里,但接受的答案并不适用于JSR-310的Android端口不具有日期是扩展API.
那么,什么是一个转换的最佳方式java.util.Date
来org.threeten.bp.LocalDate
?
Date input = new Date();
LocalDate date = ???
Run Code Online (Sandbox Code Playgroud) 我有以下应用程序代码。
public static long advanceByMax1HourWithoutOverflow(long currentTimeMillis) {
ZoneId zoneId = ZoneId.systemDefault();
ZonedDateTime zonedDateTime = Instant.ofEpochMilli(currentTimeMillis).atZone(zoneId);
// 0-23
int hour = zonedDateTime.getHour();
if (hour < 23) {
zonedDateTime = zonedDateTime.plusHours(1);
return zonedDateTime.toInstant().toEpochMilli();
}
// 0-59
int minute = zonedDateTime.getMinute();
if (minute < 59) {
zonedDateTime = zonedDateTime.plusMinutes(1);
return zonedDateTime.toInstant().toEpochMilli();
}
return currentTimeMillis;
}
Run Code Online (Sandbox Code Playgroud)
我用以下内容为它编写了一个单元测试。
@Test
public void advanceByMax1HourWithoutOverflow() {
/*
27 October 2018
1540648800000 -> 1540652400000
22:00 -> 23:00
*/
long currentTimeMillis = 1540648800000L;
long expected = 1540652400000L;
long …
Run Code Online (Sandbox Code Playgroud) 我使用这个库在我的应用程序中存储与日期和时间相关的数据。当应用程序启动时,AndroidThreeTen
首先被初始化以正常运行。所以想问一下单元测试的时候怎么初始化呢?比如我想测试使用LocalDate
,LocalDateTime
等等。
我现在的方式是这样的:
class OverviewViewModelTest {
@Rule
@JvmField
val rule = InstantTaskExecutorRule()
@Before
fun setup() {
AndroidThreeTen.init(Application())
}
//...
}
Run Code Online (Sandbox Code Playgroud)
但它抛出这个错误:
java.lang.ExceptionInInitializerError
at org.threeten.bp.ZoneRegion.ofId(ZoneRegion.java:143)
at org.threeten.bp.ZoneId.of(ZoneId.java:358)
at org.threeten.bp.ZoneId.of(ZoneId.java:286)
at org.threeten.bp.ZoneId.systemDefault(ZoneId.java:245)
at org.threeten.bp.Clock.systemDefaultZone(Clock.java:137)
at org.threeten.bp.LocalDate.now(LocalDate.java:165)
Caused by: java.lang.RuntimeException: Method getAssets in android.content.ContextWrapper not mocked. See http://g.co/androidstudio/not-mocked for details.
at android.content.ContextWrapper.getAssets(ContextWrapper.java)
at com.jakewharton.threetenabp.AssetsZoneRulesInitializer.initializeProviders(AssetsZoneRulesInitializer.java:22)
at org.threeten.bp.zone.ZoneRulesInitializer.initialize(ZoneRulesInitializer.java:89)
at org.threeten.bp.zone.ZoneRulesProvider.<clinit>(ZoneRulesProvider.java:82)
... 32 more
Run Code Online (Sandbox Code Playgroud)
那么我怎样才能让这个库在单元测试中工作呢?
threetenbp ×10
android ×7
java ×7
threetenabp ×2
unit-testing ×2
datetime ×1
exception ×1
jodatime ×1
jsr310 ×1
localdate ×1
motorola ×1