Reputation: 13290
This test normally passes all year round when the there is no lost hour or gained hour to account for. But right now it's being a nuisance. We're validating that the expiration date, getExp()
, minus 7 days, is within 10 milliseconds of the issue date, getIss()
. Since the exp
and iss
values are generated right after each other 10 milliseconds is a perfectly acceptable delta to expect the values to be between.
But now they're understandably an hour off when it looks a week into the future when the Java date code calls setExp()
after initializing a new JWT Claim.
Assertion / test code:
assertThat(claim.getExp()).isCloseTo(new DateTime(claim.getIss()).plusDays(7).toDate(), 10);
In english this reads: assert that the claim's expiration date is within 10 milliseconds of the claim's issue date + 7 days.
An immediate fix is to add an hour's worth of milliseconds to the allowed delta but I was curious to see if there was a better solution.
EDIT: I believe I found the issue. We initialize claim issue date and claim expiration date using ZonedDateTime.now():
Claim claim = new Claim();
claim.setIss(Date.from(ZonedDateTime.now(ZoneId.of("UTC")).toInstant()));
claim.setExp(Date.from(ZonedDateTime.now(ZoneId.of("UTC")).plusDays(7).toInstant()));
But when we validate with JODA time we assume our local rules for daylight savings time. This obviously causes an issue with GMT DST vs. American DST rules.
EDIT2: The fix involved 2 words and updating the unit test to respect UTC:
assertThat(claim.getExp()).isCloseTo(new DateTime(claim.getIss(), DateTimeZone.UTC).plusDays(7).toDate(), 10);
Upvotes: 3
Views: 1963
Reputation: 21639
Your only two solutions are:
Change your reporting so that, instead of being based on local time, is uses UTC (ie, epoch unix time). This is the preferable solution from a tech point of view since it's a worldwide standard including most shared servers and data sources; no DST to worry about; and you can still have your reports calculate local time.
Alternatively, to find or add a reliable 'dateadd'-type function that take Daylight Savings into account.
I've always been surprised that all platforms don't have that functionality built-in. Granted, DST has a confusing, ever-evolving set of rules that are region-specific (by continent, country, and is some areas by "state" or even "county") ...but still.
Currently, in most of North America, DST:
Begins on the 2nd Sunday of March. ("Spring Forward" so clocks change from 01:59 to 03:00)
Ends on the 1st Sunday of November. ("Fall Back" from 01:59 to 01:00)
Windows API has functionality for calculating whether DST is in effect but really, no application should allow an application to display, for example in North America: "Sunday March 11, 2018 02:30:00" because that time doesn't exist.
...still, #1 is your preferable solution because accuracy and standardization are more straightforward.
Upvotes: 4