From 047e0618d290a09a4a269b00548fe17691e31787 Mon Sep 17 00:00:00 2001 From: bsglz <18031031@qq.com> Date: Thu, 27 Aug 2020 11:17:23 +0800 Subject: [PATCH] =?UTF-8?q?HBASE-24898=20Addendum=20to=20deal=20with=C2=A0?= =?UTF-8?q?Daylight=20Saving=20Time=20(#2310)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Viraj Jasani Signed-off-by: Duo Zhang --- .../compactions/CurrentHourProvider.java | 7 ++- .../compactions/TestCurrentHourProvider.java | 48 ++++++++++++++----- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/CurrentHourProvider.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/CurrentHourProvider.java index caafd711629e..b68363498e4c 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/CurrentHourProvider.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/compactions/CurrentHourProvider.java @@ -22,6 +22,7 @@ import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; import org.apache.yetus.audience.InterfaceAudience; +import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; @InterfaceAudience.Private public class CurrentHourProvider { @@ -37,7 +38,8 @@ private static final class Tick { } } - private static Tick nextTick() { + @VisibleForTesting + static Tick nextTick() { Calendar calendar = new GregorianCalendar(); calendar.setTimeInMillis(EnvironmentEdgeManager.currentTime()); int currentHour = calendar.get(Calendar.HOUR_OF_DAY); @@ -52,7 +54,8 @@ private static void moveToNextHour(Calendar calendar) { calendar.set(Calendar.MILLISECOND, 0); } - private static volatile Tick tick = nextTick(); + @VisibleForTesting + static volatile Tick tick = nextTick(); public static int getCurrentHour() { Tick tick = CurrentHourProvider.tick; diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/compactions/TestCurrentHourProvider.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/compactions/TestCurrentHourProvider.java index 6f7d0c92cf9a..6df6b9b570d7 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/compactions/TestCurrentHourProvider.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/compactions/TestCurrentHourProvider.java @@ -19,6 +19,7 @@ import static org.junit.Assert.assertEquals; +import java.util.Date; import java.util.TimeZone; import org.apache.hadoop.hbase.HBaseClassTestRule; import org.apache.hadoop.hbase.testclassification.RegionServerTests; @@ -27,12 +28,9 @@ import org.junit.ClassRule; import org.junit.Test; import org.junit.experimental.categories.Category; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; @Category({RegionServerTests.class, SmallTests.class}) public class TestCurrentHourProvider { - private static final Logger LOG = LoggerFactory.getLogger(TestCurrentHourProvider.class); @ClassRule public static final HBaseClassTestRule CLASS_RULE = HBaseClassTestRule.forClass(TestCurrentHourProvider.class); @@ -42,19 +40,43 @@ public class TestCurrentHourProvider { * and the unix time of 2020-08-20 15:04:00 is 1597907081000, * by calculating the delta time to get expected time in current timezone, * then we can get special hour no matter which timezone it runs. + * + * In addition, we should consider the Daylight Saving Time. + * 1. If in DaylightTime, we need reduce one hour. + * 2. If in DaylightTime and timezone is "Antarctica/Troll", we need reduce two hours. */ @Test public void testWithEnvironmentEdge() { - // set a time represent hour 11 - long deltaFor11 = TimeZone.getDefault().getRawOffset() - 28800000; - long timeFor11 = 1597895561000L - deltaFor11; - EnvironmentEdgeManager.injectEdge(() -> timeFor11); - assertEquals(11, CurrentHourProvider.getCurrentHour()); + // test for all available zoneID + for (String zoneID : TimeZone.getAvailableIDs()) { + TimeZone timezone = TimeZone.getTimeZone(zoneID); + TimeZone.setDefault(timezone); - // set a time represent hour 15 - long deltaFor15 = TimeZone.getDefault().getRawOffset() - 28800000; - long timeFor15 = 1597907081000L - deltaFor15; - EnvironmentEdgeManager.injectEdge(() -> timeFor15); - assertEquals(15, CurrentHourProvider.getCurrentHour()); + // set a time represent hour 11 + long deltaFor11 = TimeZone.getDefault().getRawOffset() - 28800000; + long timeFor11 = 1597895561000L - deltaFor11; + EnvironmentEdgeManager.injectEdge(() -> timeFor11); + CurrentHourProvider.tick = CurrentHourProvider.nextTick(); + int hour11 = CurrentHourProvider.getCurrentHour(); + if (TimeZone.getDefault().inDaylightTime(new Date(timeFor11))) { + hour11 = "Antarctica/Troll".equals(zoneID) ? + CurrentHourProvider.getCurrentHour() - 2 : + CurrentHourProvider.getCurrentHour() - 1; + } + assertEquals(11, hour11); + + // set a time represent hour 15 + long deltaFor15 = TimeZone.getDefault().getRawOffset() - 28800000; + long timeFor15 = 1597907081000L - deltaFor15; + EnvironmentEdgeManager.injectEdge(() -> timeFor15); + CurrentHourProvider.tick = CurrentHourProvider.nextTick(); + int hour15 = CurrentHourProvider.getCurrentHour(); + if (TimeZone.getDefault().inDaylightTime(new Date(timeFor15))) { + hour15 = "Antarctica/Troll".equals(zoneID) ? + CurrentHourProvider.getCurrentHour() - 2 : + CurrentHourProvider.getCurrentHour() - 1; + } + assertEquals(15, hour15); + } } }