Java Android-junit-单元测试-带时区的SimpleDataFormat

Java Android-junit-单元测试-带时区的SimpleDataFormat,java,android,simpledateformat,timezone-offset,Java,Android,Simpledateformat,Timezone Offset,我正在使用Android、JUnit和SimpleDataFormat 我喜欢在带有时区的rfc3339格式的字符串和日期之间进行一些转换 例如:2017-12-31T23:59:59+02:00但不2017-12-31T23:59:59+0200 AndroidSimpleDataFormat使用Z模式,但不使用X模式(请参见下面的RFC3339_REGEX_1) 但是在我的JUnit测试(jdk1.8)中,RFC3339\u REGEX\u 1没有给我正确的格式(+02:00),而是+020

我正在使用Android、JUnit和
SimpleDataFormat

我喜欢在带有时区的rfc3339格式的
字符串
日期
之间进行一些转换

例如:
2017-12-31T23:59:59+02:00
但不
2017-12-31T23:59:59+0200

Android
SimpleDataFormat
使用
Z
模式,但不使用
X
模式(请参见下面的
RFC3339_REGEX_1

但是在我的JUnit测试(jdk1.8)中,
RFC3339\u REGEX\u 1
没有给我正确的格式(
+02:00
),而是
+0200
。JUnit测试在
RFC3339_REGEX_2
中运行良好

那么,我怎样才能做一些既能在Android设备上运行良好,又能在JUnit测试上运行良好的清洁工作呢

public static final String RFC3339_REGEX_1 = "yyyy-MM-dd'T'HH:mm:ssZ"; //android
public static final String RFC3339_REGEX_2 = "yyyy-MM-dd'T'HH:mm:ssXXX"; //java
旧类(
Date
Calendar
SimpleDateFormat
)具有和,它们正在被新的API所取代。如果我没有错的话,
X
模式(我知道,在年,它只在年引入;不确定这会如何影响不同的Android版本)

作为替代,在Android中,您可以使用。要使它工作,您还需要(参见如何使用它)

但是,如果您仍然需要使用
java.util.Date
,这个API可以让您更轻松。如果您想要像
2017-12-31T23:59:59+02:00
这样的格式,可以将
java.util.Date
转换为
org.threeten.bp.OffsetDateTime
(使用
org.threeten.bp.DateTimeUtils
类转换值,使用
org.threeten.bp.ZoneOffset
将偏移设置为
+02:00
):

输出将是:

2017-12-31T23:59:59+02:00

请注意,这是
odt.toString()
(被
System.out.println
称为隐式)的结果,默认情况下,它与所需的格式匹配。但您也可以通过使用
org.threeten.bp.format.DateTimeFormatter
,强制执行特定的格式:

DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX");
System.out.println(fmt.format(odt));
输出是相同的。唯一的区别是,第一个版本(使用
toString()
)将打印秒的分数,如果秒数不为零,则将忽略秒数,而第二个版本(带有格式化程序)将始终以所需格式打印(在本例中,打印秒数,但不打印秒数),无论值是否为零

我相信,在您的情况下,您将需要一个格式化程序,因为您似乎总是需要一个有秒的格式,而没有秒的分数


要将
OffsetDateTime
转换回
Date
,还可以使用
DateTimeUtils

// convert back to java.util.Date
date = DateTimeUtils.toDate(odt.toInstant());

如果不需要使用
java.util.Date
,可以直接使用
OffsetDateTime

// create OffsetDateTime with value = 2017-12-31T23:59:59+02:00
OffsetDateTime odt = OffsetDateTime.of(2017, 12, 31, 23, 59, 59, 0, ZoneOffset.ofHours(2));
还请注意,我使用了小时(2)的
ZoneOffset.of,这相当于(“+02:00”)的
ZoneOffset.of

您还可以使用
OffsetDateTime.now(ZoneOffset.ofHours(2))
获取当前日期



ThreeTen Backport是新Java8日期/时间类的一个Backport,它有许多不同的日期和时间类型(如上面的
OffsetDateTime
)可用于不同的情况。有关什么类型最适合您的情况的更多信息,本教程介绍了Java 8,但ThreeTen Backport具有相同的类和方法名称,只是包不同:
org.ThreeTen.bp
而不是
Java.time

在Joda time中,我们有AbstractDateTime类,它提供了datetime类的常见行为,我在三十分钟内没有找到通讯员(提供LocalDateTime、ZonedDateTime和OffsetDateTime,但没有抽象类)?@Anh TuanMai您需要什么常见行为?根据您的需要,您可以使用
Temporal
TemporalAccessor
界面。我想在Joda time中使用BaseDateTime.getMillis()之类的东西,并以毫秒为单位使用构造函数:)@Anh TuanMai但要使用毫秒,请开始查看
Instant
类谢谢,
Instant
类是解决方案。
// create OffsetDateTime with value = 2017-12-31T23:59:59+02:00
OffsetDateTime odt = OffsetDateTime.of(2017, 12, 31, 23, 59, 59, 0, ZoneOffset.ofHours(2));