diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 88948f352..22aaf885b 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.400.0"
+ ".": "0.400.1"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8585e5ea2..fa3308d3a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
# Changelog
+## 0.400.1 (2026-01-23)
+
+Full Changelog: [v0.400.0...v0.400.1](https://github.com/Increase/increase-java/compare/v0.400.0...v0.400.1)
+
+### Bug Fixes
+
+* **client:** preserve time zone in lenient date-time parsing ([1e9fb40](https://github.com/Increase/increase-java/commit/1e9fb40a88e426e18a48f7f2566743fbe9d19963))
+
+
+### Chores
+
+* **internal:** correct cache invalidation for `SKIP_MOCK_TESTS` ([e63a9f9](https://github.com/Increase/increase-java/commit/e63a9f93f7d87ffc7c80fa005ee58e9ac689c1de))
+
## 0.400.0 (2026-01-22)
Full Changelog: [v0.399.0...v0.400.0](https://github.com/Increase/increase-java/compare/v0.399.0...v0.400.0)
diff --git a/README.md b/README.md
index 9bdc5147f..ed747656b 100644
--- a/README.md
+++ b/README.md
@@ -2,8 +2,8 @@
-[](https://central.sonatype.com/artifact/com.increase.api/increase-java/0.400.0)
-[](https://javadoc.io/doc/com.increase.api/increase-java/0.400.0)
+[](https://central.sonatype.com/artifact/com.increase.api/increase-java/0.400.1)
+[](https://javadoc.io/doc/com.increase.api/increase-java/0.400.1)
@@ -13,7 +13,7 @@ The Increase Java SDK is similar to the Increase Kotlin SDK but with minor diffe
-The REST API documentation can be found on [increase.com](https://increase.com/documentation). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.increase.api/increase-java/0.400.0).
+The REST API documentation can be found on [increase.com](https://increase.com/documentation). Javadocs are available on [javadoc.io](https://javadoc.io/doc/com.increase.api/increase-java/0.400.1).
@@ -24,7 +24,7 @@ The REST API documentation can be found on [increase.com](https://increase.com/d
### Gradle
```kotlin
-implementation("com.increase.api:increase-java:0.400.0")
+implementation("com.increase.api:increase-java:0.400.1")
```
### Maven
@@ -33,7 +33,7 @@ implementation("com.increase.api:increase-java:0.400.0")
com.increase.api
increase-java
- 0.400.0
+ 0.400.1
```
diff --git a/build.gradle.kts b/build.gradle.kts
index 8804c03c1..62a356b27 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -8,7 +8,7 @@ repositories {
allprojects {
group = "com.increase.api"
- version = "0.400.0" // x-release-please-version
+ version = "0.400.1" // x-release-please-version
}
subprojects {
diff --git a/buildSrc/src/main/kotlin/increase.kotlin.gradle.kts b/buildSrc/src/main/kotlin/increase.kotlin.gradle.kts
index f55a8f384..77289c4fb 100644
--- a/buildSrc/src/main/kotlin/increase.kotlin.gradle.kts
+++ b/buildSrc/src/main/kotlin/increase.kotlin.gradle.kts
@@ -33,6 +33,9 @@ kotlin {
tasks.withType().configureEach {
systemProperty("junit.jupiter.execution.parallel.enabled", true)
systemProperty("junit.jupiter.execution.parallel.mode.default", "concurrent")
+
+ // `SKIP_MOCK_TESTS` affects which tests run so it must be added as input for proper cache invalidation.
+ inputs.property("skipMockTests", System.getenv("SKIP_MOCK_TESTS")).optional(true)
}
val ktfmt by configurations.creating
diff --git a/increase-java-core/src/main/kotlin/com/increase/api/core/ObjectMappers.kt b/increase-java-core/src/main/kotlin/com/increase/api/core/ObjectMappers.kt
index eea369d39..87ef16436 100644
--- a/increase-java-core/src/main/kotlin/com/increase/api/core/ObjectMappers.kt
+++ b/increase-java-core/src/main/kotlin/com/increase/api/core/ObjectMappers.kt
@@ -25,7 +25,7 @@ import java.time.DateTimeException
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.OffsetDateTime
-import java.time.ZonedDateTime
+import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.time.temporal.ChronoField
@@ -157,14 +157,15 @@ private class LenientOffsetDateTimeDeserializer :
val temporal = formatter.parse(p.text)
return when {
- !temporal.isSupported(ChronoField.HOUR_OF_DAY) ->
- LocalDate.from(temporal).atStartOfDay()
- !temporal.isSupported(ChronoField.OFFSET_SECONDS) ->
- LocalDateTime.from(temporal)
- else -> ZonedDateTime.from(temporal).toLocalDateTime()
- }
- .atZone(context.timeZone.toZoneId())
- .toOffsetDateTime()
+ !temporal.isSupported(ChronoField.HOUR_OF_DAY) ->
+ LocalDate.from(temporal)
+ .atStartOfDay()
+ .atZone(ZoneId.of("UTC"))
+ .toOffsetDateTime()
+ !temporal.isSupported(ChronoField.OFFSET_SECONDS) ->
+ LocalDateTime.from(temporal).atZone(ZoneId.of("UTC")).toOffsetDateTime()
+ else -> OffsetDateTime.from(temporal)
+ }
} catch (e: DateTimeException) {
exceptions.add(e)
}
diff --git a/increase-java-core/src/test/kotlin/com/increase/api/core/ObjectMappersTest.kt b/increase-java-core/src/test/kotlin/com/increase/api/core/ObjectMappersTest.kt
index 2347f36b4..5c51922ce 100644
--- a/increase-java-core/src/test/kotlin/com/increase/api/core/ObjectMappersTest.kt
+++ b/increase-java-core/src/test/kotlin/com/increase/api/core/ObjectMappersTest.kt
@@ -3,12 +3,14 @@ package com.increase.api.core
import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.databind.exc.MismatchedInputException
import com.fasterxml.jackson.module.kotlin.readValue
+import java.time.LocalDate
+import java.time.LocalTime
import java.time.OffsetDateTime
+import java.time.ZoneOffset
import kotlin.reflect.KClass
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.catchThrowable
import org.junit.jupiter.api.Test
-import org.junit.jupiter.api.assertDoesNotThrow
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.EnumSource
import org.junitpioneer.jupiter.cartesian.CartesianTest
@@ -72,11 +74,34 @@ internal class ObjectMappersTest {
}
}
- enum class LenientOffsetDateTimeTestCase(val string: String) {
- DATE("1998-04-21"),
- DATE_TIME("1998-04-21T04:00:00"),
- ZONED_DATE_TIME_1("1998-04-21T04:00:00+03:00"),
- ZONED_DATE_TIME_2("1998-04-21T04:00:00Z"),
+ enum class LenientOffsetDateTimeTestCase(
+ val string: String,
+ val expectedOffsetDateTime: OffsetDateTime,
+ ) {
+ DATE(
+ "1998-04-21",
+ expectedOffsetDateTime =
+ OffsetDateTime.of(LocalDate.of(1998, 4, 21), LocalTime.of(0, 0), ZoneOffset.UTC),
+ ),
+ DATE_TIME(
+ "1998-04-21T04:00:00",
+ expectedOffsetDateTime =
+ OffsetDateTime.of(LocalDate.of(1998, 4, 21), LocalTime.of(4, 0), ZoneOffset.UTC),
+ ),
+ ZONED_DATE_TIME_1(
+ "1998-04-21T04:00:00+03:00",
+ expectedOffsetDateTime =
+ OffsetDateTime.of(
+ LocalDate.of(1998, 4, 21),
+ LocalTime.of(4, 0),
+ ZoneOffset.ofHours(3),
+ ),
+ ),
+ ZONED_DATE_TIME_2(
+ "1998-04-21T04:00:00Z",
+ expectedOffsetDateTime =
+ OffsetDateTime.of(LocalDate.of(1998, 4, 21), LocalTime.of(4, 0), ZoneOffset.UTC),
+ ),
}
@ParameterizedTest
@@ -85,6 +110,8 @@ internal class ObjectMappersTest {
val jsonMapper = jsonMapper()
val json = jsonMapper.writeValueAsString(testCase.string)
- assertDoesNotThrow { jsonMapper().readValue(json) }
+ val offsetDateTime = jsonMapper().readValue(json)
+
+ assertThat(offsetDateTime).isEqualTo(testCase.expectedOffsetDateTime)
}
}