由于时区不同,时间戳时间不匹配

时间:2017-07-04 08:02:31

标签: java junit timestamp datetime-format timezone-offset

我的团队收到了一个新项目。该项目有一堆没有通过的测试。用他们的话说,所有的测试都应该通过。在调查问题后,我发现存在一个共同的问题。大多数失败的测试创建Timestamp并使用它,但预期和实际日期不一样。差别只有一个小时。旧开发团队一直在GMT + 1区工作,我们的工作是GMT + 2。

为什么会这样?

修改

我有一个测试,它创建实体Rating并设置一堆属性。例如:

rating.setValidFromDate(new Timestamp(1459841866798L));

然后测试断言一个预期的String常量和rating.toString()

正如我所说,差异恰好是1小时

编辑2

@Test
public void testToString() {
    Rating rating = new Rating();
    rating.setValidFromDate(new Timestamp(1459841866798L));

    assertEquals("Rating{validFromDate='2016-04-05 09:37:46'}", rating.toString());
}

@Override
public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append(Rating.class.getSimpleName());
    builder.append("{");
    builder.append("validFromDate='" + DateHelper.getStringFromDate(validFromDate) + "'");
    builder.append("}");
    return builder.toString();
}

public static String getStringFromDate(Date dateValue) {
    String strDate = "";
    if (dateValue != null) {
        DateFormat dateFormat = new SimpleDateFormat(Constants.DATETIME_FORMAT);
        strDate = dateFormat.format(dateValue);
    }
    return strDate;
}

解决

我决定给你解决这个问题的方法。

阅读之后:java.sql.Timestamp: changing timezone of Timestamp我找到了一种操纵测试时区的方法。所以我决定编写一个JUnit规则,它将对我的所有测试都这样做。

我写了以下声明:

public class GermanTimeZoneStatement extends Statement {

    private final Statement base;

    public GermanTimeZoneStatement(Statement base) {
        super();
        this.base = base;
    }

    @Override
    public void evaluate() throws Throwable {
        TimeZone.setDefault(TimeZone.getTimeZone("Europe/Berlin"));
        base.evaluate();
    }
}

之后我写了这条规则:

public class GermanTimeZoneRule implements TestRule {

    public static GermanTimeZoneRule getInstance() {
        return new GermanTimeZoneRule();
    }

    @Override
    public Statement apply(Statement base, Description description) {
        return new GermanTimeZoneStatement(base);
    }
}

最后,我在我的测试中包含了这样的规则:

    @Rule
    public GermanTimeZoneRule germanTimeZoneRule = GermanTimeZoneRule.getInstance();

1 个答案:

答案 0 :(得分:3)

您正在测试的代码与时区有关。它根据用户默认时区的时间输出特定日期。这就是为什么它会给你不同的输出结果。

您需要返回该代码的规范,并检查这是否是预期的行为。如果是,您需要修改测试以考虑时区。如果它不是预期的行为,那么恭喜你,你的测试暴露了一个错误!