From b3f35278cead1c4647a10ae615258555618bd087 Mon Sep 17 00:00:00 2001 From: Florian Zschocke Date: Sat, 23 Oct 2021 23:20:47 +0200 Subject: TimeUtils: Increase testability and add tests Add tests for `timeAgo` to analyse issue #1248. The tests are dependent on when they run as they time functions use the current date and time. To make them testable in a reproducible way, we need the ability to pass in what we think is "now". So add overloaded methods that take a `now` parameter so that we can pass in the current time. --- src/main/java/com/gitblit/utils/TimeUtils.java | 40 ++++++++++++++++++++------ 1 file changed, 32 insertions(+), 8 deletions(-) (limited to 'src/main') diff --git a/src/main/java/com/gitblit/utils/TimeUtils.java b/src/main/java/com/gitblit/utils/TimeUtils.java index c0e98e5d..001e6be6 100644 --- a/src/main/java/com/gitblit/utils/TimeUtils.java +++ b/src/main/java/com/gitblit/utils/TimeUtils.java @@ -59,7 +59,11 @@ public class TimeUtils { * @return true if date is today */ public static boolean isToday(Date date, TimeZone timezone) { - Date now = new Date(); + return isToday(date, timezone, new Date()); + } + + + public static boolean isToday(Date date, TimeZone timezone, Date now) { SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd"); if (timezone != null) { df.setTimeZone(timezone); @@ -74,8 +78,13 @@ public class TimeUtils { * @return true if date is yesterday */ public static boolean isYesterday(Date date, TimeZone timezone) { + return isYesterday(date, timezone, new Date()); + } + + + public static boolean isYesterday(Date date, TimeZone timezone, Date now) { Calendar cal = Calendar.getInstance(); - cal.setTime(new Date()); + cal.setTime(now); cal.add(Calendar.DATE, -1); SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd"); if (timezone != null) { @@ -157,7 +166,12 @@ public class TimeUtils { * @return hours ago */ public static int hoursAgo(Date date, boolean roundup) { - long diff = System.currentTimeMillis() - date.getTime(); + return hoursAgo(date, System.currentTimeMillis(), roundup); + } + + + public static int hoursAgo(Date date, long now, boolean roundup) { + long diff = now - date.getTime(); int hours = (int) (diff / ONEHOUR); if (roundup && (diff % ONEHOUR) >= HALFHOUR) { hours++; @@ -172,7 +186,11 @@ public class TimeUtils { * @return days ago */ public static int daysAgo(Date date) { - long today = ONEDAY * (System.currentTimeMillis()/ONEDAY); + return daysAgo(date, System.currentTimeMillis()); + } + + public static int daysAgo(Date date, long now) { + long today = ONEDAY * (now/ONEDAY); long day = ONEDAY * (date.getTime()/ONEDAY); long diff = today - day; int days = (int) (diff / ONEDAY); @@ -217,13 +235,19 @@ public class TimeUtils { * @return the string representation of the duration OR the css class */ private String timeAgo(Date date, boolean css) { - if (isToday(date, timezone) || isYesterday(date, timezone)) { - int mins = minutesAgo(date, true); + return timeAgo(date, css, System.currentTimeMillis()); + } + + + public String timeAgo(Date date, boolean css, long now) { + Date dNow = new Date(now); + if (isToday(date, timezone, dNow) || isYesterday(date, timezone, dNow)) { + int mins = minutesAgo(date, now, true); if (mins >= 120) { if (css) { return "age1"; } - int hours = hoursAgo(date, true); + int hours = hoursAgo(date, now, true); if (hours > 23) { return yesterday(); } else { @@ -238,7 +262,7 @@ public class TimeUtils { } return translate("gb.time.justNow", "just now"); } else { - int days = daysAgo(date); + int days = daysAgo(date, now); if (css) { if (days <= 7) { return "age2"; -- cgit v1.2.3 From bb15bf10a7052adf0f5feb55db4f894a9053adac Mon Sep 17 00:00:00 2001 From: Florian Zschocke Date: Sat, 23 Oct 2021 23:41:25 +0200 Subject: TimeUtils: Move unit test to same package as TimeUtils is For some reason the `TimeUtilsTest` class is, like almost all tests, in the `com.gitblit.tests` package. But this way all methods in classes which we might predominately need for tests have to be public. So move the unit test class `TimeUtilsTest` to the same package as the class it is testing, i.e. `com.gitblit.utils.TimeUtils`. This way we ca set the new added methods which get the current time passed in to be at least not public. --- src/main/java/com/gitblit/utils/TimeUtils.java | 10 +- src/test/java/com/gitblit/tests/GitBlitSuite.java | 1 + src/test/java/com/gitblit/tests/TimeUtilsTest.java | 265 -------------------- src/test/java/com/gitblit/utils/TimeUtilsTest.java | 266 +++++++++++++++++++++ 4 files changed, 272 insertions(+), 270 deletions(-) delete mode 100644 src/test/java/com/gitblit/tests/TimeUtilsTest.java create mode 100644 src/test/java/com/gitblit/utils/TimeUtilsTest.java (limited to 'src/main') diff --git a/src/main/java/com/gitblit/utils/TimeUtils.java b/src/main/java/com/gitblit/utils/TimeUtils.java index 001e6be6..12737047 100644 --- a/src/main/java/com/gitblit/utils/TimeUtils.java +++ b/src/main/java/com/gitblit/utils/TimeUtils.java @@ -63,7 +63,7 @@ public class TimeUtils { } - public static boolean isToday(Date date, TimeZone timezone, Date now) { + static boolean isToday(Date date, TimeZone timezone, Date now) { SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd"); if (timezone != null) { df.setTimeZone(timezone); @@ -82,7 +82,7 @@ public class TimeUtils { } - public static boolean isYesterday(Date date, TimeZone timezone, Date now) { + static boolean isYesterday(Date date, TimeZone timezone, Date now) { Calendar cal = Calendar.getInstance(); cal.setTime(now); cal.add(Calendar.DATE, -1); @@ -170,7 +170,7 @@ public class TimeUtils { } - public static int hoursAgo(Date date, long now, boolean roundup) { + static int hoursAgo(Date date, long now, boolean roundup) { long diff = now - date.getTime(); int hours = (int) (diff / ONEHOUR); if (roundup && (diff % ONEHOUR) >= HALFHOUR) { @@ -189,7 +189,7 @@ public class TimeUtils { return daysAgo(date, System.currentTimeMillis()); } - public static int daysAgo(Date date, long now) { + static int daysAgo(Date date, long now) { long today = ONEDAY * (now/ONEDAY); long day = ONEDAY * (date.getTime()/ONEDAY); long diff = today - day; @@ -239,7 +239,7 @@ public class TimeUtils { } - public String timeAgo(Date date, boolean css, long now) { + String timeAgo(Date date, boolean css, long now) { Date dNow = new Date(now); if (isToday(date, timezone, dNow) || isYesterday(date, timezone, dNow)) { int mins = minutesAgo(date, now, true); diff --git a/src/test/java/com/gitblit/tests/GitBlitSuite.java b/src/test/java/com/gitblit/tests/GitBlitSuite.java index 3292d090..fbae039c 100644 --- a/src/test/java/com/gitblit/tests/GitBlitSuite.java +++ b/src/test/java/com/gitblit/tests/GitBlitSuite.java @@ -26,6 +26,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +import com.gitblit.utils.TimeUtilsTest; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.RepositoryCache; diff --git a/src/test/java/com/gitblit/tests/TimeUtilsTest.java b/src/test/java/com/gitblit/tests/TimeUtilsTest.java deleted file mode 100644 index 2dde6d51..00000000 --- a/src/test/java/com/gitblit/tests/TimeUtilsTest.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2011 gitblit.com. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.gitblit.tests; - -import java.util.Calendar; -import java.util.Date; -import java.util.TimeZone; - -import org.junit.Test; - -import com.gitblit.utils.TimeUtils; - -public class TimeUtilsTest extends GitblitUnitTest { - - private Date offset(long subtract) { - return new Date(System.currentTimeMillis() - subtract); - } - - private Date offset(long now, long subtract) { - return new Date(now - subtract); - } - - @Test - public void testBasicTimeFunctions() throws Exception { - assertEquals(2, TimeUtils.minutesAgo(offset(2 * TimeUtils.MIN), false)); - assertEquals(3, TimeUtils.minutesAgo(offset((2 * TimeUtils.MIN) + (35 * 1000L)), true)); - - assertEquals(2, TimeUtils.hoursAgo(offset(2 * TimeUtils.ONEHOUR), false)); - assertEquals(3, TimeUtils.hoursAgo(offset(5 * TimeUtils.HALFHOUR), true)); - - assertEquals(4, TimeUtils.daysAgo(offset(4 * TimeUtils.ONEDAY))); - } - - @Test - public void testToday() throws Exception { - assertTrue(TimeUtils.isToday(new Date(), null)); - } - - @Test - public void testYesterday() throws Exception { - assertTrue(TimeUtils.isYesterday(offset(TimeUtils.ONEDAY), null)); - } - - @Test - public void testDurations() throws Exception { - TimeUtils timeUtils = new TimeUtils(); - assertEquals("1 day", timeUtils.duration(1)); - assertEquals("5 days", timeUtils.duration(5)); - assertEquals("3 months", timeUtils.duration(75)); - assertEquals("12 months", timeUtils.duration(364)); - assertEquals("1 year", timeUtils.duration(365 + 0)); - assertEquals("1 year", timeUtils.duration(365 + 10)); - assertEquals("1 year, 1 month", timeUtils.duration(365 + 15)); - assertEquals("1 year, 1 month", timeUtils.duration(365 + 30)); - assertEquals("1 year, 1 month", timeUtils.duration(365 + 44)); - assertEquals("1 year, 2 months", timeUtils.duration(365 + 45)); - assertEquals("1 year, 2 months", timeUtils.duration(365 + 60)); - - assertEquals("2 years", timeUtils.duration(2 * 365 + 0)); - assertEquals("2 years", timeUtils.duration(2 * 365 + 10)); - assertEquals("2 years, 1 month", timeUtils.duration(2 * 365 + 15)); - assertEquals("2 years, 1 month", timeUtils.duration(2 * 365 + 30)); - assertEquals("2 years, 1 month", timeUtils.duration(2 * 365 + 44)); - assertEquals("2 years, 2 months", timeUtils.duration(2 * 365 + 45)); - assertEquals("2 years, 2 months", timeUtils.duration(2 * 365 + 60)); - } - - @Test - public void testTimeAgo() throws Exception { - // standard time ago tests - TimeUtils timeUtils = new TimeUtils(); - assertEquals("just now", timeUtils.timeAgo(offset(1 * TimeUtils.MIN))); - assertEquals("60 mins ago", timeUtils.timeAgo(offset(60 * TimeUtils.MIN))); - assertEquals("2 hours ago", timeUtils.timeAgo(offset(120 * TimeUtils.MIN))); - assertEquals("15 hours ago", timeUtils.timeAgo(offset(15 * TimeUtils.ONEHOUR))); - assertEquals("yesterday", timeUtils.timeAgo(offset(24 * TimeUtils.ONEHOUR))); - assertEquals("2 days ago", timeUtils.timeAgo(offset(2 * TimeUtils.ONEDAY))); - assertEquals("5 weeks ago", timeUtils.timeAgo(offset(35 * TimeUtils.ONEDAY))); - assertEquals("3 months ago", timeUtils.timeAgo(offset(84 * TimeUtils.ONEDAY))); - assertEquals("3 months ago", timeUtils.timeAgo(offset(95 * TimeUtils.ONEDAY))); - assertEquals("4 months ago", timeUtils.timeAgo(offset(104 * TimeUtils.ONEDAY))); - assertEquals("1 year ago", timeUtils.timeAgo(offset(365 * TimeUtils.ONEDAY))); - assertEquals("13 months ago", timeUtils.timeAgo(offset(395 * TimeUtils.ONEDAY))); - assertEquals("2 years ago", timeUtils.timeAgo(offset((2 * 365 + 30) * TimeUtils.ONEDAY))); - } - - @Test - public void testTimeAgoCss() throws Exception { - // css class tests - TimeUtils timeUtils = new TimeUtils(); - assertEquals("age0", timeUtils.timeAgoCss(offset(1 * TimeUtils.MIN))); - assertEquals("age0", timeUtils.timeAgoCss(offset(60 * TimeUtils.MIN))); - assertEquals("age1", timeUtils.timeAgoCss(offset(120 * TimeUtils.MIN))); - assertEquals("age1", timeUtils.timeAgoCss(offset(24 * TimeUtils.ONEHOUR))); - assertEquals("age2", timeUtils.timeAgoCss(offset(2 * TimeUtils.ONEDAY))); - } - - - @Test - public void testTimeAgoYesterday() throws Exception { - TimeZone myTimezone = TimeZone.getTimeZone("GMT"); - TimeUtils timeUtils = new TimeUtils(null, myTimezone); - - Calendar myCal = Calendar.getInstance(myTimezone); - myCal.set(Calendar.HOUR_OF_DAY, 12); - myCal.set(Calendar.MINUTE, 0); - long now = myCal.getTime().getTime(); - - assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,23 * TimeUtils.ONEHOUR), false, now)); - assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,(23 * TimeUtils.ONEHOUR) + (29 * TimeUtils.MIN)), false, now)); - - assertEquals("yesterday", timeUtils.timeAgo(offset(now,(23 * TimeUtils.ONEHOUR) + (31 * TimeUtils.MIN)), false, now)); - assertEquals("yesterday", timeUtils.timeAgo(offset(now,24 * TimeUtils.ONEHOUR), false, now)); - assertEquals("yesterday", timeUtils.timeAgo(offset(now,35 * TimeUtils.ONEHOUR), false, now)); - assertEquals("yesterday", timeUtils.timeAgo(offset(now,36 * TimeUtils.ONEHOUR), false, now)); - - assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,37 * TimeUtils.ONEHOUR), false, now)); - assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,44 * TimeUtils.ONEHOUR), false, now)); - } - - @Test - public void testTimeAgoYesterdayCET() throws Exception { - TimeZone myTimezone = TimeZone.getTimeZone("CET"); - TimeUtils timeUtils = new TimeUtils(null, myTimezone); - - Calendar myCal = Calendar.getInstance(myTimezone); - myCal.set(Calendar.HOUR_OF_DAY, 22); - myCal.set(Calendar.MINUTE, 0); - long now = myCal.getTime().getTime(); - - assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,23 * TimeUtils.ONEHOUR), false, now)); - assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,(23 * TimeUtils.ONEHOUR) + (29 * TimeUtils.MIN)), false, now)); - - assertEquals("yesterday", timeUtils.timeAgo(offset(now,(23 * TimeUtils.ONEHOUR) + (31 * TimeUtils.MIN)), false, now)); - assertEquals("yesterday", timeUtils.timeAgo(offset(now,24 * TimeUtils.ONEHOUR), false, now)); - assertEquals("yesterday", timeUtils.timeAgo(offset(now,36 * TimeUtils.ONEHOUR), false, now)); - assertEquals("yesterday", timeUtils.timeAgo(offset(now,46 * TimeUtils.ONEHOUR), false, now)); - - assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,47 * TimeUtils.ONEHOUR), false, now)); - assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,56 * TimeUtils.ONEHOUR), false, now)); - } - - - @Test - public void testTimeAgoYesterdayPST() throws Exception { - TimeZone myTimezone = TimeZone.getTimeZone("PST"); - TimeUtils timeUtils = new TimeUtils(null, myTimezone); - - Calendar myCal = Calendar.getInstance(myTimezone); - myCal.set(Calendar.HOUR_OF_DAY, 8); - myCal.set(Calendar.MINUTE, 0); - long now = myCal.getTime().getTime(); - - assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,23 * TimeUtils.ONEHOUR), false, now)); - assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,(23 * TimeUtils.ONEHOUR) + (29 * TimeUtils.MIN)), false, now)); - - assertEquals("yesterday", timeUtils.timeAgo(offset(now,(23 * TimeUtils.ONEHOUR) + (31 * TimeUtils.MIN)), false, now)); - assertEquals("yesterday", timeUtils.timeAgo(offset(now,24 * TimeUtils.ONEHOUR), false, now)); - assertEquals("yesterday", timeUtils.timeAgo(offset(now,30 * TimeUtils.ONEHOUR), false, now)); - assertEquals("yesterday", timeUtils.timeAgo(offset(now,32 * TimeUtils.ONEHOUR), false, now)); - - assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,33 * TimeUtils.ONEHOUR), false, now)); - assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,48 * TimeUtils.ONEHOUR), false, now)); - } - - @Test - public void testFrequency() { - assertEquals(5, TimeUtils.convertFrequencyToMinutes("2 mins", 5)); - assertEquals(10, TimeUtils.convertFrequencyToMinutes("10 mins", 5)); - assertEquals(600, TimeUtils.convertFrequencyToMinutes("10 hours", 5)); - assertEquals(14400, TimeUtils.convertFrequencyToMinutes(" 10 days ", 5)); - } - - - @Test - public void testTimeAgoDaysAgo() throws Exception { - TimeZone myTimezone = TimeZone.getTimeZone("GMT"); - TimeUtils timeUtils = new TimeUtils(null, myTimezone); - - Calendar myCal = Calendar.getInstance(myTimezone); - myCal.set(Calendar.HOUR_OF_DAY, 12); - myCal.set(Calendar.MINUTE, 0); - long now = myCal.getTime().getTime(); - - assertEquals("yesterday", timeUtils.timeAgo(offset(now,24 * TimeUtils.ONEHOUR), false, now)); - assertEquals("yesterday", timeUtils.timeAgo(offset(now,36 * TimeUtils.ONEHOUR), false, now)); - - assertEquals("2 days ago", timeUtils.timeAgo(offset(now,37 * TimeUtils.ONEHOUR), false, now)); - assertEquals("2 days ago", timeUtils.timeAgo(offset(now,48 * TimeUtils.ONEHOUR), false, now)); - assertEquals("2 days ago", timeUtils.timeAgo(offset(now,60 * TimeUtils.ONEHOUR), false, now)); - - assertEquals("3 days ago", timeUtils.timeAgo(offset(now,61 * TimeUtils.ONEHOUR), false, now)); - assertEquals("3 days ago", timeUtils.timeAgo(offset(now,72 * TimeUtils.ONEHOUR), false, now)); - assertEquals("3 days ago", timeUtils.timeAgo(offset(now,84 * TimeUtils.ONEHOUR), false, now)); - - assertEquals("4 days ago", timeUtils.timeAgo(offset(now,85 * TimeUtils.ONEHOUR), false, now)); - } - - - - @Test - public void testTimeAgoDaysAgoCET() throws Exception { - TimeZone myTimezone = TimeZone.getTimeZone("CET"); - TimeUtils timeUtils = new TimeUtils(null, myTimezone); - - Calendar myCal = Calendar.getInstance(myTimezone); - myCal.set(Calendar.HOUR_OF_DAY, 8); - myCal.set(Calendar.MINUTE, 0); - long now = myCal.getTime().getTime(); - - - assertEquals("yesterday", timeUtils.timeAgo(offset(now,24 * TimeUtils.ONEHOUR), false, now)); - assertEquals("yesterday", timeUtils.timeAgo(offset(now,32 * TimeUtils.ONEHOUR), false, now)); - - assertEquals("2 days ago", timeUtils.timeAgo(offset(now,33 * TimeUtils.ONEHOUR), false, now)); - assertEquals("2 days ago", timeUtils.timeAgo(offset(now,48 * TimeUtils.ONEHOUR), false, now)); - assertEquals("2 days ago", timeUtils.timeAgo(offset(now,56 * TimeUtils.ONEHOUR), false, now)); - - assertEquals("3 days ago", timeUtils.timeAgo(offset(now,57 * TimeUtils.ONEHOUR), false, now)); - assertEquals("3 days ago", timeUtils.timeAgo(offset(now,72 * TimeUtils.ONEHOUR), false, now)); - assertEquals("3 days ago", timeUtils.timeAgo(offset(now,80 * TimeUtils.ONEHOUR), false, now)); - - assertEquals("4 days ago", timeUtils.timeAgo(offset(now,81 * TimeUtils.ONEHOUR), false, now)); - } - - - - @Test - public void testTimeAgoDaysAgoPST() throws Exception { - TimeZone myTimezone = TimeZone.getTimeZone("PST"); - TimeUtils timeUtils = new TimeUtils(null, myTimezone); - - Calendar myCal = Calendar.getInstance(myTimezone); - myCal.set(Calendar.HOUR_OF_DAY, 22); - myCal.set(Calendar.MINUTE, 0); - long now = myCal.getTime().getTime(); - - assertEquals("yesterday", timeUtils.timeAgo(offset(now,24 * TimeUtils.ONEHOUR), false, now)); - assertEquals("yesterday", timeUtils.timeAgo(offset(now,46 * TimeUtils.ONEHOUR), false, now)); - - assertEquals("2 days ago", timeUtils.timeAgo(offset(now,47 * TimeUtils.ONEHOUR), false, now)); - assertEquals("2 days ago", timeUtils.timeAgo(offset(now,48 * TimeUtils.ONEHOUR), false, now)); - assertEquals("2 days ago", timeUtils.timeAgo(offset(now,70 * TimeUtils.ONEHOUR), false, now)); - - assertEquals("3 days ago", timeUtils.timeAgo(offset(now,71 * TimeUtils.ONEHOUR), false, now)); - assertEquals("3 days ago", timeUtils.timeAgo(offset(now,72 * TimeUtils.ONEHOUR), false, now)); - assertEquals("3 days ago", timeUtils.timeAgo(offset(now,94 * TimeUtils.ONEHOUR), false, now)); - - assertEquals("4 days ago", timeUtils.timeAgo(offset(now,95 * TimeUtils.ONEHOUR), false, now)); - } - -} diff --git a/src/test/java/com/gitblit/utils/TimeUtilsTest.java b/src/test/java/com/gitblit/utils/TimeUtilsTest.java new file mode 100644 index 00000000..77710e06 --- /dev/null +++ b/src/test/java/com/gitblit/utils/TimeUtilsTest.java @@ -0,0 +1,266 @@ +/* + * Copyright 2011 gitblit.com. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.gitblit.utils; + +import java.util.Calendar; +import java.util.Date; +import java.util.TimeZone; + +import com.gitblit.tests.GitblitUnitTest; +import org.junit.Test; + + +public class TimeUtilsTest extends GitblitUnitTest +{ + + private Date offset(long subtract) { + return new Date(System.currentTimeMillis() - subtract); + } + + private Date offset(long now, long subtract) { + return new Date(now - subtract); + } + + @Test + public void testBasicTimeFunctions() throws Exception { + assertEquals(2, TimeUtils.minutesAgo(offset(2 * TimeUtils.MIN), false)); + assertEquals(3, TimeUtils.minutesAgo(offset((2 * TimeUtils.MIN) + (35 * 1000L)), true)); + + assertEquals(2, TimeUtils.hoursAgo(offset(2 * TimeUtils.ONEHOUR), false)); + assertEquals(3, TimeUtils.hoursAgo(offset(5 * TimeUtils.HALFHOUR), true)); + + assertEquals(4, TimeUtils.daysAgo(offset(4 * TimeUtils.ONEDAY))); + } + + @Test + public void testToday() throws Exception { + assertTrue(TimeUtils.isToday(new Date(), null)); + } + + @Test + public void testYesterday() throws Exception { + assertTrue(TimeUtils.isYesterday(offset(TimeUtils.ONEDAY), null)); + } + + @Test + public void testDurations() throws Exception { + TimeUtils timeUtils = new TimeUtils(); + assertEquals("1 day", timeUtils.duration(1)); + assertEquals("5 days", timeUtils.duration(5)); + assertEquals("3 months", timeUtils.duration(75)); + assertEquals("12 months", timeUtils.duration(364)); + assertEquals("1 year", timeUtils.duration(365 + 0)); + assertEquals("1 year", timeUtils.duration(365 + 10)); + assertEquals("1 year, 1 month", timeUtils.duration(365 + 15)); + assertEquals("1 year, 1 month", timeUtils.duration(365 + 30)); + assertEquals("1 year, 1 month", timeUtils.duration(365 + 44)); + assertEquals("1 year, 2 months", timeUtils.duration(365 + 45)); + assertEquals("1 year, 2 months", timeUtils.duration(365 + 60)); + + assertEquals("2 years", timeUtils.duration(2 * 365 + 0)); + assertEquals("2 years", timeUtils.duration(2 * 365 + 10)); + assertEquals("2 years, 1 month", timeUtils.duration(2 * 365 + 15)); + assertEquals("2 years, 1 month", timeUtils.duration(2 * 365 + 30)); + assertEquals("2 years, 1 month", timeUtils.duration(2 * 365 + 44)); + assertEquals("2 years, 2 months", timeUtils.duration(2 * 365 + 45)); + assertEquals("2 years, 2 months", timeUtils.duration(2 * 365 + 60)); + } + + @Test + public void testTimeAgo() throws Exception { + // standard time ago tests + TimeUtils timeUtils = new TimeUtils(); + assertEquals("just now", timeUtils.timeAgo(offset(1 * TimeUtils.MIN))); + assertEquals("60 mins ago", timeUtils.timeAgo(offset(60 * TimeUtils.MIN))); + assertEquals("2 hours ago", timeUtils.timeAgo(offset(120 * TimeUtils.MIN))); + assertEquals("15 hours ago", timeUtils.timeAgo(offset(15 * TimeUtils.ONEHOUR))); + assertEquals("yesterday", timeUtils.timeAgo(offset(24 * TimeUtils.ONEHOUR))); + assertEquals("2 days ago", timeUtils.timeAgo(offset(2 * TimeUtils.ONEDAY))); + assertEquals("5 weeks ago", timeUtils.timeAgo(offset(35 * TimeUtils.ONEDAY))); + assertEquals("3 months ago", timeUtils.timeAgo(offset(84 * TimeUtils.ONEDAY))); + assertEquals("3 months ago", timeUtils.timeAgo(offset(95 * TimeUtils.ONEDAY))); + assertEquals("4 months ago", timeUtils.timeAgo(offset(104 * TimeUtils.ONEDAY))); + assertEquals("1 year ago", timeUtils.timeAgo(offset(365 * TimeUtils.ONEDAY))); + assertEquals("13 months ago", timeUtils.timeAgo(offset(395 * TimeUtils.ONEDAY))); + assertEquals("2 years ago", timeUtils.timeAgo(offset((2 * 365 + 30) * TimeUtils.ONEDAY))); + } + + @Test + public void testTimeAgoCss() throws Exception { + // css class tests + TimeUtils timeUtils = new TimeUtils(); + assertEquals("age0", timeUtils.timeAgoCss(offset(1 * TimeUtils.MIN))); + assertEquals("age0", timeUtils.timeAgoCss(offset(60 * TimeUtils.MIN))); + assertEquals("age1", timeUtils.timeAgoCss(offset(120 * TimeUtils.MIN))); + assertEquals("age1", timeUtils.timeAgoCss(offset(24 * TimeUtils.ONEHOUR))); + assertEquals("age2", timeUtils.timeAgoCss(offset(2 * TimeUtils.ONEDAY))); + } + + + @Test + public void testTimeAgoYesterday() throws Exception { + TimeZone myTimezone = TimeZone.getTimeZone("GMT"); + TimeUtils timeUtils = new TimeUtils(null, myTimezone); + + Calendar myCal = Calendar.getInstance(myTimezone); + myCal.set(Calendar.HOUR_OF_DAY, 12); + myCal.set(Calendar.MINUTE, 0); + long now = myCal.getTime().getTime(); + + assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,23 * TimeUtils.ONEHOUR), false, now)); + assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,(23 * TimeUtils.ONEHOUR) + (29 * TimeUtils.MIN)), false, now)); + + assertEquals("yesterday", timeUtils.timeAgo(offset(now,(23 * TimeUtils.ONEHOUR) + (31 * TimeUtils.MIN)), false, now)); + assertEquals("yesterday", timeUtils.timeAgo(offset(now,24 * TimeUtils.ONEHOUR), false, now)); + assertEquals("yesterday", timeUtils.timeAgo(offset(now,35 * TimeUtils.ONEHOUR), false, now)); + assertEquals("yesterday", timeUtils.timeAgo(offset(now,36 * TimeUtils.ONEHOUR), false, now)); + + assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,37 * TimeUtils.ONEHOUR), false, now)); + assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,44 * TimeUtils.ONEHOUR), false, now)); + } + + @Test + public void testTimeAgoYesterdayCET() throws Exception { + TimeZone myTimezone = TimeZone.getTimeZone("CET"); + TimeUtils timeUtils = new TimeUtils(null, myTimezone); + + Calendar myCal = Calendar.getInstance(myTimezone); + myCal.set(Calendar.HOUR_OF_DAY, 22); + myCal.set(Calendar.MINUTE, 0); + long now = myCal.getTime().getTime(); + + assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,23 * TimeUtils.ONEHOUR), false, now)); + assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,(23 * TimeUtils.ONEHOUR) + (29 * TimeUtils.MIN)), false, now)); + + assertEquals("yesterday", timeUtils.timeAgo(offset(now,(23 * TimeUtils.ONEHOUR) + (31 * TimeUtils.MIN)), false, now)); + assertEquals("yesterday", timeUtils.timeAgo(offset(now,24 * TimeUtils.ONEHOUR), false, now)); + assertEquals("yesterday", timeUtils.timeAgo(offset(now,36 * TimeUtils.ONEHOUR), false, now)); + assertEquals("yesterday", timeUtils.timeAgo(offset(now,46 * TimeUtils.ONEHOUR), false, now)); + + assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,47 * TimeUtils.ONEHOUR), false, now)); + assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,56 * TimeUtils.ONEHOUR), false, now)); + } + + + @Test + public void testTimeAgoYesterdayPST() throws Exception { + TimeZone myTimezone = TimeZone.getTimeZone("PST"); + TimeUtils timeUtils = new TimeUtils(null, myTimezone); + + Calendar myCal = Calendar.getInstance(myTimezone); + myCal.set(Calendar.HOUR_OF_DAY, 8); + myCal.set(Calendar.MINUTE, 0); + long now = myCal.getTime().getTime(); + + assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,23 * TimeUtils.ONEHOUR), false, now)); + assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,(23 * TimeUtils.ONEHOUR) + (29 * TimeUtils.MIN)), false, now)); + + assertEquals("yesterday", timeUtils.timeAgo(offset(now,(23 * TimeUtils.ONEHOUR) + (31 * TimeUtils.MIN)), false, now)); + assertEquals("yesterday", timeUtils.timeAgo(offset(now,24 * TimeUtils.ONEHOUR), false, now)); + assertEquals("yesterday", timeUtils.timeAgo(offset(now,30 * TimeUtils.ONEHOUR), false, now)); + assertEquals("yesterday", timeUtils.timeAgo(offset(now,32 * TimeUtils.ONEHOUR), false, now)); + + assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,33 * TimeUtils.ONEHOUR), false, now)); + assertNotEquals("yesterday", timeUtils.timeAgo(offset(now,48 * TimeUtils.ONEHOUR), false, now)); + } + + @Test + public void testFrequency() { + assertEquals(5, TimeUtils.convertFrequencyToMinutes("2 mins", 5)); + assertEquals(10, TimeUtils.convertFrequencyToMinutes("10 mins", 5)); + assertEquals(600, TimeUtils.convertFrequencyToMinutes("10 hours", 5)); + assertEquals(14400, TimeUtils.convertFrequencyToMinutes(" 10 days ", 5)); + } + + + @Test + public void testTimeAgoDaysAgo() throws Exception { + TimeZone myTimezone = TimeZone.getTimeZone("GMT"); + TimeUtils timeUtils = new TimeUtils(null, myTimezone); + + Calendar myCal = Calendar.getInstance(myTimezone); + myCal.set(Calendar.HOUR_OF_DAY, 12); + myCal.set(Calendar.MINUTE, 0); + long now = myCal.getTime().getTime(); + + assertEquals("yesterday", timeUtils.timeAgo(offset(now,24 * TimeUtils.ONEHOUR), false, now)); + assertEquals("yesterday", timeUtils.timeAgo(offset(now,36 * TimeUtils.ONEHOUR), false, now)); + + assertEquals("2 days ago", timeUtils.timeAgo(offset(now,37 * TimeUtils.ONEHOUR), false, now)); + assertEquals("2 days ago", timeUtils.timeAgo(offset(now,48 * TimeUtils.ONEHOUR), false, now)); + assertEquals("2 days ago", timeUtils.timeAgo(offset(now,60 * TimeUtils.ONEHOUR), false, now)); + + assertEquals("3 days ago", timeUtils.timeAgo(offset(now,61 * TimeUtils.ONEHOUR), false, now)); + assertEquals("3 days ago", timeUtils.timeAgo(offset(now,72 * TimeUtils.ONEHOUR), false, now)); + assertEquals("3 days ago", timeUtils.timeAgo(offset(now,84 * TimeUtils.ONEHOUR), false, now)); + + assertEquals("4 days ago", timeUtils.timeAgo(offset(now,85 * TimeUtils.ONEHOUR), false, now)); + } + + + + @Test + public void testTimeAgoDaysAgoCET() throws Exception { + TimeZone myTimezone = TimeZone.getTimeZone("CET"); + TimeUtils timeUtils = new TimeUtils(null, myTimezone); + + Calendar myCal = Calendar.getInstance(myTimezone); + myCal.set(Calendar.HOUR_OF_DAY, 8); + myCal.set(Calendar.MINUTE, 0); + long now = myCal.getTime().getTime(); + + + assertEquals("yesterday", timeUtils.timeAgo(offset(now,24 * TimeUtils.ONEHOUR), false, now)); + assertEquals("yesterday", timeUtils.timeAgo(offset(now,32 * TimeUtils.ONEHOUR), false, now)); + + assertEquals("2 days ago", timeUtils.timeAgo(offset(now,33 * TimeUtils.ONEHOUR), false, now)); + assertEquals("2 days ago", timeUtils.timeAgo(offset(now,48 * TimeUtils.ONEHOUR), false, now)); + assertEquals("2 days ago", timeUtils.timeAgo(offset(now,56 * TimeUtils.ONEHOUR), false, now)); + + assertEquals("3 days ago", timeUtils.timeAgo(offset(now,57 * TimeUtils.ONEHOUR), false, now)); + assertEquals("3 days ago", timeUtils.timeAgo(offset(now,72 * TimeUtils.ONEHOUR), false, now)); + assertEquals("3 days ago", timeUtils.timeAgo(offset(now,80 * TimeUtils.ONEHOUR), false, now)); + + assertEquals("4 days ago", timeUtils.timeAgo(offset(now,81 * TimeUtils.ONEHOUR), false, now)); + } + + + + @Test + public void testTimeAgoDaysAgoPST() throws Exception { + TimeZone myTimezone = TimeZone.getTimeZone("PST"); + TimeUtils timeUtils = new TimeUtils(null, myTimezone); + + Calendar myCal = Calendar.getInstance(myTimezone); + myCal.set(Calendar.HOUR_OF_DAY, 22); + myCal.set(Calendar.MINUTE, 0); + long now = myCal.getTime().getTime(); + + assertEquals("yesterday", timeUtils.timeAgo(offset(now,24 * TimeUtils.ONEHOUR), false, now)); + assertEquals("yesterday", timeUtils.timeAgo(offset(now,46 * TimeUtils.ONEHOUR), false, now)); + + assertEquals("2 days ago", timeUtils.timeAgo(offset(now,47 * TimeUtils.ONEHOUR), false, now)); + assertEquals("2 days ago", timeUtils.timeAgo(offset(now,48 * TimeUtils.ONEHOUR), false, now)); + assertEquals("2 days ago", timeUtils.timeAgo(offset(now,70 * TimeUtils.ONEHOUR), false, now)); + + assertEquals("3 days ago", timeUtils.timeAgo(offset(now,71 * TimeUtils.ONEHOUR), false, now)); + assertEquals("3 days ago", timeUtils.timeAgo(offset(now,72 * TimeUtils.ONEHOUR), false, now)); + assertEquals("3 days ago", timeUtils.timeAgo(offset(now,94 * TimeUtils.ONEHOUR), false, now)); + + assertEquals("4 days ago", timeUtils.timeAgo(offset(now,95 * TimeUtils.ONEHOUR), false, now)); + } + +} -- cgit v1.2.3 From 920fc522b47b90c534848dc926af1bbc5f517592 Mon Sep 17 00:00:00 2001 From: Florian Zschocke Date: Sun, 24 Oct 2021 00:44:18 +0200 Subject: TimeUtils: Change daysAgo to calculate difference in calendar days The `daysAgo` method seemed to want to normalize on a calendar day? I can't really tell what it was trying to do, but the problem is that it does not take into account any time shift due to time zones so it never really worked outside of GMT. So instead a new `calendarDaysAgo` method is added (because I am unsure on what the `daysAgo` method is trying to do. It can probably be removed). The new method cleanly calculates difference in calendar days because it normalizes the two given time stamps on the same time zone. The `timeAgo` method now used the new method. This fixes #1248. --- src/main/java/com/gitblit/utils/TimeUtils.java | 53 ++- src/test/java/com/gitblit/utils/TimeUtilsTest.java | 424 +++++++++++++++++++++ 2 files changed, 476 insertions(+), 1 deletion(-) (limited to 'src/main') diff --git a/src/main/java/com/gitblit/utils/TimeUtils.java b/src/main/java/com/gitblit/utils/TimeUtils.java index 12737047..6e0d3534 100644 --- a/src/main/java/com/gitblit/utils/TimeUtils.java +++ b/src/main/java/com/gitblit/utils/TimeUtils.java @@ -197,6 +197,57 @@ public class TimeUtils { return days; } + + + /** + * Return the difference in calendar days between a given timestamp and the date. + * Calendar days means that the difference is calculated between + * calendar days, not 24 hour increments. + * + * This means the result is dependent on the timezone. Only the local + * time's time zone is used, i.e. both time stamps are interpreted in + * the given time zone. + * + * E.g. if now is 10:00 on 20.10.2020 GMT and the date given is for + * either 6:00 or 20:00 on 18.10.2020 GMT then the result is two days + * in both cases. + * + * + * @param date + * Date in the past + * @param now + * Timestamp representing current time (used for unit tests) + * @return calendar days ago + */ + static int calendarDaysAgo(Date date, TimeZone timezone, long now) { + Calendar cal; + if (timezone == null) { + cal = Calendar.getInstance(); + } else { + cal = Calendar.getInstance(timezone); + } + + cal.setTimeInMillis(now); + cal.set(Calendar.MILLISECOND, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.HOUR_OF_DAY, 12); + long today = cal.getTime().getTime(); + + cal.clear(); + cal.setTime(date); + cal.set(Calendar.MILLISECOND, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.HOUR_OF_DAY, 12); + long day = cal.getTime().getTime(); + + long diff = today - day; + int days = (int) (diff / ONEDAY); + return days; + } + + public String today() { return translate("gb.time.today", "today"); } @@ -262,7 +313,7 @@ public class TimeUtils { } return translate("gb.time.justNow", "just now"); } else { - int days = daysAgo(date, now); + int days = calendarDaysAgo(date, timezone, now); if (css) { if (days <= 7) { return "age2"; diff --git a/src/test/java/com/gitblit/utils/TimeUtilsTest.java b/src/test/java/com/gitblit/utils/TimeUtilsTest.java index 77710e06..0e58a364 100644 --- a/src/test/java/com/gitblit/utils/TimeUtilsTest.java +++ b/src/test/java/com/gitblit/utils/TimeUtilsTest.java @@ -263,4 +263,428 @@ public class TimeUtilsTest extends GitblitUnitTest assertEquals("4 days ago", timeUtils.timeAgo(offset(now,95 * TimeUtils.ONEHOUR), false, now)); } + + + /* + * Test if time difference is correctly calculated in full calendar days relative to GMT. + */ + @Test + public void testCalendarDaysAgoToGmt() { + TimeZone myTimezone = TimeZone.getTimeZone("GMT"); + + Calendar myCal = Calendar.getInstance(myTimezone); + myCal.set(2021, Calendar.AUGUST, 19, 12, 0, 5); + long now = myCal.getTime().getTime(); + // Date from the same time zone + assertEquals(0, TimeUtils.calendarDaysAgo(offset(now, 11 * TimeUtils.ONEHOUR ), myTimezone, now)); + assertEquals(0, TimeUtils.calendarDaysAgo(offset(now, 12 * TimeUtils.ONEHOUR ), myTimezone, now)); + + assertEquals(1, TimeUtils.calendarDaysAgo(offset(now, 12 * TimeUtils.ONEHOUR + 1 * TimeUtils.MIN), myTimezone, now)); + assertEquals(1, TimeUtils.calendarDaysAgo(offset(now, 24 * TimeUtils.ONEHOUR ), myTimezone, now)); + assertEquals(1, TimeUtils.calendarDaysAgo(offset(now, 36 * TimeUtils.ONEHOUR ), myTimezone, now)); + + assertEquals(2, TimeUtils.calendarDaysAgo(offset(now, 36 * TimeUtils.ONEHOUR + 10 * 1000), myTimezone, now)); + assertEquals(2, TimeUtils.calendarDaysAgo(offset(now, 48 * TimeUtils.ONEHOUR ), myTimezone, now)); + assertEquals(2, TimeUtils.calendarDaysAgo(offset(now, 60 * TimeUtils.ONEHOUR ), myTimezone, now)); + + assertEquals(3, TimeUtils.calendarDaysAgo(offset(now, 61 * TimeUtils.ONEHOUR ), myTimezone, now)); + + + // What if we get passed a date created from a UTC timestamp that came from a different time zone? + // CET in August is +2 hours from GMT (CEST). So the day border is shifted two hours forward + + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("CET")); + + cal.set(2021, Calendar.AUGUST, 19, 8, 0, 5); + Date date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2021, Calendar.AUGUST, 19, 2, 0, 5); + date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2021, Calendar.AUGUST, 19, 1, 30, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2021, Calendar.AUGUST, 18, 12, 0, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2021, Calendar.AUGUST, 18, 2, 0, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2021, Calendar.AUGUST, 18, 0, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2021, Calendar.AUGUST, 17, 23, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2021, Calendar.AUGUST, 17, 3, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2021, Calendar.AUGUST, 17, 1, 0, 5); + date = cal.getTime(); + assertEquals(3, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + // Now we travel westwards. + // PST in August is -7 hours from GMT (PDT). So the day border is shifted seven hours back + + cal = Calendar.getInstance(TimeZone.getTimeZone("PST")); + cal.clear(); + + cal.set(2021, Calendar.AUGUST, 19, 5, 0, 0); + date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2021, Calendar.AUGUST, 19, 0, 0, 5); + date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2021, Calendar.AUGUST, 18, 17, 0, 5); + date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2021, Calendar.AUGUST, 18, 16, 55, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2021, Calendar.AUGUST, 18, 12, 0, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2021, Calendar.AUGUST, 17, 17, 0, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2021, Calendar.AUGUST, 17, 16, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2021, Calendar.AUGUST, 17, 1, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2021, Calendar.AUGUST, 16, 17, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2021, Calendar.AUGUST, 16, 14, 0, 5); + date = cal.getTime(); + assertEquals(3, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + } + + + /* + * Test if time difference is correctly calculated in full calendar days relative to CET. + */ + @Test + public void testCalendarDaysAgoToCet() { + TimeZone myTimezone = TimeZone.getTimeZone("CET"); + + Calendar myCal = Calendar.getInstance(myTimezone); + myCal.set(2020, Calendar.JUNE, 5, 12, 0, 5); + long now = myCal.getTime().getTime(); + + // Date from the same time zone + assertEquals(0, TimeUtils.calendarDaysAgo(offset(now, 11 * TimeUtils.ONEHOUR ), myTimezone, now)); + assertEquals(0, TimeUtils.calendarDaysAgo(offset(now, 12 * TimeUtils.ONEHOUR ), myTimezone, now)); + + assertEquals(1, TimeUtils.calendarDaysAgo(offset(now, 12 * TimeUtils.ONEHOUR + 1 * TimeUtils.MIN), myTimezone, now)); + assertEquals(1, TimeUtils.calendarDaysAgo(offset(now, 24 * TimeUtils.ONEHOUR ), myTimezone, now)); + assertEquals(1, TimeUtils.calendarDaysAgo(offset(now, 36 * TimeUtils.ONEHOUR ), myTimezone, now)); + + assertEquals(2, TimeUtils.calendarDaysAgo(offset(now, 36 * TimeUtils.ONEHOUR + 10 * 1000), myTimezone, now)); + assertEquals(2, TimeUtils.calendarDaysAgo(offset(now, 48 * TimeUtils.ONEHOUR ), myTimezone, now)); + assertEquals(2, TimeUtils.calendarDaysAgo(offset(now, 60 * TimeUtils.ONEHOUR ), myTimezone, now)); + + assertEquals(3, TimeUtils.calendarDaysAgo(offset(now, 61 * TimeUtils.ONEHOUR ), myTimezone, now)); + + + // What if we get passed a date created from a UTC timestamp that came from a different time zone? + // IST in June is +3:30 hours from CEST. So the day border is shifted three and a half hours forward + + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("IST")); + + cal.set(2020, Calendar.JUNE, 5, 13, 0, 5); + Date date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2020, Calendar.JUNE, 5, 3, 30, 5); + date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2020, Calendar.JUNE, 5, 3, 29, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2020, Calendar.JUNE, 5, 0, 0, 0); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2020, Calendar.JUNE, 4, 10, 0, 0); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2020, Calendar.JUNE, 4, 4, 0, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2020, Calendar.JUNE, 4, 3, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2020, Calendar.JUNE, 3, 12, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2020, Calendar.JUNE, 3, 4, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2020, Calendar.JUNE, 3, 3, 20, 5); + date = cal.getTime(); + assertEquals(3, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + // Now we travel westwards to New York. + // EST in June is -6 hours from CEST (EDT). So the day border is shifted six hours back + + cal = Calendar.getInstance(TimeZone.getTimeZone("EST5EDT")); + cal.clear(); + + cal.set(2020, Calendar.JUNE, 5, 5, 0, 5); + date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2020, Calendar.JUNE, 5, 0, 0, 5); + date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2020, Calendar.JUNE, 4, 18, 0, 5); + date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2020, Calendar.JUNE, 4, 17, 59, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2020, Calendar.JUNE, 4, 12, 0, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2020, Calendar.JUNE, 3, 19, 0, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2020, Calendar.JUNE, 3, 17, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2020, Calendar.JUNE, 3, 8, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2020, Calendar.JUNE, 2, 18, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2020, Calendar.JUNE, 2, 17, 20, 5); + date = cal.getTime(); + assertEquals(3, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + } + + + /* + * Test if time difference is correctly calculated in full calendar days relative to AET (Australia). + */ + @Test + public void testCalendarDaysAgoToAet() { + TimeZone myTimezone = TimeZone.getTimeZone("AET"); + + Calendar myCal = Calendar.getInstance(myTimezone); + myCal.set(2022, Calendar.FEBRUARY, 22, 12, 0, 5); + long now = myCal.getTime().getTime(); + + // Date from the same time zone + assertEquals(0, TimeUtils.calendarDaysAgo(offset(now, 11 * TimeUtils.ONEHOUR ), myTimezone, now)); + assertEquals(0, TimeUtils.calendarDaysAgo(offset(now, 12 * TimeUtils.ONEHOUR ), myTimezone, now)); + + assertEquals(1, TimeUtils.calendarDaysAgo(offset(now, 12 * TimeUtils.ONEHOUR + 1 * TimeUtils.MIN), myTimezone, now)); + assertEquals(1, TimeUtils.calendarDaysAgo(offset(now, 24 * TimeUtils.ONEHOUR ), myTimezone, now)); + assertEquals(1, TimeUtils.calendarDaysAgo(offset(now, 36 * TimeUtils.ONEHOUR ), myTimezone, now)); + + assertEquals(2, TimeUtils.calendarDaysAgo(offset(now, 36 * TimeUtils.ONEHOUR + 10 * 1000), myTimezone, now)); + assertEquals(2, TimeUtils.calendarDaysAgo(offset(now, 48 * TimeUtils.ONEHOUR ), myTimezone, now)); + assertEquals(2, TimeUtils.calendarDaysAgo(offset(now, 60 * TimeUtils.ONEHOUR ), myTimezone, now)); + + assertEquals(3, TimeUtils.calendarDaysAgo(offset(now, 61 * TimeUtils.ONEHOUR ), myTimezone, now)); + + + // What if we get passed a date created from a UTC timestamp that came from a different time zone? + // NZ in February is +2 hours from AEDT. So the day border is shifted two hours forward + + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("NZ")); + + cal.set(2022, Calendar.FEBRUARY, 22, 12, 0, 5); + Date date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 22, 2, 0, 5); + date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2022, Calendar.FEBRUARY, 22, 1, 45, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 21, 22, 0, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 21, 12, 0, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 21, 2, 0, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2022, Calendar.FEBRUARY, 21, 1, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 20, 10, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 20, 2, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2022, Calendar.FEBRUARY, 20, 1, 0, 5); + date = cal.getTime(); + assertEquals(3, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + // Now we travel westwards to Europe. + // CET in February is -10 hours from AEDT. So the day border is shifted ten hours back + + cal = Calendar.getInstance(TimeZone.getTimeZone("CET")); + cal.clear(); + + cal.set(2022, Calendar.FEBRUARY, 22, 2, 0, 5); + date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 22, 0, 0, 5); + date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 21, 14, 0, 5); + date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2022, Calendar.FEBRUARY, 21, 13, 30, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 21, 7, 0, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 20, 15, 0, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2022, Calendar.FEBRUARY, 20, 13, 59, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 20, 1, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 19, 14, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2022, Calendar.FEBRUARY, 19, 9, 0, 5); + date = cal.getTime(); + assertEquals(3, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + // Lets continue even further west. + // AST in February is -15 hours from AEDT. So the day border is shifted fifteen hours back + + cal = Calendar.getInstance(TimeZone.getTimeZone("America/Curacao")); + cal.clear(); + + cal.set(2022, Calendar.FEBRUARY, 21, 21, 0, 0); + date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 21, 12, 0, 5); + date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 21, 9, 0, 5); + date = cal.getTime(); + assertEquals(0, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2022, Calendar.FEBRUARY, 21, 8, 0, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 20, 19, 0, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 20, 10, 0, 5); + date = cal.getTime(); + assertEquals(1, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2022, Calendar.FEBRUARY, 20, 8, 50, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 19, 17, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + cal.set(2022, Calendar.FEBRUARY, 19, 9, 0, 5); + date = cal.getTime(); + assertEquals(2, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + + + cal.set(2022, Calendar.FEBRUARY, 19, 7, 0, 5); + date = cal.getTime(); + assertEquals(3, TimeUtils.calendarDaysAgo(date, myTimezone, now)); + } + } -- cgit v1.2.3