mirror of
https://github.com/Myzel394/NumberHub.git
synced 2025-06-18 16:25:27 +02:00
Less sugar
This commit is contained in:
parent
32fafb9a66
commit
52d7db579c
@ -79,6 +79,7 @@ android {
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
@ -101,6 +102,7 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation(libs.androidx.core)
|
||||
coreLibraryDesugaring(libs.android.desugarJdkLibs)
|
||||
|
||||
implementation(libs.androidx.compose.material3)
|
||||
implementation(libs.androidx.lifecycle.runtime.compose)
|
||||
|
@ -21,7 +21,10 @@ package com.sadellie.unitto
|
||||
import com.android.build.api.dsl.CommonExtension
|
||||
import org.gradle.api.JavaVersion
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.VersionCatalogsExtension
|
||||
import org.gradle.api.plugins.ExtensionAware
|
||||
import org.gradle.kotlin.dsl.dependencies
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions
|
||||
|
||||
internal fun Project.configureKotlinAndroid(
|
||||
@ -47,6 +50,7 @@ internal fun Project.configureKotlinAndroid(
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
@ -75,6 +79,12 @@ internal fun Project.configureKotlinAndroid(
|
||||
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||
}
|
||||
}
|
||||
|
||||
val libs = extensions.getByType<VersionCatalogsExtension>().named("libs")
|
||||
|
||||
dependencies {
|
||||
add("coreLibraryDesugaring", libs.findLibrary("android.desugarJdkLibs").get())
|
||||
}
|
||||
}
|
||||
|
||||
fun CommonExtension<*, *, *, *>.kotlinOptions(block: KotlinJvmOptions.() -> Unit) {
|
||||
|
@ -24,3 +24,7 @@ plugins {
|
||||
android {
|
||||
namespace = "com.sadellie.unitto.data.epoch"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
testImplementation(libs.junit)
|
||||
}
|
||||
|
@ -18,60 +18,33 @@
|
||||
|
||||
package com.sadellie.unitto.data.epoch
|
||||
|
||||
import java.math.BigDecimal
|
||||
import java.util.*
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneOffset
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.format.DateTimeParseException
|
||||
|
||||
object EpochDateConverter {
|
||||
private val pattern by lazy {
|
||||
DateTimeFormatter.ofPattern("HHmmssddMMyyyy")
|
||||
}
|
||||
|
||||
fun convertDateToUnix(date: String): String {
|
||||
// Here we add some zeros, so that input is 14 symbols long
|
||||
val inputWithPadding = date.padEnd(14, '0')
|
||||
|
||||
// Now we break input that is 14 symbols into pieces
|
||||
val hour = inputWithPadding.substring(0, 2)
|
||||
val minute = inputWithPadding.substring(2, 4)
|
||||
val second = inputWithPadding.substring(4, 6)
|
||||
val day = inputWithPadding.substring(6, 8)
|
||||
val month = inputWithPadding.substring(8, 10)
|
||||
val year = inputWithPadding.substring(10, 14)
|
||||
|
||||
val cal = Calendar.getInstance()
|
||||
cal.set(
|
||||
year.toIntOrNull() ?: 1970,
|
||||
(month.toIntOrNull() ?: 1) - 1,
|
||||
day.toIntOrNull() ?: 0,
|
||||
hour.toIntOrNull() ?: 0,
|
||||
minute.toIntOrNull() ?: 0,
|
||||
second.toIntOrNull() ?: 0,
|
||||
)
|
||||
return (cal.timeInMillis / 1000).toString()
|
||||
return try {
|
||||
// Here we add some zeros, so that input is 14 symbols long
|
||||
LocalDateTime
|
||||
.parse(date.padEnd(14, '0'), pattern)
|
||||
.toEpochSecond(ZoneOffset.UTC)
|
||||
} catch (e: DateTimeParseException) {
|
||||
0
|
||||
}.toString()
|
||||
}
|
||||
|
||||
fun convertUnixToDate(unix: String): String {
|
||||
var date = ""
|
||||
val cal2 = Calendar.getInstance()
|
||||
cal2.clear()
|
||||
cal2.isLenient = true
|
||||
val unixLong = unix.toLong().takeIf { it <= 253402300559L }
|
||||
?: throw IllegalArgumentException("Max unix is 253402300559")
|
||||
|
||||
// This lets us bypass calendars limits (it uses Int, we want BigDecimal)
|
||||
try {
|
||||
val unixBg = BigDecimal(unix.ifEmpty { "0" })
|
||||
val division = unixBg.divideAndRemainder(BigDecimal(Int.MAX_VALUE))
|
||||
val intTimes = division.component1()
|
||||
val rem = division.component2()
|
||||
repeat(intTimes.intValueExact()) {
|
||||
cal2.add(Calendar.SECOND, Int.MAX_VALUE)
|
||||
}
|
||||
cal2.add(Calendar.SECOND, rem.intValueExact())
|
||||
} catch (e: NumberFormatException) {
|
||||
return ""
|
||||
}
|
||||
date += cal2.get(Calendar.HOUR_OF_DAY).toString().padStart(2, '0')
|
||||
date += cal2.get(Calendar.MINUTE).toString().padStart(2, '0')
|
||||
date += cal2.get(Calendar.SECOND).toString().padStart(2, '0')
|
||||
date += cal2.get(Calendar.DAY_OF_MONTH).toString().padStart(2, '0')
|
||||
date += (cal2.get(Calendar.MONTH) + 1).toString().padStart(2, '0')
|
||||
// Year is 4 symbols long
|
||||
date += cal2.get(Calendar.YEAR).toString().padStart(4, '0')
|
||||
return date
|
||||
return LocalDateTime
|
||||
.ofEpochSecond(unixLong, 0, ZoneOffset.UTC)
|
||||
.format(pattern)
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Unitto is a unit converter for Android
|
||||
* Copyright (c) 2023 Elshan Agaev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sadellie.unitto.data.epoch
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class DateToEpochTest {
|
||||
|
||||
@Test
|
||||
fun `00h0m00s 00 00 0000`() {
|
||||
convertDateToUnixTest("00:00:00 00.00.0000", "0")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `00h00m00s 01 01 0001`() {
|
||||
convertDateToUnixTest("00:00:00 01.01.0001", "-62135596800")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `00h00m00s 01 01 1970`() {
|
||||
convertDateToUnixTest("00:00:00 01.01.1970", "0")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `23h55m59s 31 12 9999`() {
|
||||
convertDateToUnixTest("23:55:59 31.12.9999", "253402300559")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `99h99m99s 99 99 9999`() {
|
||||
convertDateToUnixTest("99:99:99 99.99.9999", "0")
|
||||
}
|
||||
|
||||
private fun convertDateToUnixTest(inputDate: String, expectedUnix: String) {
|
||||
// Date input comes "fancy"
|
||||
val cleanInputDate = inputDate.filter{ it.isDigit() }
|
||||
assertEquals(
|
||||
"Couldn't convert $inputDate ($cleanInputDate) into unix",
|
||||
expectedUnix,
|
||||
EpochDateConverter.convertDateToUnix(cleanInputDate)
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Unitto is a unit converter for Android
|
||||
* Copyright (c) 2023 Elshan Agaev
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sadellie.unitto.data.epoch
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertThrows
|
||||
import org.junit.Test
|
||||
|
||||
class EpochToDateTest {
|
||||
|
||||
@Test
|
||||
fun `0`() {
|
||||
convertUnixToDate("0", "00:00:00 01.01.1970")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `00000000000000 max input length`() {
|
||||
convertUnixToDate("00000000000000", "00:00:00 01.01.1970")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `253402300559 max possible date`() {
|
||||
convertUnixToDate("253402300559", "23:55:59 31.12.9999")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `2534023005599999 input longe than allowed`() {
|
||||
convertUnixToDate("2534023005599999", "23:55:59 31.12.9999", IllegalArgumentException())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `99999999999999 max possible unix with max length`() {
|
||||
convertUnixToDate("99999999999999", "23:55:59 31.12.9999", IllegalArgumentException())
|
||||
}
|
||||
|
||||
private fun convertUnixToDate(inputUnix: String, expectedDate: String, throwable: Throwable? = null) {
|
||||
// Date input comes "fancy"
|
||||
val cleanExpectedDate = expectedDate.filter{ it.isDigit() }
|
||||
|
||||
// Will throw
|
||||
if (throwable != null) {
|
||||
assertThrows(
|
||||
"Failed to throw ${throwable.javaClass} when converting $inputUnix into $expectedDate ($cleanExpectedDate)",
|
||||
throwable.javaClass
|
||||
) { EpochDateConverter.convertUnixToDate(inputUnix) }
|
||||
return
|
||||
}
|
||||
|
||||
// Should actually convert
|
||||
assertEquals(
|
||||
"Couldn't convert $inputUnix into $expectedDate ($cleanExpectedDate)",
|
||||
cleanExpectedDate,
|
||||
EpochDateConverter.convertUnixToDate(inputUnix)
|
||||
)
|
||||
}
|
||||
}
|
@ -52,9 +52,15 @@ class EpochViewModel @Inject constructor() : ViewModel() {
|
||||
dateToUnix = fromDateToUnix
|
||||
)
|
||||
} else {
|
||||
val date = try {
|
||||
EpochDateConverter.convertUnixToDate(input)
|
||||
} catch (e: IllegalArgumentException) {
|
||||
""
|
||||
}
|
||||
|
||||
EpochUIState(
|
||||
unixField = input,
|
||||
dateField = EpochDateConverter.convertUnixToDate(input),
|
||||
dateField = date,
|
||||
dateToUnix = fromDateToUnix
|
||||
)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ appName = "Glaucous"
|
||||
androidxCore = "1.9.0"
|
||||
androidxTest = "1.5.0"
|
||||
androidxTestExt = "1.1.4"
|
||||
androidDesugarJdkLibs = "2.0.0"
|
||||
junit = "4.13.2"
|
||||
androidxTestRunner = "1.5.1"
|
||||
androidxTestRules = "1.5.0"
|
||||
@ -61,6 +62,7 @@ com-squareup-retrofit2 = { group = "com.squareup.retrofit2", name = "converter-m
|
||||
com-github-sadellie-themmo = { group = "com.github.sadellie", name = "themmo", version.ref = "comGithubSadellieThemmo" }
|
||||
org-burnoutcrew-composereorderable = { group = "org.burnoutcrew.composereorderable", name = "reorderable", version.ref = "orgBurnoutcrewComposereorderable" }
|
||||
com-github-sadellie-exprk = { group = "com.github.sadellie", name = "ExprK", version.ref = "comGithubSadellieExprk" }
|
||||
android-desugarJdkLibs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" }
|
||||
|
||||
# classpath
|
||||
android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" }
|
||||
|
Loading…
x
Reference in New Issue
Block a user