Java,在PC上更改时区后测试失败

时间:2016-07-31 08:23:13

标签: java spring time timezone spring-data

最初我的测试非常简单:

@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);
}

始终在具有默认TimeZone UTC且具有以下输出的PC上执行:

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

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

但是:

Q1:

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

假设,Spring Data仅比较日,月,年和修剪时间段。 这是对的吗??

Q2:

我试图修正测试,将时区直接放在测试中:

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]

目前我无法理解它是如何可能的:

Mon Aug 08 07:00:00 UTC 2016&gt; = Tue Aug 09 00:00:00 UTC 2016

Q3: 我试图将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 相同。

Q4: 在静态块中指定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解决了问题?

1 个答案:

答案 0 :(得分:0)

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

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