【问题标题】:Java, failed test after changing Time zone on PCJava,在 PC 上更改时区后测试失败
【发布时间】:2016-07-31 08:23:13
【问题描述】:

最初我有一个非常简单的测试:

@Test
public void testMe() {

    System.out.println("Records in H2 db:");
    List<DateRangeBean> all = dateRangeServiceImpl.findAll();
    all.forEach(x -> System.out.println(x.getDateTo()));

    Clock.system(ZoneId.of("UTC"));
    ZonedDateTime currentDate = ZonedDateTime.of(2016, 8, 9, 0, 0, 0, 0, clock.getZone());
    Date currentDate_date = Date.from(currentDate.toInstant());
    System.out.println("Current Date is: " + currentDate_date);

    List<DateRangeBean> result = new ArrayList<>();
    dateRangeServiceImpl.findGreaterDateTo(currentDate_date).iterator().forEachRemaining(result::add);
    result.forEach(x -> System.out.println(x.getDateTo()));

    assertEquals(result.size(), 2);
}

始终在 PC 上使用默认 TimeZone UTC 执行,并具有以下输出:

Records in H2 db:
Mon Aug 08 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Current Date is: Tue Aug 09 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016

在哪里: dateRangeServiceImpl.findAll() 实现为:

    public List<DateRangeBean> findAll (){
    List<DateRangeBean> result = new ArrayList<>();
    dateRangeRepository.findAll().iterator().forEachRemaining(result::add);

    return result;
}

dateRangeServiceImpl.findGreatedDateTo(日期日期)

    public List<DateRangeBean> test (Date currentDate){
    List<DateRangeBean> result = new ArrayList<>();
    dateRangeRepository.findGreatedDateTo(currentDate).iterator().forEachRemaining(result::add);

    return result;
}

dateRangeRepository - 作为 Spring Data 的一部分的纯接口

public interface DateRangeRepository extends PagingAndSortingRepository<DateRangeBean, Long> {
@Query("from DateRangeBean drb where (drb.dateTo >= :currentDate)")
List<DateRangeBean> findGreatedDateTo(@Param("currentDate") Date currentDate);
}

DateRangeBean

@Entity
public class DateRangeBean implements java.io.Serializable {
    @Temporal(TemporalType.DATE)
    @Column(name = "date_To", length = 10)
    private Date dateTo;
.....................
public Date getDateTo() {
    return new Date(this.dateTo.getTime());
}

public void setDateTo(Date dateTo) {
    this.dateTo = new Date(dateTo.getTime());
}

} 今天我尝试在具有时区的 PC 上运行此测试:UTC -07:00,测试失败,输出如下:

Records in H2 db:
Mon Aug 08 00:00:00 MST 2016
Thu Oct 20 00:00:00 MST 2016
Thu Oct 20 00:00:00 MST 2016
Current Date is: Mon Aug 08 17:00:00 MST 2016
Mon Aug 08 00:00:00 MST 2016
Thu Oct 20 00:00:00 MST 2016
Thu Oct 20 00:00:00 MST 2016
java.lang.AssertionError: expected [2] but found [3]
Expected :2
Actual   :3

好吧,也许这是合理的:我们定义了 currentDate 变量 Aug 9 UTC TZ,但在下一步中,我们在 MST TZ 中将 currentDate 重新转换为 currentDate_date,结果是 8 月 8 日。

但是:

第一季度:

基于我们的@Query:drb.DateTo >= :currentDate 在当前情况下:Mon Aug 08 00:00:00 MST 2016 >= Mon Aug 08 17:00:00 MST 2016 - 此语句不正确!

假设 Spring Data 仅比较日、月、年并修剪时间段。 这是正确的吗??

第二季度:

我尝试修复测试,将时区直接放在测试中:

public void testMe() {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
..............
}

但我仍然得到失败的结果:

Records in H2 db:
Mon Aug 08 07:00:00 UTC 2016
Thu Oct 20 07:00:00 UTC 2016
Thu Oct 20 07:00:00 UTC 2016
Current Date is: Tue Aug 09 00:00:00 UTC 2016
Mon Aug 08 07:00:00 UTC 2016
Thu Oct 20 07:00:00 UTC 2016
Thu Oct 20 07:00:00 UTC 2016
java.lang.AssertionError: expected [2] but found [3]

目前我无法理解这怎么可能:

2016 年 8 月 8 日星期一 07:00:00 UTC >= 2016 年 8 月 9 日星期二 00:00:00 UTC ?

第三季度: 我试图将 TZ 指定为 Spring Context 的一部分:

    <bean id="defaultZoneInfo" class="sun.util.calendar.ZoneInfo" factory-method="getTimeZone">
    <constructor-arg type="java.lang.String" value="UTC"/>
</bean>

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="staticMethod" value="java.util.TimeZone.setDefault"/>
    <property name="arguments">
        <list>
            <ref bean="defaultZoneInfo"/>
        </list>
    </property>
</bean>

但结果与 Q2 相同。

第四季度: 在静态块中指定 TZ:

static {
   TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
}

并测试 - 通过!

Records in H2 db:
Mon Aug 08 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Current Date is: Tue Aug 09 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016
Thu Oct 20 00:00:00 UTC 2016

那么,有人能解释一下为什么在 Spring Context xml 文件中指定默认 TZ 并直接在测试方法中没有解决问题吗?

只有通过静态块指定 TZ 才能解决问题?

【问题讨论】:

    标签: java spring time timezone spring-data


    【解决方案1】:

    我认为这可能是您的数据库问题而不是您的应用程序

    例如,在控制面板中更改客户端位置后,Oracle 数据库不接受来自客户端的连接。

    【讨论】:

    • 也许你是对的,但我需要为这个问题找到合适的解决方案。顺便说一句,为了测试我使用的是嵌入式 h2 db。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多