fIwJlxSzApHEZIl
fIwJlxSzApHEZIl

Reputation: 13290

JWT Issue date vs. Expiration date check is failing due to daylight savings time. What's a year-round permanent solution?

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

Answers (1)

ashleedawg
ashleedawg

Reputation: 21639

Your only two solutions are:

  1. 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.

  2. 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

Related Questions