|
17 | 17 | package okio.internal |
18 | 18 |
|
19 | 19 | internal actual val DEFAULT_COMPRESSION: Int = platform.zlib.Z_DEFAULT_COMPRESSION |
| 20 | + |
| 21 | +/** |
| 22 | + * Roll our own date math because Kotlin doesn't include a built-in date math API, and the |
| 23 | + * kotlinx.datetime library doesn't offer a stable at this time. |
| 24 | + * |
| 25 | + * Also, we don't necessarily want to take on that dependency for Okio. |
| 26 | + * |
| 27 | + * This implementation assumes UTC. |
| 28 | + * |
| 29 | + * This code is broken for years before 1970. It doesn't implement subtraction for leap years. |
| 30 | + * |
| 31 | + * This code is broken for out-of-range values. For example, it doesn't correctly implement leap |
| 32 | + * year offsets when the month is -24 or when the day is -365. |
| 33 | + */ |
| 34 | +internal actual fun datePartsToEpochMillis( |
| 35 | + year: Int, |
| 36 | + month: Int, |
| 37 | + day: Int, |
| 38 | + hour: Int, |
| 39 | + minute: Int, |
| 40 | + second: Int, |
| 41 | +): Long { |
| 42 | + // Make sure month is in 1..12, adding or subtracting years as necessary. |
| 43 | + val rawMonth = month |
| 44 | + val month = (month - 1).mod(12) + 1 |
| 45 | + val year = year + (rawMonth - month) / 12 |
| 46 | + |
| 47 | + // Start with the cumulative number of days elapsed preceding the current year. |
| 48 | + var dayCount = (year - 1970) * 365L |
| 49 | + |
| 50 | + // Adjust by leap years. Years that divide 4 are leap years, unless they divide 100 but not 400. |
| 51 | + val leapYear = if (month > 2) year else year - 1 |
| 52 | + dayCount += (leapYear - 1968) / 4 - (leapYear - 1900) / 100 + (leapYear - 1600) / 400 |
| 53 | + |
| 54 | + // Add the cumulative number of days elapsed preceding the current month. |
| 55 | + dayCount += when (month) { |
| 56 | + 1 -> 0 |
| 57 | + 2 -> 31 |
| 58 | + 3 -> 59 |
| 59 | + 4 -> 90 |
| 60 | + 5 -> 120 |
| 61 | + 6 -> 151 |
| 62 | + 7 -> 181 |
| 63 | + 8 -> 212 |
| 64 | + 9 -> 243 |
| 65 | + 10 -> 273 |
| 66 | + 11 -> 304 |
| 67 | + else -> 334 |
| 68 | + } |
| 69 | + |
| 70 | + // Add the cumulative number of days that precede the current day. |
| 71 | + dayCount += (day - 1) |
| 72 | + |
| 73 | + // Add hours + minutes + seconds for the current day. |
| 74 | + val hourCount = dayCount * 24 + hour |
| 75 | + val minuteCount = hourCount * 60 + minute |
| 76 | + val secondCount = minuteCount * 60 + second |
| 77 | + return secondCount * 1_000L |
| 78 | +} |
0 commit comments