es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Convertir una fecha desde XMLGregorianCalendar con ZoneId.systemDefault() a un timestamp con UTC.

Tengo un archivo xml con la etiqueta <Birthday>1994-11-30</Birthday> que necesito convertir a formato json con la fecha de timestamp en utc. Mi código es el siguiente:

kotlin
fun convertXmlToJson(profile: NotifyGetDocsRqType): JsonNode? {
return objectMapper.valueToTree(profile.data)
}

El campo Birthday se encuentra en la clase NotifyGetDocsRqType:

java
@XmlElement(name = "Birthday")
protected XMLGregorianCalendar birthday;

Como resultado, obtengo un json con la fecha Birthday = 786142800000, lo que corresponde al 29 de noviembre de 1994, 21:00:00 en utc (verificado en https://www.epochconverter.com).

La configuración para el objectMapper es la siguiente:

kotlin
@Bean
fun objectMapper() = ObjectMapper()
.apply {
disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)
enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)
enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS)
registerKotlinModule()
setTimeZone(TimeZone.getTimeZone("UTC"))
registerModule(JavaTimeModule())
registerModule(Jdk8Module())
setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE)
}

¿Por qué mi código no está funcionando, a pesar de haber especificado la zona horaria UTC para el objectMapper?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El código no funciona porque el valor XMLGregorianCalendar se convierte en una marca de tiempo utilizando la zona horaria predeterminada del sistema, no UTC. Para solucionar esto, es necesario convertir el XMLGregorianCalendar a un ZonedDateTime con la zona horaria UTC, y luego extraer la marca de tiempo de ese objeto. Aquí hay una versión actualizada del código:

    import java.time.ZoneOffset
    import java.time.ZonedDateTime
    
    fun convertXmlToJson(profile: NotifyGetDocsRqType): JsonNode? {
        val birthday = profile.birthday
        val utcBirthday = ZonedDateTime.ofInstant(birthday.toInstant(), ZoneOffset.UTC)
        val birthdayTimestamp = utcBirthday.toInstant().toEpochMilli()
        return objectMapper.valueToTree(profile.data).apply {
            put("Birthday", birthdayTimestamp)
        }
    }
    

    Este código primero toma el valor XMLGregorianCalendar y lo convierte en un Instant utilizando el método toInstant(). A continuación, crea un objeto ZonedDateTime con la zona horaria UTC utilizando el método ofInstant(). Finalmente, extrae la marca de tiempo del objeto ZonedDateTime con el método toEpochMilli().

    La función actualizada luego agrega la propiedad Birthday con la marca de tiempo calculada al objeto JSON.

    Con este cambio, el código debería convertir correctamente el valor XML en una marca de tiempo con la zona horaria UTC en el JSON resultante.

Comments are closed.