简体   繁体   中英

Timestamp time mismatch because of the different time zone

My team received a new project. The project has a bunch of tests which do not pass. By their words, all the tests should pass. After investigating the problem I discovered that there is a common issue. Most of the failing tests create Timestamp and work with it but the expected and the actual date is not the same. The difference is exactly one hour. The old dev team has been working from a zone which is GMT + 1 and we are working from GMT + 2.

Why this may happen?

EDIT :

I have a test which creates entity Rating and sets a bunch of properties. For example:

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

then the test assert an expected String constant and rating.toString()

As I said the difference is exactly 1 hour

EDIT 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;
}

Solved

I decided to give you my solution to this problem.

After reading this: java.sql.Timestamp: changing timezone of Timestamp I found a way to manipulate time zone of the tests. So I decided to write a JUnit rule which will do this to all of my tests.

I have written the following Statement:

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

After that I've written this rule:

public class GermanTimeZoneRule implements TestRule {

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

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

Finally I've include the rule in my tests like this:

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

The code that you're testing is time-zone dependent. It outputs a particular date according to what time it is in the user's default time-zone . That's why it gives you different output from what it gives your colleagues.

You need to go back to the specification for that code, and check whether that's the intended behaviour. If it is, you'll need to modify the test to take the time-zone into account. If it's not the intended behaviour, then congratulations, your test has exposed a bug!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM