Skip to content

Commit 3c306a0

Browse files
authored
Merge pull request #5067 from Isira-Seneviratne/Add_workaround_for_null_offset_ID
Add a workaround for a possible null offset ID.
2 parents b27b49e + c0d6c8a commit 3c306a0

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,29 @@
11
package org.schabi.newpipe.ktx
22

33
import java.time.OffsetDateTime
4-
import java.time.ZoneId
4+
import java.time.ZoneOffset
5+
import java.time.temporal.ChronoField
56
import java.util.Calendar
7+
import java.util.Date
68
import java.util.GregorianCalendar
9+
import java.util.TimeZone
710

8-
fun OffsetDateTime.toCalendar(zoneId: ZoneId = ZoneId.systemDefault()): Calendar {
9-
return GregorianCalendar.from(if (zoneId != offset) atZoneSameInstant(zoneId) else toZonedDateTime())
11+
// This method is a modified version of GregorianCalendar.from(ZonedDateTime).
12+
// Math.addExact() and Math.multiplyExact() are desugared even though lint displays a warning.
13+
@SuppressWarnings("NewApi")
14+
fun OffsetDateTime.toCalendar(): Calendar {
15+
val cal = GregorianCalendar(TimeZone.getTimeZone("UTC"))
16+
val offsetDateTimeUTC = withOffsetSameInstant(ZoneOffset.UTC)
17+
cal.gregorianChange = Date(Long.MIN_VALUE)
18+
cal.firstDayOfWeek = Calendar.MONDAY
19+
cal.minimalDaysInFirstWeek = 4
20+
try {
21+
cal.timeInMillis = Math.addExact(
22+
Math.multiplyExact(offsetDateTimeUTC.toEpochSecond(), 1000),
23+
offsetDateTimeUTC[ChronoField.MILLI_OF_SECOND].toLong()
24+
)
25+
} catch (ex: ArithmeticException) {
26+
throw IllegalArgumentException(ex)
27+
}
28+
return cal
1029
}

app/src/main/java/org/schabi/newpipe/util/Localization.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.schabi.newpipe.R;
2121
import org.schabi.newpipe.extractor.ListExtractor;
2222
import org.schabi.newpipe.extractor.localization.ContentCountry;
23+
import org.schabi.newpipe.ktx.OffsetDateTimeKt;
2324

2425
import java.math.BigDecimal;
2526
import java.math.RoundingMode;
@@ -30,7 +31,6 @@
3031
import java.time.format.FormatStyle;
3132
import java.util.Arrays;
3233
import java.util.Calendar;
33-
import java.util.GregorianCalendar;
3434
import java.util.List;
3535
import java.util.Locale;
3636

@@ -314,7 +314,7 @@ private static void initPrettyTime(final Context context) {
314314
}
315315

316316
public static String relativeTime(final OffsetDateTime offsetDateTime) {
317-
return relativeTime(GregorianCalendar.from(offsetDateTime.toZonedDateTime()));
317+
return relativeTime(OffsetDateTimeKt.toCalendar(offsetDateTime));
318318
}
319319

320320
public static String relativeTime(final Calendar calendarTime) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.schabi.newpipe.ktx
2+
3+
import org.junit.Assert.assertEquals
4+
import org.junit.Test
5+
import java.time.LocalDate
6+
import java.time.OffsetDateTime
7+
import java.time.ZoneId
8+
import java.time.ZoneOffset
9+
import java.util.Calendar
10+
import java.util.TimeZone
11+
12+
class OffsetDateTimeToCalendarTest {
13+
@Test
14+
fun testRelativeTimeWithCurrentOffsetDateTime() {
15+
val calendar = LocalDate.of(2020, 1, 1).atStartOfDay().atOffset(ZoneOffset.UTC)
16+
.toCalendar()
17+
18+
assertEquals(2020, calendar[Calendar.YEAR])
19+
assertEquals(0, calendar[Calendar.MONTH])
20+
assertEquals(1, calendar[Calendar.DAY_OF_MONTH])
21+
assertEquals(0, calendar[Calendar.HOUR])
22+
assertEquals(0, calendar[Calendar.MINUTE])
23+
assertEquals(0, calendar[Calendar.SECOND])
24+
assertEquals(TimeZone.getTimeZone("UTC"), calendar.timeZone)
25+
}
26+
27+
@Test(expected = IllegalArgumentException::class)
28+
fun testRelativeTimeWithFarOffOffsetDateTime() {
29+
OffsetDateTime.MAX.minusYears(1).toCalendar()
30+
}
31+
}

0 commit comments

Comments
 (0)