diff --git a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/adapters/OffsetDateTimeJsonAdapter.java b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/adapters/OffsetDateTimeJsonAdapter.java
index 831d460e4..f866bd8c2 100644
--- a/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/adapters/OffsetDateTimeJsonAdapter.java
+++ b/iso20022-core/src/main/java/com/prowidesoftware/swift/model/mx/adapters/OffsetDateTimeJsonAdapter.java
@@ -17,6 +17,7 @@
import com.google.gson.*;
import java.lang.reflect.Type;
+import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
@@ -26,6 +27,9 @@
/**
* This adapter enables accepting OffsetDateTime time Json format.
+ *
The adapter supports two DTO formats: the current one and the
+ * legacy one based on XMLGregorianCalendar model with Java 1.8.
+ *
*
* @since 10.0.1
*/
@@ -58,46 +62,101 @@ public JsonElement serialize(
public OffsetDateTime deserialize(
JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) {
try {
- // Parse DTO model
- DateTimeOffsetDTO dateTimeOffsetDTO = gson.fromJson(jsonElement, DateTimeOffsetDTO.class);
-
- // Prepare OffsetDateTime
- OffsetDateTime offsetDateTime;
- int nano = 0;
- if (dateTimeOffsetDTO.dateTime.time.nano != null) {
- nano = dateTimeOffsetDTO.dateTime.time.nano;
- }
-
- if (dateTimeOffsetDTO.offset != null) {
- ZoneOffset zoneoffset = ZoneOffset.ofTotalSeconds(dateTimeOffsetDTO.offset.totalSeconds);
- offsetDateTime = OffsetDateTime.of(
- dateTimeOffsetDTO.dateTime.date.year,
- dateTimeOffsetDTO.dateTime.date.month,
- dateTimeOffsetDTO.dateTime.date.day,
- dateTimeOffsetDTO.dateTime.time.hour,
- dateTimeOffsetDTO.dateTime.time.minute,
- dateTimeOffsetDTO.dateTime.time.second,
- nano,
- zoneoffset);
- } else {
- LocalDateTime localDateTime = LocalDateTime.of(
- dateTimeOffsetDTO.dateTime.date.year,
- dateTimeOffsetDTO.dateTime.date.month,
- dateTimeOffsetDTO.dateTime.date.day,
- dateTimeOffsetDTO.dateTime.time.hour,
- dateTimeOffsetDTO.dateTime.time.minute,
- dateTimeOffsetDTO.dateTime.time.second,
- nano);
-
- ZoneId zoneId = ZoneOffset.systemDefault();
- offsetDateTime = localDateTime.atZone(zoneId).toOffsetDateTime();
- }
-
- return offsetDateTime;
- } catch (Exception e) {
- log.log(Level.FINEST, "Cannot parse JSON into OffsetDateTime: " + e.getMessage(), e);
- return null;
+ // Parse DTO from current OffsetDateTime model
+ return deserializeFromOffsetDateTimeDTO(gson.fromJson(jsonElement, DateTimeOffsetDTO.class));
+ } catch (final Exception e) {
+ log.log(
+ Level.FINEST,
+ "Cannot parse JSON into OffsetDateTime from current DTO format: " + e.getMessage(),
+ e);
}
+ log.log(Level.FINEST, "Attempting parsing from legacy DTO format");
+ try {
+ // Parse DTO from legacy XMLGregorianCalendar model
+ return deserializeFromXMLGregorianCalendarDTO(gson.fromJson(jsonElement, XMLGregorianCalendarDTO.class));
+ } catch (final Exception e) {
+ log.log(Level.FINEST, "Cannot parse JSON into OffsetDateTime from legacy DTO format: " + e.getMessage(), e);
+ }
+ return null;
+ }
+
+ private OffsetDateTime deserializeFromOffsetDateTimeDTO(final DateTimeOffsetDTO dateTimeOffsetDTO) {
+ // Prepare OffsetDateTime
+ OffsetDateTime offsetDateTime;
+ int nano = 0;
+ if (dateTimeOffsetDTO.dateTime.time.nano != null) {
+ nano = dateTimeOffsetDTO.dateTime.time.nano;
+ }
+
+ if (dateTimeOffsetDTO.offset != null) {
+ ZoneOffset zoneoffset = ZoneOffset.ofTotalSeconds(dateTimeOffsetDTO.offset.totalSeconds);
+ offsetDateTime = OffsetDateTime.of(
+ dateTimeOffsetDTO.dateTime.date.year,
+ dateTimeOffsetDTO.dateTime.date.month,
+ dateTimeOffsetDTO.dateTime.date.day,
+ dateTimeOffsetDTO.dateTime.time.hour,
+ dateTimeOffsetDTO.dateTime.time.minute,
+ dateTimeOffsetDTO.dateTime.time.second,
+ nano,
+ zoneoffset);
+ } else {
+ LocalDateTime localDateTime = LocalDateTime.of(
+ dateTimeOffsetDTO.dateTime.date.year,
+ dateTimeOffsetDTO.dateTime.date.month,
+ dateTimeOffsetDTO.dateTime.date.day,
+ dateTimeOffsetDTO.dateTime.time.hour,
+ dateTimeOffsetDTO.dateTime.time.minute,
+ dateTimeOffsetDTO.dateTime.time.second,
+ nano);
+
+ ZoneId zoneId = ZoneOffset.systemDefault();
+ offsetDateTime = localDateTime.atZone(zoneId).toOffsetDateTime();
+ }
+
+ return offsetDateTime;
+ }
+
+ private OffsetDateTime deserializeFromXMLGregorianCalendarDTO(
+ final XMLGregorianCalendarDTO xmlGregorianCalendarDTO) {
+ if (Integer.MIN_VALUE == xmlGregorianCalendarDTO.year) {
+ xmlGregorianCalendarDTO.year = 0;
+ }
+ if (Integer.MIN_VALUE == xmlGregorianCalendarDTO.month) {
+ xmlGregorianCalendarDTO.month = 0;
+ }
+ if (Integer.MIN_VALUE == xmlGregorianCalendarDTO.day) {
+ xmlGregorianCalendarDTO.day = 0;
+ }
+ if (Integer.MIN_VALUE == xmlGregorianCalendarDTO.hour) {
+ xmlGregorianCalendarDTO.hour = 0;
+ }
+ if (Integer.MIN_VALUE == xmlGregorianCalendarDTO.minute) {
+ xmlGregorianCalendarDTO.minute = 0;
+ }
+ if (Integer.MIN_VALUE == xmlGregorianCalendarDTO.second) {
+ xmlGregorianCalendarDTO.second = 0;
+ }
+ if (Integer.MIN_VALUE == xmlGregorianCalendarDTO.timezone) {
+ xmlGregorianCalendarDTO.timezone = null;
+ }
+
+ return LocalDateTime.of(
+ xmlGregorianCalendarDTO.year,
+ xmlGregorianCalendarDTO.month,
+ xmlGregorianCalendarDTO.day,
+ xmlGregorianCalendarDTO.hour,
+ xmlGregorianCalendarDTO.minute,
+ xmlGregorianCalendarDTO.second,
+ xmlGregorianCalendarDTO
+ .fractionalSecond
+ .scaleByPowerOfTen(9)
+ .toBigInteger()
+ .intValueExact())
+ .atZone(
+ xmlGregorianCalendarDTO.timezone != null
+ ? ZoneOffset.ofHours(xmlGregorianCalendarDTO.timezone)
+ : ZoneOffset.systemDefault())
+ .toOffsetDateTime();
}
static class DateTimeOffsetDTO {
@@ -126,4 +185,15 @@ static class TimeDTO {
static class OffsetDTO {
Integer totalSeconds = 0;
}
+
+ static class XMLGregorianCalendarDTO {
+ Integer year;
+ Integer month;
+ Integer day;
+ Integer hour = 0;
+ Integer minute = 0;
+ Integer second = 0;
+ BigDecimal fractionalSecond = BigDecimal.ZERO;
+ Integer timezone;
+ }
}
diff --git a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/adapters/DateTimeJsonAdapterBackwardCompatibilityTest.java b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/adapters/DateTimeJsonAdapterBackwardCompatibilityTest.java
new file mode 100644
index 000000000..5051c809d
--- /dev/null
+++ b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/adapters/DateTimeJsonAdapterBackwardCompatibilityTest.java
@@ -0,0 +1,547 @@
+package com.prowidesoftware.swift.model.mx.adapters;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import com.prowidesoftware.swift.model.mx.AbstractMX;
+import com.prowidesoftware.swift.model.mx.MxSese02500109;
+import org.junit.jupiter.api.DisplayNameGeneration;
+import org.junit.jupiter.api.DisplayNameGenerator;
+import org.junit.jupiter.api.Test;
+
+@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
+class DateTimeJsonAdapterBackwardCompatibilityTest {
+ private static final String XML_MX = "\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " IJKLMNOPXXX\n"
+ + " \n"
+ + " ABCDEFGHXXX\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " ABCDEFGHXXX\n"
+ + " \n"
+ + " ABCDEFGHXXX\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " 1423905641002\n"
+ + " sese.025.001.09\n"
+ + " 2024-07-17T05:27:51Z\n"
+ + " COPY\n"
+ + " true\n"
+ + " 2024071700000208\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " FOO\n"
+ + " BAR\n"
+ + " TOTO\n"
+ + " RECE\n"
+ + " APMT\n"
+ + " TITI\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " EXCH\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " QRSTUVWYXXX\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " 2024-07-16\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " 2024-07-17\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " 2024-07-17T07:26:04.207459\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " NL0000009165\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " 0\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " NECISOGEFRPPAGN000L10\n"
+ + " \n"
+ + " \n"
+ + " CFREURSOGEFRPPTIT-DCA-SGSS\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " NETT\n"
+ + " \n"
+ + " PARQ\n"
+ + " \n"
+ + " DLVR\n"
+ + " T2S\n"
+ + " RT\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " ABCDEFGHXXX\n"
+ + " \n"
+ + " 2407162881091741\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " QRSTUVWYXXX\n"
+ + " \n"
+ + " \n"
+ + " MOTICCEGITRRXXX9100000\n"
+ + " \n"
+ + " 1VUVZK\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " HGFEDCBAXXX\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " SOGEFRPPAGN\n"
+ + " \n"
+ + " \n"
+ + " NECISOGEFRPPAGN000L10\n"
+ + " \n"
+ + " FOO\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " 1\n"
+ + " DBIT\n"
+ + " \n"
+ + " \n"
+ + " /Document/SctiesSttlmTxConf/TxIdDtls\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " 42\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + " ";
+
+ private static final String JSON_MX_V9 = "{\n" + " \"sctiesSttlmTxConf\": {\n"
+ + " \"txIdDtls\": {\n"
+ + " \"acctOwnrTxId\": \"FOO\",\n"
+ + " \"mktInfrstrctrTxId\": \"BAR\",\n"
+ + " \"prcrTxId\": \"TOTO\",\n"
+ + " \"sctiesMvmntTp\": \"RECE\",\n"
+ + " \"pmt\": \"APMT\",\n"
+ + " \"cmonId\": \"TITI\"\n"
+ + " },\n"
+ + " \"tradDtls\": {\n"
+ + " \"plcOfTrad\": {\n"
+ + " \"mktTpAndId\": {\n"
+ + " \"tp\": {\n"
+ + " \"cd\": \"EXCH\"\n"
+ + " }\n"
+ + " }\n"
+ + " },\n"
+ + " \"plcOfClr\": {\n"
+ + " \"id\": \"QRSTUVWYXXX\"\n"
+ + " },\n"
+ + " \"tradDt\": {\n"
+ + " \"dt\": {\n"
+ + " \"dt\": {\n"
+ + " \"year\": 2024,\n"
+ + " \"month\": 7,\n"
+ + " \"day\": 16,\n"
+ + " \"timezone\": -2147483648,\n"
+ + " \"hour\": -2147483648,\n"
+ + " \"minute\": -2147483648,\n"
+ + " \"second\": -2147483648\n"
+ + " }\n"
+ + " }\n"
+ + " },\n"
+ + " \"sttlmDt\": {\n"
+ + " \"dt\": {\n"
+ + " \"dt\": {\n"
+ + " \"year\": 2024,\n"
+ + " \"month\": 7,\n"
+ + " \"day\": 17,\n"
+ + " \"timezone\": -2147483648,\n"
+ + " \"hour\": -2147483648,\n"
+ + " \"minute\": -2147483648,\n"
+ + " \"second\": -2147483648\n"
+ + " }\n"
+ + " }\n"
+ + " },\n"
+ + " \"fctvSttlmDt\": {\n"
+ + " \"dt\": {\n"
+ + " \"dtTm\": {\n"
+ + " \"year\": 2024,\n"
+ + " \"month\": 7,\n"
+ + " \"day\": 17,\n"
+ + " \"timezone\": -2147483648,\n"
+ + " \"hour\": 7,\n"
+ + " \"minute\": 26,\n"
+ + " \"second\": 4,\n"
+ + " \"fractionalSecond\": 0.207459\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + " },\n"
+ + " \"finInstrmId\": {\n"
+ + " \"isin\": \"NL0000009165\"\n"
+ + " },\n"
+ + " \"qtyAndAcctDtls\": {\n"
+ + " \"sttldQty\": {\n"
+ + " \"qty\": {\n"
+ + " \"unit\": 0\n"
+ + " }\n"
+ + " },\n"
+ + " \"sfkpgAcct\": {\n"
+ + " \"id\": \"NECISOGEFRPPAGN000L10\"\n"
+ + " },\n"
+ + " \"cshAcct\": {\n"
+ + " \"prtry\": \"CFREURSOGEFRPPTIT-DCA-SGSS\"\n"
+ + " }\n"
+ + " },\n"
+ + " \"sttlmParams\": {\n"
+ + " \"sctiesTxTp\": {\n"
+ + " \"cd\": \"NETT\"\n"
+ + " },\n"
+ + " \"prtlSttlmInd\": \"PARQ\",\n"
+ + " \"cshSubBalTp\": {\n"
+ + " \"id\": \"DLVR\",\n"
+ + " \"issr\": \"T2S\",\n"
+ + " \"schmeNm\": \"RT\"\n"
+ + " }\n"
+ + " },\n"
+ + " \"dlvrgSttlmPties\": {\n"
+ + " \"dpstry\": {\n"
+ + " \"id\": {\n"
+ + " \"anyBIC\": \"ABCDEFGHXXX\"\n"
+ + " },\n"
+ + " \"prcgId\": \"2407162881091741\"\n"
+ + " },\n"
+ + " \"pty1\": {\n"
+ + " \"id\": {\n"
+ + " \"anyBIC\": \"QRSTUVWYXXX\"\n"
+ + " },\n"
+ + " \"sfkpgAcct\": {\n"
+ + " \"id\": \"MOTICCEGITRRXXX9100000\"\n"
+ + " },\n"
+ + " \"prcgId\": \"1VUVZK\"\n"
+ + " }\n"
+ + " },\n"
+ + " \"rcvgSttlmPties\": {\n"
+ + " \"dpstry\": {\n"
+ + " \"id\": {\n"
+ + " \"anyBIC\": \"HGFEDCBAXXX\"\n"
+ + " }\n"
+ + " },\n"
+ + " \"pty1\": {\n"
+ + " \"id\": {\n"
+ + " \"anyBIC\": \"SOGEFRPPAGN\"\n"
+ + " },\n"
+ + " \"sfkpgAcct\": {\n"
+ + " \"id\": \"NECISOGEFRPPAGN000L10\"\n"
+ + " },\n"
+ + " \"prcgId\": \"FOO\"\n"
+ + " }\n"
+ + " },\n"
+ + " \"sttldAmt\": {\n"
+ + " \"amt\": {\n"
+ + " \"value\": 1,\n"
+ + " \"ccy\": \"EUR\"\n"
+ + " },\n"
+ + " \"cdtDbtInd\": \"DBIT\"\n"
+ + " },\n"
+ + " \"splmtryData\": [\n"
+ + " {\n"
+ + " \"plcAndNm\": \"/Document/SctiesSttlmTxConf/TxIdDtls\",\n"
+ + " \"envlp\": {}\n"
+ + " }\n"
+ + " ]\n"
+ + " },\n"
+ + " \"appHdr\": {\n"
+ + " \"fr\": {\n"
+ + " \"fiId\": {\n"
+ + " \"finInstnId\": {\n"
+ + " \"bicfi\": \"IJKLMNOPXXX\",\n"
+ + " \"othr\": {\n"
+ + " \"id\": \"ABCDEFGHXXX\"\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + " },\n"
+ + " \"to\": {\n"
+ + " \"fiId\": {\n"
+ + " \"finInstnId\": {\n"
+ + " \"bicfi\": \"ABCDEFGHXXX\",\n"
+ + " \"othr\": {\n"
+ + " \"id\": \"ABCDEFGHXXX\"\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + " },\n"
+ + " \"bizMsgIdr\": \"1423905641002\",\n"
+ + " \"msgDefIdr\": \"sese.025.001.09\",\n"
+ + " \"creDt\": {\n"
+ + " \"year\": 2024,\n"
+ + " \"month\": 7,\n"
+ + " \"day\": 17,\n"
+ + " \"timezone\": 0,\n"
+ + " \"hour\": 5,\n"
+ + " \"minute\": 27,\n"
+ + " \"second\": 51\n"
+ + " },\n"
+ + " \"cpyDplct\": \"COPY\",\n"
+ + " \"pssblDplct\": true,\n"
+ + " \"prty\": \"2024071700000208\",\n"
+ + " \"namespace\": \"urn:iso:std:iso:20022:tech:xsd:head.001.001.01\"\n"
+ + " },\n"
+ + " \"type\": \"MX\",\n"
+ + " \"@xmlns\": \"urn:iso:std:iso:20022:tech:xsd:sese.025.001.09\",\n"
+ + " \"identifier\": \"sese.025.001.09\"\n"
+ + " }";
+
+ private static final String JSON_MX_V10 = "{\n" + " \"sctiesSttlmTxConf\": {\n"
+ + " \"txIdDtls\": {\n"
+ + " \"acctOwnrTxId\": \"FOO\",\n"
+ + " \"mktInfrstrctrTxId\": \"BAR\",\n"
+ + " \"prcrTxId\": \"TOTO\",\n"
+ + " \"sctiesMvmntTp\": \"RECE\",\n"
+ + " \"pmt\": \"APMT\",\n"
+ + " \"cmonId\": \"TITI\"\n"
+ + " },\n"
+ + " \"tradDtls\": {\n"
+ + " \"plcOfTrad\": {\n"
+ + " \"mktTpAndId\": {\n"
+ + " \"tp\": {\n"
+ + " \"cd\": \"EXCH\"\n"
+ + " }\n"
+ + " }\n"
+ + " },\n"
+ + " \"plcOfClr\": {\n"
+ + " \"id\": \"QRSTUVWYXXX\"\n"
+ + " },\n"
+ + " \"tradDt\": {\n"
+ + " \"dt\": {\n"
+ + " \"dt\": {\n"
+ + " \"year\": 2024,\n"
+ + " \"month\": 7,\n"
+ + " \"day\": 16\n"
+ + " }\n"
+ + " }\n"
+ + " },\n"
+ + " \"sttlmDt\": {\n"
+ + " \"dt\": {\n"
+ + " \"dt\": {\n"
+ + " \"year\": 2024,\n"
+ + " \"month\": 7,\n"
+ + " \"day\": 17\n"
+ + " }\n"
+ + " }\n"
+ + " },\n"
+ + " \"fctvSttlmDt\": {\n"
+ + " \"dt\": {\n"
+ + " \"dtTm\": {\n"
+ + " \"dateTime\": {\n"
+ + " \"date\": {\n"
+ + " \"year\": 2024,\n"
+ + " \"month\": 7,\n"
+ + " \"day\": 17\n"
+ + " },\n"
+ + " \"time\": {\n"
+ + " \"hour\": 7,\n"
+ + " \"minute\": 26,\n"
+ + " \"second\": 4,\n"
+ + " \"nano\": 207459000\n"
+ + " }\n"
+ + " },\n"
+ + " \"offset\": {\n"
+ + " \"totalSeconds\": 7200\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + " },\n"
+ + " \"finInstrmId\": {\n"
+ + " \"isin\": \"NL0000009165\"\n"
+ + " },\n"
+ + " \"qtyAndAcctDtls\": {\n"
+ + " \"sttldQty\": {\n"
+ + " \"qty\": {\n"
+ + " \"unit\": 0\n"
+ + " }\n"
+ + " },\n"
+ + " \"sfkpgAcct\": {\n"
+ + " \"id\": \"NECISOGEFRPPAGN000L10\"\n"
+ + " },\n"
+ + " \"cshAcct\": {\n"
+ + " \"prtry\": \"CFREURSOGEFRPPTIT-DCA-SGSS\"\n"
+ + " }\n"
+ + " },\n"
+ + " \"sttlmParams\": {\n"
+ + " \"sctiesTxTp\": {\n"
+ + " \"cd\": \"NETT\"\n"
+ + " },\n"
+ + " \"prtlSttlmInd\": \"PARQ\",\n"
+ + " \"cshSubBalTp\": {\n"
+ + " \"id\": \"DLVR\",\n"
+ + " \"issr\": \"T2S\",\n"
+ + " \"schmeNm\": \"RT\"\n"
+ + " }\n"
+ + " },\n"
+ + " \"dlvrgSttlmPties\": {\n"
+ + " \"dpstry\": {\n"
+ + " \"id\": {\n"
+ + " \"anyBIC\": \"ABCDEFGHXXX\"\n"
+ + " },\n"
+ + " \"prcgId\": \"2407162881091741\"\n"
+ + " },\n"
+ + " \"pty1\": {\n"
+ + " \"id\": {\n"
+ + " \"anyBIC\": \"QRSTUVWYXXX\"\n"
+ + " },\n"
+ + " \"sfkpgAcct\": {\n"
+ + " \"id\": \"MOTICCEGITRRXXX9100000\"\n"
+ + " },\n"
+ + " \"prcgId\": \"1VUVZK\"\n"
+ + " }\n"
+ + " },\n"
+ + " \"rcvgSttlmPties\": {\n"
+ + " \"dpstry\": {\n"
+ + " \"id\": {\n"
+ + " \"anyBIC\": \"HGFEDCBAXXX\"\n"
+ + " }\n"
+ + " },\n"
+ + " \"pty1\": {\n"
+ + " \"id\": {\n"
+ + " \"anyBIC\": \"SOGEFRPPAGN\"\n"
+ + " },\n"
+ + " \"sfkpgAcct\": {\n"
+ + " \"id\": \"NECISOGEFRPPAGN000L10\"\n"
+ + " },\n"
+ + " \"prcgId\": \"FOO\"\n"
+ + " }\n"
+ + " },\n"
+ + " \"sttldAmt\": {\n"
+ + " \"amt\": {\n"
+ + " \"value\": 1,\n"
+ + " \"ccy\": \"EUR\"\n"
+ + " },\n"
+ + " \"cdtDbtInd\": \"DBIT\"\n"
+ + " },\n"
+ + " \"splmtryData\": [\n"
+ + " {\n"
+ + " \"plcAndNm\": \"/Document/SctiesSttlmTxConf/TxIdDtls\",\n"
+ + " \"envlp\": {}\n"
+ + " }\n"
+ + " ]\n"
+ + " },\n"
+ + " \"appHdr\": {\n"
+ + " \"fr\": {\n"
+ + " \"fiId\": {\n"
+ + " \"finInstnId\": {\n"
+ + " \"bicfi\": \"IJKLMNOPXXX\",\n"
+ + " \"othr\": {\n"
+ + " \"id\": \"ABCDEFGHXXX\"\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + " },\n"
+ + " \"to\": {\n"
+ + " \"fiId\": {\n"
+ + " \"finInstnId\": {\n"
+ + " \"bicfi\": \"ABCDEFGHXXX\",\n"
+ + " \"othr\": {\n"
+ + " \"id\": \"ABCDEFGHXXX\"\n"
+ + " }\n"
+ + " }\n"
+ + " }\n"
+ + " },\n"
+ + " \"bizMsgIdr\": \"1423905641002\",\n"
+ + " \"msgDefIdr\": \"sese.025.001.09\",\n"
+ + " \"creDt\": {\n"
+ + " \"dateTime\": {\n"
+ + " \"date\": {\n"
+ + " \"year\": 2024,\n"
+ + " \"month\": 7,\n"
+ + " \"day\": 17\n"
+ + " },\n"
+ + " \"time\": {\n"
+ + " \"hour\": 5,\n"
+ + " \"minute\": 27,\n"
+ + " \"second\": 51,\n"
+ + " \"nano\": 0\n"
+ + " }\n"
+ + " },\n"
+ + " \"offset\": {\n"
+ + " \"totalSeconds\": 0\n"
+ + " }\n"
+ + " },\n"
+ + " \"cpyDplct\": \"COPY\",\n"
+ + " \"pssblDplct\": true,\n"
+ + " \"prty\": \"2024071700000208\",\n"
+ + " \"namespace\": \"urn:iso:std:iso:20022:tech:xsd:head.001.001.01\"\n"
+ + " },\n"
+ + " \"type\": \"MX\",\n"
+ + " \"@xmlns\": \"urn:iso:std:iso:20022:tech:xsd:sese.025.001.09\",\n"
+ + " \"identifier\": \"sese.025.001.09\"\n"
+ + " }";
+
+ @Test
+ void v10_should_be_able_to_parse_json_with_date_time_created_from_v9() {
+ final MxSese02500109 mx = (MxSese02500109) AbstractMX.fromJson(JSON_MX_V9);
+ assertThat(mx.getSctiesSttlmTxConf().getTradDtls().getTradDt().getDt().getDt())
+ .isNotNull(); // Success
+ assertThat(mx.getSctiesSttlmTxConf()
+ .getTradDtls()
+ .getFctvSttlmDt()
+ .getDt()
+ .getDtTm())
+ .isNotNull(); // Fail
+ }
+
+ @Test
+ void v10_should_be_able_to_parse_json_from_v9_and_read_same_content_than_json_from_v10_and_xml() {
+ final MxSese02500109 reference = (MxSese02500109) AbstractMX.parse(XML_MX);
+ final MxSese02500109 fromV9 = (MxSese02500109) AbstractMX.fromJson(JSON_MX_V9);
+ final String toV10 = reference.toJson();
+ final MxSese02500109 fromV10 = (MxSese02500109) AbstractMX.fromJson(JSON_MX_V10);
+
+ assertThat(fromV9).isEqualTo(reference);
+ assertThat(fromV10).isEqualTo(reference);
+ assertThat(fromV9).isEqualTo(fromV10);
+ assertThat(toV10).isEqualToIgnoringWhitespace(JSON_MX_V10);
+ assertThat(toV10).isNotEqualToIgnoringWhitespace(JSON_MX_V9);
+ }
+}
diff --git a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/adapters/OffsetTimeJsonAdapterTest.java b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/adapters/OffsetTimeJsonAdapterTest.java
index d92996d36..4c5b1fe02 100644
--- a/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/adapters/OffsetTimeJsonAdapterTest.java
+++ b/iso20022-core/src/test/java/com/prowidesoftware/swift/model/mx/adapters/OffsetTimeJsonAdapterTest.java
@@ -19,7 +19,9 @@
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
+import java.time.Instant;
import java.time.OffsetTime;
+import java.time.ZoneId;
import org.junit.jupiter.api.Test;
class OffsetTimeJsonAdapterTest {
@@ -28,7 +30,10 @@ class OffsetTimeJsonAdapterTest {
@Test
void testSerializationAndDeserialization() {
- int systemOffsetSeconds = OffsetTime.now().getOffset().getTotalSeconds();
+ int systemOffsetSeconds = ZoneId.systemDefault()
+ .getRules()
+ .getStandardOffset(Instant.now())
+ .getTotalSeconds();
// without offset, nano 0
String jsonActual = "{\"time\":{\"hour\":12,\"minute\":13,\"second\":14,\"nano\":0}}";