From da393f0e259f984a0f6adf2f1c456b7087555419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillermo=20Rodr=C3=ADguez?= Date: Mon, 27 Apr 2026 02:02:23 +0200 Subject: [PATCH] Fix getUTCOffSet rounding for non-integer timezones SolarEventCalculator.getUTCOffSet() uses BigDecimal.divide(3600000, new MathContext(2)) to convert ZONE_OFFSET into fractional hours. This was introduced in commit 30f64ec to fix handling of zones with non-integer offsets, such as Asia/Kolkata (UTC +5:30). However, MathContext(2) caps the result to 2 *significant digits* (not "2 decimal places"), so timezones whose offset has more than 2 significant digits were rounded incorrectly. Examples: Asia/Kathmandu +5:45 (5.75) -> 5.8 (off by 3 min) Australia/Eucla +8:45 (8.75) -> 8.8 (off by 3 min) Pacific/Chatham +12:45 (12.75) -> 13 (off by 15 min) Australia/Lord_Howe +10:30 (10.5) -> 11 (off by 30 min) Fix by using the existing divideBy() helper instead. Fixes: #48 --- .../calculator/SolarEventCalculator.java | 2 +- .../SunriseSunsetCalculatorTest.java | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/luckycatlabs/sunrisesunset/calculator/SolarEventCalculator.java b/src/main/java/com/luckycatlabs/sunrisesunset/calculator/SolarEventCalculator.java index 323fc7a..c00ab11 100644 --- a/src/main/java/com/luckycatlabs/sunrisesunset/calculator/SolarEventCalculator.java +++ b/src/main/java/com/luckycatlabs/sunrisesunset/calculator/SolarEventCalculator.java @@ -375,7 +375,7 @@ private BigDecimal getDayOfYear(Calendar date) { private BigDecimal getUTCOffSet(Calendar date) { BigDecimal offSetInMillis = new BigDecimal(date.get(Calendar.ZONE_OFFSET)); - BigDecimal offSet = offSetInMillis.divide(new BigDecimal(3600000), new MathContext(2)); + BigDecimal offSet = divideBy(offSetInMillis, BigDecimal.valueOf(3600000)); return offSet; } diff --git a/src/test/java/com/luckycatlabs/sunrisesunset/SunriseSunsetCalculatorTest.java b/src/test/java/com/luckycatlabs/sunrisesunset/SunriseSunsetCalculatorTest.java index a557222..9e07106 100644 --- a/src/test/java/com/luckycatlabs/sunrisesunset/SunriseSunsetCalculatorTest.java +++ b/src/test/java/com/luckycatlabs/sunrisesunset/SunriseSunsetCalculatorTest.java @@ -108,4 +108,27 @@ public void testNonIntegerTimezoneOffset() { String officialSunriseForDate = calculator.getOfficialSunriseForDate(calendar); assertEquals("06:19", officialSunriseForDate); } + + @Test + public void testNonIntegerTimezoneOffset2() { + // Asia/Kathmandu (+5:45, no DST) + Location kathmandu = new Location("27.7172", "85.3240"); + SunriseSunsetCalculator calc = new SunriseSunsetCalculator(kathmandu, "Asia/Kathmandu"); + + Calendar calendar = Calendar.getInstance(); + calendar.set(2024, Calendar.JUNE, 15); + + assertEquals("05:08", calc.getOfficialSunriseForDate(calendar)); + assertEquals("19:01", calc.getOfficialSunsetForDate(calendar)); + + // Pacific/Chatham (+12:45), outside DST window (July is southern winter) + Location chatham = new Location("-43.8800", "176.3200"); + calc = new SunriseSunsetCalculator(chatham, "Pacific/Chatham"); + + calendar = Calendar.getInstance(); + calendar.set(2024, Calendar.JULY, 15); + + assertEquals("08:29", calc.getOfficialSunriseForDate(calendar)); + assertEquals("17:42", calc.getOfficialSunsetForDate(calendar)); + } }