The Week Number That Went Back to 1999 — Java Bug Hunt
Modelled on the GPS week-number rollover of 6 April 2019: the legacy GPS navigation message carries the week number in 10 bits, so it wraps to zero every…
- Language: Java
- Layer: Backend
- Difficulty: Medium
- Concepts: Time, Overflow
- Modelled on: GPS week rollover · 2019
- Visible tests: a week late in the build era resolves; week 0 after the 2019 rollover is week 2048
- Reward: 50 XP for a complete fix
Briefing
Modelled on the GPS week-number rollover of 6 April 2019: the legacy GPS navigation message carries the week number in 10 bits, so it wraps to zero every 1024 weeks (about 19.6 years). The first wrap was in August 1999; at the second, receivers that assumed a fixed rollover era — or had no rollover handling at all — suddenly reported dates 1024 weeks in the past, and some systems that depended on them failed.
This project is a reconstruction. GpsWeek.resolve turns the broadcast 10-bit week into a full week number by adding the era the firmware was built in, as a fixed constant.
Fix resolve so the full week is found relative to the firmware's build week and keeps working across any number of future rollovers.
Bug report
BUG-WNRO · Priority: High · Reported by: field support
GpsWeek.resolve(broadcastWeek):
- broadcastWeek outside 0..1023 throws IllegalArgumentException
- otherwise returns the SMALLEST full week w such that w % 1024 == broadcastWeek and w >= GpsConstants.BUILD_WEEK (a receiver can never be running before it was built)
GpsWeek.dayNumber(broadcastWeek, dayOfWeek) = resolve(broadcastWeek) * 7 + dayOfWeek.
Observed: after the April 2019 rollover the broadcast week reads 0 and the receiver resolves it to week 1024 — August 1999.
Logs
[gps] wn10=1023 -> week 2047 (2019-03-31)
[gps] wn10=0 -> week 1024 (1999-08-22)
[nav] timestamp moved back 7168 days, rejecting fixThe code as shipped
src/gps/GpsWeek.java (editable)
class GpsWeek {
static int resolve(int broadcastWeek) {
if (broadcastWeek < 0 || broadcastWeek >= GpsConstants.ROLLOVER) {
throw new IllegalArgumentException("week out of range: " + broadcastWeek);
}
return GpsConstants.ERA_AT_BUILD * GpsConstants.ROLLOVER + broadcastWeek;
}
static int dayNumber(int broadcastWeek, int dayOfWeek) {
return resolve(broadcastWeek) * 7 + dayOfWeek;
}
}
Read-only context: src/gps/GpsConstants.java.
Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More Java bug hunts.