Skip to content

Commit f2e3133

Browse files
committed
fix leap year calculations
1 parent 5ab7433 commit f2e3133

File tree

5 files changed

+56
-41
lines changed

5 files changed

+56
-41
lines changed

src/main/kotlin/YearUtil.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ object YearUtil {
33
fun isLeapYear(year: Int): Boolean =
44
when {
55
year % 4 != 0 -> false
6-
year % 400 == 0 -> true
7-
year % 100 == 0 -> false
6+
year % 100 == 0 -> year % 400 == 0
87
else -> true
98
}
109
}

src/main/kotlin/localdate/LocalDateUtil.kt

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,13 @@ object LocalDateUtil {
1717
* @param day Day of the month with range 1-31.
1818
* @return LocalDate.
1919
*/
20-
fun new(
21-
year: Int,
22-
month: Int,
23-
day: Int,
24-
): LocalDate =
25-
LocalDate.of(
26-
year,
27-
Month.of(month),
28-
day
29-
)
20+
fun new(year: Int, month: Int, day: Int): LocalDate = LocalDate.of(year, Month.of(month), day)
3021

3122
/**
3223
* @param epochMilliseconds Epoch time, aka Unix time, are seconds elapsed since January 1st 1970 at 00:00:00 UTC.
3324
* @return LocalDate.
3425
*/
35-
fun new(epochMilliseconds: Long): LocalDate =
36-
LocalDate.ofEpochDay(epochMilliseconds / 1000 / 60 / 60 / 24)
26+
fun new(epochMilliseconds: Long): LocalDate = LocalDate.ofEpochDay(epochMilliseconds / 1000 / 60 / 60 / 24)
3727

3828
/**
3929
* @param date A wrapper of Epoch time in UTC.

src/main/kotlin/localdatetime/LocalDateTimeUtil.kt

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,7 @@ object LocalDateTimeUtil {
3030
minute: Int = 0,
3131
second: Int = 0,
3232
nano: Int = 0
33-
): LocalDateTime =
34-
LocalDateTime.of(
35-
year,
36-
Month.of(month),
37-
day,
38-
hourIn24,
39-
minute,
40-
second,
41-
nano
42-
)
33+
): LocalDateTime = LocalDateTime.of(year, Month.of(month), day, hourIn24, minute, second, nano)
4334

4435
/**
4536
* @param year Year, ie, 2020.
@@ -61,10 +52,7 @@ object LocalDateTimeUtil {
6152
second: Int = 0,
6253
nano: Int = 0,
6354
isAm: Boolean,
64-
): LocalDateTime =
65-
new(
66-
year, month, day, if (isAm) hour else hour + 12, minute, second, nano
67-
)
55+
): LocalDateTime = new(year, month, day, if (isAm) hour else hour + 12, minute, second, nano)
6856

6957
/**
7058
* @param epochMilliseconds Epoch time, aka Unix time, are seconds elapsed since January 1st 1970 at 00:00:00 UTC.

src/main/kotlin/zoneddatetime/ZonedDateTimeUtil.kt

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,7 @@ object ZonedDateTimeUtil {
3737
nano: Int = 0,
3838
useSystemTimeZone: Boolean = true
3939
): ZonedDateTime {
40-
val localDateTime = LocalDateTime.of(
41-
year,
42-
Month.of(month),
43-
day,
44-
hourIn24,
45-
minute,
46-
second,
47-
nano
48-
)
40+
val localDateTime = LocalDateTime.of(year, Month.of(month), day, hourIn24, minute, second, nano)
4941
return ZonedDateTime.of(localDateTime, if (useSystemTimeZone) ZoneId.systemDefault() else UTC)
5042
}
5143

@@ -71,10 +63,7 @@ object ZonedDateTimeUtil {
7163
nano: Int = 0,
7264
isAm: Boolean,
7365
useSystemTimeZone: Boolean = true
74-
): ZonedDateTime =
75-
new(
76-
year, month, day, if (isAm) hour else hour + 12, minute, second, nano, useSystemTimeZone
77-
)
66+
): ZonedDateTime = new(year, month, day, if (isAm) hour else hour + 12, minute, second, nano, useSystemTimeZone)
7867

7968
/**
8069
* @param epochMilliseconds Epoch time, aka Unix time, are seconds elapsed since January 1st 1970 at 00:00:00 UTC.

src/test/kotlin/YearUtilTest.kt

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import org.junit.jupiter.api.Assertions.assertTrue
2+
import org.junit.jupiter.api.Test
3+
4+
class YearUtilTest {
5+
6+
companion object {
7+
val LEAP_YEAR_LIST = arrayOf(1804, 1808, 1812, 1816, 1820, 1824, 1828, 1832, 1836, 1840, 1844, 1848, 1852,
8+
1856, 1860, 1864, 1868, 1872, 1876, 1880, 1884, 1888, 1892, 1896, 1904, 1908, 1912, 1916, 1920, 1924,
9+
1928, 1932, 1936, 1940, 1944, 1948, 1952, 1956, 1960, 1964, 1968, 1972, 1976, 1980, 1984, 1988, 1992,
10+
1996, 2000, 2004, 2008, 2012, 2016, 2020,2024, 2028, 2032, 2036, 2040, 2044, 2048, 2052, 2056, 2060,
11+
2064, 2068, 2072, 2076, 2080, 2084, 2088, 2092, 2096
12+
)
13+
}
14+
15+
@Test
16+
fun `given leap years, then should properly mark them as such`() {
17+
// given
18+
var areAllLeapYears = true
19+
20+
// when
21+
LEAP_YEAR_LIST.forEach { year ->
22+
areAllLeapYears = areAllLeapYears and YearUtil.isLeapYear(year)
23+
}
24+
25+
// then
26+
assertTrue(areAllLeapYears)
27+
}
28+
29+
@Test
30+
fun `given non-leap years, then should properly mark them as such`() {
31+
// given
32+
var areAllNonLeapYears = true
33+
34+
// when
35+
LEAP_YEAR_LIST.forEachIndexed { index, currentLeapYear ->
36+
if (index == LEAP_YEAR_LIST.size - 1) {
37+
return@forEachIndexed
38+
}
39+
val nextLeapYear = LEAP_YEAR_LIST[index + 1]
40+
for (nonLeapYear in (currentLeapYear + 1) until nextLeapYear) {
41+
areAllNonLeapYears = areAllNonLeapYears and !YearUtil.isLeapYear(nonLeapYear)
42+
}
43+
}
44+
45+
// then
46+
assertTrue(areAllNonLeapYears)
47+
}
48+
49+
}

0 commit comments

Comments
 (0)