diff --git a/build.gradle.kts b/build.gradle.kts index 58d435ab..26e44f5e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -80,6 +80,9 @@ dependencies { // Content validation implementation("org.apache.tika:tika-core:2.9.1") + + // Import: DateTime Parsing + implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.17.0") } group = "icu.samnya" diff --git a/src/main/java/ext/Ext.kt b/src/main/java/ext/Ext.kt index 03fa8ba0..db9ff96a 100644 --- a/src/main/java/ext/Ext.kt +++ b/src/main/java/ext/Ext.kt @@ -84,6 +84,7 @@ val ACCEPTABLE_FALSE = setOf("0", "false", "no", "off", "False", "None", "null") val ACCEPTABLE_TRUE = setOf("1", "true", "yes", "on", "True") @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "UNCHECKED_CAST") val jackson = ObjectMapper().apply { + findAndRegisterModules() registerModule(SimpleModule().addDeserializer(Boolean::class.java, object : JsonDeserializer() { override fun deserialize(parser: JsonParser, context: DeserializationContext) = when(parser.text) { in ACCEPTABLE_FALSE -> false @@ -98,6 +99,9 @@ val jackson = ObjectMapper().apply { else text.split(',').map { it.trim().toInt() } as List } catch (e: Exception) { 400 - "Invalid list value ${parser.text}: $e" } + }).addDeserializer(LocalDateTime::class.java, object : JsonDeserializer() { + override fun deserialize(parser: JsonParser, context: DeserializationContext) = + parser.text.asDateTime() ?: (400 - "Invalid date time value ${parser.text}") })) } @OptIn(ExperimentalSerializationApi::class) @@ -131,6 +135,11 @@ val DATE_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd") fun LocalDate.isoDate() = format(DATE_FORMAT) fun LocalDateTime.isoDateTime() = format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) +val ALT_DATETIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss") +fun Str.asDateTime() = try { LocalDateTime.parse(this, DateTimeFormatter.ISO_LOCAL_DATE_TIME) } +catch (e: Exception) { try { LocalDateTime.parse(this, ALT_DATETIME_FORMAT) } +catch (e: Exception) { null } } + // Encodings fun Long.toHex(len: Int = 16): Str = "0x${this.toString(len).padStart(len, '0').uppercase()}" fun Map.toUrl() = entries.joinToString("&") { (k, v) -> "$k=$v" }