由于时区不同导致时间戳时间不匹配

Timestamp time mismatch because of the different time zone

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

为什么会发生这种情况?

编辑:

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

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

然后测试声明一个预期的字符串常量和 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();

您正在测试的代码取决于时区。它根据用户默认时区中的时间输出特定日期。这就是为什么它给你的输出与它给你的同事的不同。

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