Icônes SCW
héros bg sans séparateur
Blog

Migración de Joda-Time a java.time

Cameron Gregor
Publié le 12 novembre 2021
Dernière mise à jour le 6 mars 2026

Migrar código (léase: código heredado) no es divertido. Se necesita una enorme cantidad de planificación y esfuerzo para lograrlo. Si bien no es el trabajo más emocionante o motivador para los desarrolladores, sí que requiere determinación y la experiencia adecuada para migrar el código heredado a las nuevas versiones de la biblioteca. Hora de Joda a java.time es una de esas migraciones que requiere una planificación y ejecución meticulosas.

Si su proyecto Java comenzó su vida antes de Java SE 8 y utiliza el procesamiento de fecha y hora, es probable que haya utilizado Joda-Time, una biblioteca excelente y un estándar de facto para gestionar las funciones de fecha y hora anteriores a SE 8. Si tu proyecto Aún así usa Joda-Time pero le gustaría migrar a java.time y luego siga leyendo.

La versión de Java SE 8 incluía una API de fecha y hora estándar nueva y mejorada, comúnmente denominada java.time (JSR-310). El proyecto Joda-Time ahora recomienda migrar a java.time (JSR-310).

Si bien java.time (JSR-310) se inspiró en gran medida en Joda-Time, no es compatible con versiones anteriores y los conceptos y terminologías han cambiado. Por eso, migrar de Joda-Time a java.time requiere prestar mucha atención a todas y cada una de las líneas de código que cambias. Esto puede llevar mucho tiempo y casi haría que deseara que hubiera una forma más fácil y automatizada de migrar.

Hay una forma mejor de migrar y la hemos creado con Sensei, un complemento de IntelliJ que realiza automáticamente transformaciones de código según las recetas (reglas) definidas por usted. Dedica tu tiempo a definir recetas reutilizables, en lugar de a realizar tareas de migración repetitivas. La automatización no solo transformará tu código heredado de Joda-Time, sino que también ayudará a los equipos a seguir las directrices que aparecen en el IDE a medida que escriben código nuevo.

Para ayudarlo a comenzar con ventaja, hemos creado un libro de cocina público sobre Sensei Estandarización en java.time (JSR-310) que incluye recetas para migrar de Joda-Time a java.time de una manera menos dolorosa. Se trata de un conjunto de recetas cada vez mayor que seguiremos ampliando para añadir más cobertura con más recetas.

Este es un ejemplo de un ejemplo de migración que puede ayudarle a ver cómo Sensei facilita la migración del código heredado.

Vidéo de la définition de l'heure de la date java.time zoned

Desde la migración manual repetitiva hasta las transformaciones de código automatizadas

Veamos un ejemplo de creación de un nuevo DateTime que muestra algunas trampas ocultas al migrar una sola línea de código de Joda-Time a java.time. A continuación, analizaremos una de las recetas de Sensei de nuestro libro de recetas sobre la estandarización de java.time (JSR-310) y mostraremos cómo captura toda esta información para que cualquier desarrollador pueda volver a utilizar esta misma migración una y otra vez.

En este ejemplo, estamos construyendo un Joda-Time DateTime a partir de 7 argumentos int que representan los valores de los campos DateTime.

¿Cómo migramos esto a un equivalente de java.time?

El javadoc en Joda-Time para este constructor dice:

Construye una instancia a partir de los valores de los campos de fecha y hora utilizando IsoChronology en la zona horaria predeterminada.

Al principio, podemos suponer que hay Fecha/hora clase en java.time, pero no hay ninguna. Si buscas en Google «migrar de la hora de Joda a la hora de Java», lo más probable es que encuentres la entrada del blog de Stephen Colebourne Conversión de Joda-Time a java.time.

Esto le da un buen comienzo y nos indica cómo usar java.time.zonedDateTime o java.time.offsetDateTime. Esta es nuestra primera pregunta, ¿cuál uso? Probablemente ZonedDateTime se basa en los comentarios de Stephen.

Buscando el ZonedDateTime javadoc, no podemos ver ningún constructor en absoluto. Volviendo a la entrada del blog de Stephen, leemos más abajo:

Construcción. Joda-Time tiene un constructor que acepta un objeto y realiza la conversión de tipos. java.time solo tiene métodos de fábrica, por lo que la conversión es un problema del usuario, aunque se proporciona un método parse () para las cadenas.

Por lo tanto, debe haber un método de fábrica estático, al buscar los métodos estáticos encontramos uno que se parece bastante, pero no es exactamente el mismo.

Tiene 7 parámetros int como nuestro constructor Joda-Time DateTime original, sin embargo, si no prestas atención, te perderás un detalle importante. El séptimo parámetro ya no representa milisegundos, sino nanosegundos, ya que java.time tiene una precisión mayor que Joda-Time y mide los instantes hasta el nano-segundo. Un detalle importante que podrías haber pasado por alto fácilmente. Además, este método espera un ZoneID, por lo que hace que te preguntes por qué no necesitabas uno antes y por qué lo necesitas ahora.

Recordando el javadoc de nuestro constructor original que mencionaba que usaría la zona horaria predeterminada, ¿tal vez haya una forma de obtener el ZoneID predeterminado?

El javadoc para ZoneID no nos informa sobre ningún constructor de la lista, pero al observar los métodos estáticos vemos que podemos usar Predeterminado del sistema ()

Ahora que hemos resuelto el ZoneID, ¿qué debemos hacer con nuestra conversión de milisegundos a nanosegundos? Tal vez podamos usar java.util.Concurrent.TimeUnit para realizar la conversión.

Este método devuelve un valor long y nuestro método espera un int, por lo que ahora también tenemos que resolver un problema de conversión. Tal vez podríamos probar algo simple. ¿Una multiplicación?

Esto funcionará, pero parece un poco fuera de lugar. Si aún no lo has notado, hemos dedicado una cantidad considerable de tiempo y esfuerzo a migrar una sola línea de código. Pero como puedes imaginar, tenemos muchas ediciones de este tipo que hacer a mano y no hay nada mejor.

Sin embargo, si analizamos un poco más la API java.time, podemos descubrir una solución que parece un poco más fluida.

Aunque ZonedDateTime no tiene una forma obvia de configurar los milisegundos, se puede hacer usando el con el método (campo temporalField, newValue largo), utilizando Cronofield. Mili_de_segundo como TemporalField.

Y el documento de Java menciona que realizará la conversión a nanosegundos por nosotros:

Cuando este campo se usa para establecer un valor, debe comportarse de la misma manera que si se establece NANO_OF_SECOND con el valor multiplicado por 1 000 000.

Así que podemos simplemente especificar 0 para nuestros nanosegundos en el método de fábrica y, a continuación, usar el con método para crear un ZonedDateTime que tenga todos los valores originales, así como los milisegundos.

Al observar nuestro resultado final, parece que solo hemos cambiado una línea de código, ¡realmente no muestra el esfuerzo que se dedicó a investigar solo una migración!

Cree una receta para migrar de forma más rápida y sencilla

Sensei nos proporciona una forma de compartir esta información ganada con tanto esfuerzo con otros desarrolladores. Al crear una receta que recoja todos estos requisitos, permitirá a los usuarios de Sensei realizar esta migración con solo un clic del ratón.

Una receta de Sensei consta de 3 secciones principales:

  • Metadatos
  • Búsqueda
  • Correcciones disponibles

Veamos una receta de Sensei (también se puede ver como una receta de YAML) que nos ayudará a migrar esta llamada a su equivalente en java.time.

DateTime foo = nueva fecha y hora (año, mes del año, día del mes, hora del día, minuto de hora, segundo de minuto, milisegundo de segundo);

Sección de metadatos

La sección de metadatos contiene información sobre la receta y cómo debe usarse.

Sección de búsqueda

La sección de búsqueda de una receta de Sensei especifica a qué elementos de código se debe aplicar esta receta.

buscar:
Creación de instancias:
argumentos:
1:
tipo: int
2:
tipo: int
3:
tipo: int
4:
tipo: int
5:
tipo: int
6:
tipo: int
7:
tipo: int
Recuento de arg: 7
tipo: org.joda.time.DateTime

En esta sección de búsqueda vemos que estamos:

  • En busca de un Creación de instancias, es decir, el uso de un Constructor. Nota: hay muchos otros objetivos de búsqueda disponibles
  • El constructor debe tener 7 argumentos, esto se especifica en Recuento de arg propiedad
  • argumentos 1-7 debe ser de tipo int
  • Estamos buscando a los constructores del tipo org.joda.time.dateTime

Sección de correcciones disponibles

La sección AvailableFixes puede especificar una o más correcciones que se pueden aplicar al elemento de código coincidente. Cada corrección puede tener varias acciones y, en nuestro caso, tenemos una única solución que realiza 2 acciones.

  • El nombre de la solución se muestra al usuario en el menú «Correcciones rápidas» y describe lo que ocurrirá si el usuario aplica esta solución rápida
  • La lista de acciones muestra las acciones que realizará esta solución rápida.
  • El volver a escribir la acción reescribirá el elemento de código utilizando una plantilla de bigote. Puede hacer uso de variables y funciones de reemplazo de cadenas.
  • El Modificar variable asignada action comprobará si este constructor se utiliza para asignar el valor a una variable. Si es así, esta acción modificará la variable para declararla como el tipo especificado por tipo

Uso de la receta para realizar la transformación del código

Con nuestra receta escrita y habilitada, escanea nuestro código y resalta los segmentos a los que se puede aplicar.

En la siguiente captura de pantalla podemos ver que el constructor objetivo ha sido marcado por Sensei. Al pasar el ratón sobre el constructor marcado, aparecen la opción Recipe ShortDescription y Quickfix Migrar a java.time.ZonedDateTime

Migrer la nouvelle date et l'heure

Después de seleccionar el Migrar a java.time.ZonedDateTime Quickfix, el código se transforma de acuerdo con las acciones que especificamos en la receta.

Zonage Date Heure Avec Année Mois Jour Heure

Una migración única y prácticas de codificación uniformes en todos los equipos, con Sensei

En nuestro ejemplo anterior, podemos ver que la migración de una sola línea de código puede implicar un conocimiento adquirido con esfuerzo. Sensei puede convertir ese conocimiento en recetas prácticas o libros de cocina que puedan compartirse entre equipos. Puedes planificar una migración rápida única o adoptar el enfoque de realizar transformaciones instantáneas incrementales a java.time a medida que te encuentres con el código de Joda-Time. Puedes activar o desactivar las recetas para realizar las migraciones por etapas o pasos lógicos e incluso ampliar o reducir el alcance de los archivos analizados por Sensei, con la flexibilidad que hace que las migraciones de código sean menos complicadas.

La migración de bibliotecas es solo un ejemplo de las muchas maneras en las que se puede usar Sensei para estandarizar sus proyectos. Siempre puedes estar atento a los antipatrones o a ciertas transformaciones manuales de código que aparecen con frecuencia en las solicitudes de cambios o mientras codificas tú mismo. Si tienes un conjunto de directrices de codificación que los desarrolladores suelen pasar por alto, podrías convertir las directrices en recetas, lo que permitiría a los desarrolladores aplicar las transformaciones de código aprobadas con confianza.

Si tiene alguna pregunta, ¡nos encantaría saber de usted! Únete a nosotros en Slack en: sensei-scw.slack.com

Veuillez consulter la ressource
Veuillez consulter la ressource

Migre Joda-Time a java.time de forma cómoda

Souhaitez-vous en savoir davantage ?

Cameron est développeur de logiciels senior à Secure Code Warrior. Il a plus de 15 ans d'expérience dans la fourniture de logiciels. Il est passionné par la productivité des développeurs et contribue activement aux logiciels libres.

En savoir plus

Secure Code Warrior là pour aider votre organisation à protéger le code tout au long du cycle de vie du développement logiciel et à créer une culture où la cybersécurité est une priorité. Que vous soyez administrateur AppSec, développeur, CISO ou toute autre personne impliquée dans la sécurité, nous pouvons aider votre organisation à réduire les risques associés à un code non sécurisé.

Veuillez réserver une démonstration.
Partager sur :
marques LinkedInSocialLogo x
auteur
Cameron Gregor
Publié le 12 novembre 2021

Cameron est développeur de logiciels senior à Secure Code Warrior. Il a plus de 15 ans d'expérience dans la fourniture de logiciels. Il est passionné par la productivité des développeurs et contribue activement aux logiciels libres.

Partager sur :
marques LinkedInSocialLogo x

Migrar código (léase: código heredado) no es divertido. Se necesita una enorme cantidad de planificación y esfuerzo para lograrlo. Si bien no es el trabajo más emocionante o motivador para los desarrolladores, sí que requiere determinación y la experiencia adecuada para migrar el código heredado a las nuevas versiones de la biblioteca. Hora de Joda a java.time es una de esas migraciones que requiere una planificación y ejecución meticulosas.

Si su proyecto Java comenzó su vida antes de Java SE 8 y utiliza el procesamiento de fecha y hora, es probable que haya utilizado Joda-Time, una biblioteca excelente y un estándar de facto para gestionar las funciones de fecha y hora anteriores a SE 8. Si tu proyecto Aún así usa Joda-Time pero le gustaría migrar a java.time y luego siga leyendo.

La versión de Java SE 8 incluía una API de fecha y hora estándar nueva y mejorada, comúnmente denominada java.time (JSR-310). El proyecto Joda-Time ahora recomienda migrar a java.time (JSR-310).

Si bien java.time (JSR-310) se inspiró en gran medida en Joda-Time, no es compatible con versiones anteriores y los conceptos y terminologías han cambiado. Por eso, migrar de Joda-Time a java.time requiere prestar mucha atención a todas y cada una de las líneas de código que cambias. Esto puede llevar mucho tiempo y casi haría que deseara que hubiera una forma más fácil y automatizada de migrar.

Hay una forma mejor de migrar y la hemos creado con Sensei, un complemento de IntelliJ que realiza automáticamente transformaciones de código según las recetas (reglas) definidas por usted. Dedica tu tiempo a definir recetas reutilizables, en lugar de a realizar tareas de migración repetitivas. La automatización no solo transformará tu código heredado de Joda-Time, sino que también ayudará a los equipos a seguir las directrices que aparecen en el IDE a medida que escriben código nuevo.

Para ayudarlo a comenzar con ventaja, hemos creado un libro de cocina público sobre Sensei Estandarización en java.time (JSR-310) que incluye recetas para migrar de Joda-Time a java.time de una manera menos dolorosa. Se trata de un conjunto de recetas cada vez mayor que seguiremos ampliando para añadir más cobertura con más recetas.

Este es un ejemplo de un ejemplo de migración que puede ayudarle a ver cómo Sensei facilita la migración del código heredado.

Vidéo de la définition de l'heure de la date java.time zoned

Desde la migración manual repetitiva hasta las transformaciones de código automatizadas

Veamos un ejemplo de creación de un nuevo DateTime que muestra algunas trampas ocultas al migrar una sola línea de código de Joda-Time a java.time. A continuación, analizaremos una de las recetas de Sensei de nuestro libro de recetas sobre la estandarización de java.time (JSR-310) y mostraremos cómo captura toda esta información para que cualquier desarrollador pueda volver a utilizar esta misma migración una y otra vez.

En este ejemplo, estamos construyendo un Joda-Time DateTime a partir de 7 argumentos int que representan los valores de los campos DateTime.

¿Cómo migramos esto a un equivalente de java.time?

El javadoc en Joda-Time para este constructor dice:

Construye una instancia a partir de los valores de los campos de fecha y hora utilizando IsoChronology en la zona horaria predeterminada.

Al principio, podemos suponer que hay Fecha/hora clase en java.time, pero no hay ninguna. Si buscas en Google «migrar de la hora de Joda a la hora de Java», lo más probable es que encuentres la entrada del blog de Stephen Colebourne Conversión de Joda-Time a java.time.

Esto le da un buen comienzo y nos indica cómo usar java.time.zonedDateTime o java.time.offsetDateTime. Esta es nuestra primera pregunta, ¿cuál uso? Probablemente ZonedDateTime se basa en los comentarios de Stephen.

Buscando el ZonedDateTime javadoc, no podemos ver ningún constructor en absoluto. Volviendo a la entrada del blog de Stephen, leemos más abajo:

Construcción. Joda-Time tiene un constructor que acepta un objeto y realiza la conversión de tipos. java.time solo tiene métodos de fábrica, por lo que la conversión es un problema del usuario, aunque se proporciona un método parse () para las cadenas.

Por lo tanto, debe haber un método de fábrica estático, al buscar los métodos estáticos encontramos uno que se parece bastante, pero no es exactamente el mismo.

Tiene 7 parámetros int como nuestro constructor Joda-Time DateTime original, sin embargo, si no prestas atención, te perderás un detalle importante. El séptimo parámetro ya no representa milisegundos, sino nanosegundos, ya que java.time tiene una precisión mayor que Joda-Time y mide los instantes hasta el nano-segundo. Un detalle importante que podrías haber pasado por alto fácilmente. Además, este método espera un ZoneID, por lo que hace que te preguntes por qué no necesitabas uno antes y por qué lo necesitas ahora.

Recordando el javadoc de nuestro constructor original que mencionaba que usaría la zona horaria predeterminada, ¿tal vez haya una forma de obtener el ZoneID predeterminado?

El javadoc para ZoneID no nos informa sobre ningún constructor de la lista, pero al observar los métodos estáticos vemos que podemos usar Predeterminado del sistema ()

Ahora que hemos resuelto el ZoneID, ¿qué debemos hacer con nuestra conversión de milisegundos a nanosegundos? Tal vez podamos usar java.util.Concurrent.TimeUnit para realizar la conversión.

Este método devuelve un valor long y nuestro método espera un int, por lo que ahora también tenemos que resolver un problema de conversión. Tal vez podríamos probar algo simple. ¿Una multiplicación?

Esto funcionará, pero parece un poco fuera de lugar. Si aún no lo has notado, hemos dedicado una cantidad considerable de tiempo y esfuerzo a migrar una sola línea de código. Pero como puedes imaginar, tenemos muchas ediciones de este tipo que hacer a mano y no hay nada mejor.

Sin embargo, si analizamos un poco más la API java.time, podemos descubrir una solución que parece un poco más fluida.

Aunque ZonedDateTime no tiene una forma obvia de configurar los milisegundos, se puede hacer usando el con el método (campo temporalField, newValue largo), utilizando Cronofield. Mili_de_segundo como TemporalField.

Y el documento de Java menciona que realizará la conversión a nanosegundos por nosotros:

Cuando este campo se usa para establecer un valor, debe comportarse de la misma manera que si se establece NANO_OF_SECOND con el valor multiplicado por 1 000 000.

Así que podemos simplemente especificar 0 para nuestros nanosegundos en el método de fábrica y, a continuación, usar el con método para crear un ZonedDateTime que tenga todos los valores originales, así como los milisegundos.

Al observar nuestro resultado final, parece que solo hemos cambiado una línea de código, ¡realmente no muestra el esfuerzo que se dedicó a investigar solo una migración!

Cree una receta para migrar de forma más rápida y sencilla

Sensei nos proporciona una forma de compartir esta información ganada con tanto esfuerzo con otros desarrolladores. Al crear una receta que recoja todos estos requisitos, permitirá a los usuarios de Sensei realizar esta migración con solo un clic del ratón.

Una receta de Sensei consta de 3 secciones principales:

  • Metadatos
  • Búsqueda
  • Correcciones disponibles

Veamos una receta de Sensei (también se puede ver como una receta de YAML) que nos ayudará a migrar esta llamada a su equivalente en java.time.

DateTime foo = nueva fecha y hora (año, mes del año, día del mes, hora del día, minuto de hora, segundo de minuto, milisegundo de segundo);

Sección de metadatos

La sección de metadatos contiene información sobre la receta y cómo debe usarse.

Sección de búsqueda

La sección de búsqueda de una receta de Sensei especifica a qué elementos de código se debe aplicar esta receta.

buscar:
Creación de instancias:
argumentos:
1:
tipo: int
2:
tipo: int
3:
tipo: int
4:
tipo: int
5:
tipo: int
6:
tipo: int
7:
tipo: int
Recuento de arg: 7
tipo: org.joda.time.DateTime

En esta sección de búsqueda vemos que estamos:

  • En busca de un Creación de instancias, es decir, el uso de un Constructor. Nota: hay muchos otros objetivos de búsqueda disponibles
  • El constructor debe tener 7 argumentos, esto se especifica en Recuento de arg propiedad
  • argumentos 1-7 debe ser de tipo int
  • Estamos buscando a los constructores del tipo org.joda.time.dateTime

Sección de correcciones disponibles

La sección AvailableFixes puede especificar una o más correcciones que se pueden aplicar al elemento de código coincidente. Cada corrección puede tener varias acciones y, en nuestro caso, tenemos una única solución que realiza 2 acciones.

  • El nombre de la solución se muestra al usuario en el menú «Correcciones rápidas» y describe lo que ocurrirá si el usuario aplica esta solución rápida
  • La lista de acciones muestra las acciones que realizará esta solución rápida.
  • El volver a escribir la acción reescribirá el elemento de código utilizando una plantilla de bigote. Puede hacer uso de variables y funciones de reemplazo de cadenas.
  • El Modificar variable asignada action comprobará si este constructor se utiliza para asignar el valor a una variable. Si es así, esta acción modificará la variable para declararla como el tipo especificado por tipo

Uso de la receta para realizar la transformación del código

Con nuestra receta escrita y habilitada, escanea nuestro código y resalta los segmentos a los que se puede aplicar.

En la siguiente captura de pantalla podemos ver que el constructor objetivo ha sido marcado por Sensei. Al pasar el ratón sobre el constructor marcado, aparecen la opción Recipe ShortDescription y Quickfix Migrar a java.time.ZonedDateTime

Migrer la nouvelle date et l'heure

Después de seleccionar el Migrar a java.time.ZonedDateTime Quickfix, el código se transforma de acuerdo con las acciones que especificamos en la receta.

Zonage Date Heure Avec Année Mois Jour Heure

Una migración única y prácticas de codificación uniformes en todos los equipos, con Sensei

En nuestro ejemplo anterior, podemos ver que la migración de una sola línea de código puede implicar un conocimiento adquirido con esfuerzo. Sensei puede convertir ese conocimiento en recetas prácticas o libros de cocina que puedan compartirse entre equipos. Puedes planificar una migración rápida única o adoptar el enfoque de realizar transformaciones instantáneas incrementales a java.time a medida que te encuentres con el código de Joda-Time. Puedes activar o desactivar las recetas para realizar las migraciones por etapas o pasos lógicos e incluso ampliar o reducir el alcance de los archivos analizados por Sensei, con la flexibilidad que hace que las migraciones de código sean menos complicadas.

La migración de bibliotecas es solo un ejemplo de las muchas maneras en las que se puede usar Sensei para estandarizar sus proyectos. Siempre puedes estar atento a los antipatrones o a ciertas transformaciones manuales de código que aparecen con frecuencia en las solicitudes de cambios o mientras codificas tú mismo. Si tienes un conjunto de directrices de codificación que los desarrolladores suelen pasar por alto, podrías convertir las directrices en recetas, lo que permitiría a los desarrolladores aplicar las transformaciones de código aprobadas con confianza.

Si tiene alguna pregunta, ¡nos encantaría saber de usted! Únete a nosotros en Slack en: sensei-scw.slack.com

Veuillez consulter la ressource
Veuillez consulter la ressource

Veuillez remplir le formulaire suivant pour télécharger le rapport.

Nous souhaiterions obtenir votre autorisation pour vous envoyer des informations sur nos produits ou sur des sujets liés au codage sécurisé. Nous traiterons toujours vos données personnelles avec le plus grand soin et ne les vendrons jamais à d'autres entreprises à des fins de marketing.

Envoyer
icône de réussite scw
icône d'erreur scw
Pour envoyer le formulaire, veuillez activer les cookies « d'analyse ». N'hésitez pas à les désactiver à nouveau une fois que vous avez terminé.

Migrar código (léase: código heredado) no es divertido. Se necesita una enorme cantidad de planificación y esfuerzo para lograrlo. Si bien no es el trabajo más emocionante o motivador para los desarrolladores, sí que requiere determinación y la experiencia adecuada para migrar el código heredado a las nuevas versiones de la biblioteca. Hora de Joda a java.time es una de esas migraciones que requiere una planificación y ejecución meticulosas.

Si su proyecto Java comenzó su vida antes de Java SE 8 y utiliza el procesamiento de fecha y hora, es probable que haya utilizado Joda-Time, una biblioteca excelente y un estándar de facto para gestionar las funciones de fecha y hora anteriores a SE 8. Si tu proyecto Aún así usa Joda-Time pero le gustaría migrar a java.time y luego siga leyendo.

La versión de Java SE 8 incluía una API de fecha y hora estándar nueva y mejorada, comúnmente denominada java.time (JSR-310). El proyecto Joda-Time ahora recomienda migrar a java.time (JSR-310).

Si bien java.time (JSR-310) se inspiró en gran medida en Joda-Time, no es compatible con versiones anteriores y los conceptos y terminologías han cambiado. Por eso, migrar de Joda-Time a java.time requiere prestar mucha atención a todas y cada una de las líneas de código que cambias. Esto puede llevar mucho tiempo y casi haría que deseara que hubiera una forma más fácil y automatizada de migrar.

Hay una forma mejor de migrar y la hemos creado con Sensei, un complemento de IntelliJ que realiza automáticamente transformaciones de código según las recetas (reglas) definidas por usted. Dedica tu tiempo a definir recetas reutilizables, en lugar de a realizar tareas de migración repetitivas. La automatización no solo transformará tu código heredado de Joda-Time, sino que también ayudará a los equipos a seguir las directrices que aparecen en el IDE a medida que escriben código nuevo.

Para ayudarlo a comenzar con ventaja, hemos creado un libro de cocina público sobre Sensei Estandarización en java.time (JSR-310) que incluye recetas para migrar de Joda-Time a java.time de una manera menos dolorosa. Se trata de un conjunto de recetas cada vez mayor que seguiremos ampliando para añadir más cobertura con más recetas.

Este es un ejemplo de un ejemplo de migración que puede ayudarle a ver cómo Sensei facilita la migración del código heredado.

Vidéo de la définition de l'heure de la date java.time zoned

Desde la migración manual repetitiva hasta las transformaciones de código automatizadas

Veamos un ejemplo de creación de un nuevo DateTime que muestra algunas trampas ocultas al migrar una sola línea de código de Joda-Time a java.time. A continuación, analizaremos una de las recetas de Sensei de nuestro libro de recetas sobre la estandarización de java.time (JSR-310) y mostraremos cómo captura toda esta información para que cualquier desarrollador pueda volver a utilizar esta misma migración una y otra vez.

En este ejemplo, estamos construyendo un Joda-Time DateTime a partir de 7 argumentos int que representan los valores de los campos DateTime.

¿Cómo migramos esto a un equivalente de java.time?

El javadoc en Joda-Time para este constructor dice:

Construye una instancia a partir de los valores de los campos de fecha y hora utilizando IsoChronology en la zona horaria predeterminada.

Al principio, podemos suponer que hay Fecha/hora clase en java.time, pero no hay ninguna. Si buscas en Google «migrar de la hora de Joda a la hora de Java», lo más probable es que encuentres la entrada del blog de Stephen Colebourne Conversión de Joda-Time a java.time.

Esto le da un buen comienzo y nos indica cómo usar java.time.zonedDateTime o java.time.offsetDateTime. Esta es nuestra primera pregunta, ¿cuál uso? Probablemente ZonedDateTime se basa en los comentarios de Stephen.

Buscando el ZonedDateTime javadoc, no podemos ver ningún constructor en absoluto. Volviendo a la entrada del blog de Stephen, leemos más abajo:

Construcción. Joda-Time tiene un constructor que acepta un objeto y realiza la conversión de tipos. java.time solo tiene métodos de fábrica, por lo que la conversión es un problema del usuario, aunque se proporciona un método parse () para las cadenas.

Por lo tanto, debe haber un método de fábrica estático, al buscar los métodos estáticos encontramos uno que se parece bastante, pero no es exactamente el mismo.

Tiene 7 parámetros int como nuestro constructor Joda-Time DateTime original, sin embargo, si no prestas atención, te perderás un detalle importante. El séptimo parámetro ya no representa milisegundos, sino nanosegundos, ya que java.time tiene una precisión mayor que Joda-Time y mide los instantes hasta el nano-segundo. Un detalle importante que podrías haber pasado por alto fácilmente. Además, este método espera un ZoneID, por lo que hace que te preguntes por qué no necesitabas uno antes y por qué lo necesitas ahora.

Recordando el javadoc de nuestro constructor original que mencionaba que usaría la zona horaria predeterminada, ¿tal vez haya una forma de obtener el ZoneID predeterminado?

El javadoc para ZoneID no nos informa sobre ningún constructor de la lista, pero al observar los métodos estáticos vemos que podemos usar Predeterminado del sistema ()

Ahora que hemos resuelto el ZoneID, ¿qué debemos hacer con nuestra conversión de milisegundos a nanosegundos? Tal vez podamos usar java.util.Concurrent.TimeUnit para realizar la conversión.

Este método devuelve un valor long y nuestro método espera un int, por lo que ahora también tenemos que resolver un problema de conversión. Tal vez podríamos probar algo simple. ¿Una multiplicación?

Esto funcionará, pero parece un poco fuera de lugar. Si aún no lo has notado, hemos dedicado una cantidad considerable de tiempo y esfuerzo a migrar una sola línea de código. Pero como puedes imaginar, tenemos muchas ediciones de este tipo que hacer a mano y no hay nada mejor.

Sin embargo, si analizamos un poco más la API java.time, podemos descubrir una solución que parece un poco más fluida.

Aunque ZonedDateTime no tiene una forma obvia de configurar los milisegundos, se puede hacer usando el con el método (campo temporalField, newValue largo), utilizando Cronofield. Mili_de_segundo como TemporalField.

Y el documento de Java menciona que realizará la conversión a nanosegundos por nosotros:

Cuando este campo se usa para establecer un valor, debe comportarse de la misma manera que si se establece NANO_OF_SECOND con el valor multiplicado por 1 000 000.

Así que podemos simplemente especificar 0 para nuestros nanosegundos en el método de fábrica y, a continuación, usar el con método para crear un ZonedDateTime que tenga todos los valores originales, así como los milisegundos.

Al observar nuestro resultado final, parece que solo hemos cambiado una línea de código, ¡realmente no muestra el esfuerzo que se dedicó a investigar solo una migración!

Cree una receta para migrar de forma más rápida y sencilla

Sensei nos proporciona una forma de compartir esta información ganada con tanto esfuerzo con otros desarrolladores. Al crear una receta que recoja todos estos requisitos, permitirá a los usuarios de Sensei realizar esta migración con solo un clic del ratón.

Una receta de Sensei consta de 3 secciones principales:

  • Metadatos
  • Búsqueda
  • Correcciones disponibles

Veamos una receta de Sensei (también se puede ver como una receta de YAML) que nos ayudará a migrar esta llamada a su equivalente en java.time.

DateTime foo = nueva fecha y hora (año, mes del año, día del mes, hora del día, minuto de hora, segundo de minuto, milisegundo de segundo);

Sección de metadatos

La sección de metadatos contiene información sobre la receta y cómo debe usarse.

Sección de búsqueda

La sección de búsqueda de una receta de Sensei especifica a qué elementos de código se debe aplicar esta receta.

buscar:
Creación de instancias:
argumentos:
1:
tipo: int
2:
tipo: int
3:
tipo: int
4:
tipo: int
5:
tipo: int
6:
tipo: int
7:
tipo: int
Recuento de arg: 7
tipo: org.joda.time.DateTime

En esta sección de búsqueda vemos que estamos:

  • En busca de un Creación de instancias, es decir, el uso de un Constructor. Nota: hay muchos otros objetivos de búsqueda disponibles
  • El constructor debe tener 7 argumentos, esto se especifica en Recuento de arg propiedad
  • argumentos 1-7 debe ser de tipo int
  • Estamos buscando a los constructores del tipo org.joda.time.dateTime

Sección de correcciones disponibles

La sección AvailableFixes puede especificar una o más correcciones que se pueden aplicar al elemento de código coincidente. Cada corrección puede tener varias acciones y, en nuestro caso, tenemos una única solución que realiza 2 acciones.

  • El nombre de la solución se muestra al usuario en el menú «Correcciones rápidas» y describe lo que ocurrirá si el usuario aplica esta solución rápida
  • La lista de acciones muestra las acciones que realizará esta solución rápida.
  • El volver a escribir la acción reescribirá el elemento de código utilizando una plantilla de bigote. Puede hacer uso de variables y funciones de reemplazo de cadenas.
  • El Modificar variable asignada action comprobará si este constructor se utiliza para asignar el valor a una variable. Si es así, esta acción modificará la variable para declararla como el tipo especificado por tipo

Uso de la receta para realizar la transformación del código

Con nuestra receta escrita y habilitada, escanea nuestro código y resalta los segmentos a los que se puede aplicar.

En la siguiente captura de pantalla podemos ver que el constructor objetivo ha sido marcado por Sensei. Al pasar el ratón sobre el constructor marcado, aparecen la opción Recipe ShortDescription y Quickfix Migrar a java.time.ZonedDateTime

Migrer la nouvelle date et l'heure

Después de seleccionar el Migrar a java.time.ZonedDateTime Quickfix, el código se transforma de acuerdo con las acciones que especificamos en la receta.

Zonage Date Heure Avec Année Mois Jour Heure

Una migración única y prácticas de codificación uniformes en todos los equipos, con Sensei

En nuestro ejemplo anterior, podemos ver que la migración de una sola línea de código puede implicar un conocimiento adquirido con esfuerzo. Sensei puede convertir ese conocimiento en recetas prácticas o libros de cocina que puedan compartirse entre equipos. Puedes planificar una migración rápida única o adoptar el enfoque de realizar transformaciones instantáneas incrementales a java.time a medida que te encuentres con el código de Joda-Time. Puedes activar o desactivar las recetas para realizar las migraciones por etapas o pasos lógicos e incluso ampliar o reducir el alcance de los archivos analizados por Sensei, con la flexibilidad que hace que las migraciones de código sean menos complicadas.

La migración de bibliotecas es solo un ejemplo de las muchas maneras en las que se puede usar Sensei para estandarizar sus proyectos. Siempre puedes estar atento a los antipatrones o a ciertas transformaciones manuales de código que aparecen con frecuencia en las solicitudes de cambios o mientras codificas tú mismo. Si tienes un conjunto de directrices de codificación que los desarrolladores suelen pasar por alto, podrías convertir las directrices en recetas, lo que permitiría a los desarrolladores aplicar las transformaciones de código aprobadas con confianza.

Si tiene alguna pregunta, ¡nos encantaría saber de usted! Únete a nosotros en Slack en: sensei-scw.slack.com

Veuillez consulter le webinaire
Commencer
En savoir plus

Veuillez cliquer sur le lien ci-dessous et télécharger le PDF de cette ressource.

Secure Code Warrior là pour aider votre organisation à protéger le code tout au long du cycle de vie du développement logiciel et à créer une culture où la cybersécurité est une priorité. Que vous soyez administrateur AppSec, développeur, CISO ou toute autre personne impliquée dans la sécurité, nous pouvons aider votre organisation à réduire les risques associés à un code non sécurisé.

Veuillez consulter le rapportVeuillez réserver une démonstration.
Télécharger le PDF
Veuillez consulter la ressource
Partager sur :
marques LinkedInSocialLogo x
Souhaitez-vous en savoir davantage ?

Partager sur :
marques LinkedInSocialLogo x
auteur
Cameron Gregor
Publié le 12 novembre 2021

Cameron est développeur de logiciels senior à Secure Code Warrior. Il a plus de 15 ans d'expérience dans la fourniture de logiciels. Il est passionné par la productivité des développeurs et contribue activement aux logiciels libres.

Partager sur :
marques LinkedInSocialLogo x

Migrar código (léase: código heredado) no es divertido. Se necesita una enorme cantidad de planificación y esfuerzo para lograrlo. Si bien no es el trabajo más emocionante o motivador para los desarrolladores, sí que requiere determinación y la experiencia adecuada para migrar el código heredado a las nuevas versiones de la biblioteca. Hora de Joda a java.time es una de esas migraciones que requiere una planificación y ejecución meticulosas.

Si su proyecto Java comenzó su vida antes de Java SE 8 y utiliza el procesamiento de fecha y hora, es probable que haya utilizado Joda-Time, una biblioteca excelente y un estándar de facto para gestionar las funciones de fecha y hora anteriores a SE 8. Si tu proyecto Aún así usa Joda-Time pero le gustaría migrar a java.time y luego siga leyendo.

La versión de Java SE 8 incluía una API de fecha y hora estándar nueva y mejorada, comúnmente denominada java.time (JSR-310). El proyecto Joda-Time ahora recomienda migrar a java.time (JSR-310).

Si bien java.time (JSR-310) se inspiró en gran medida en Joda-Time, no es compatible con versiones anteriores y los conceptos y terminologías han cambiado. Por eso, migrar de Joda-Time a java.time requiere prestar mucha atención a todas y cada una de las líneas de código que cambias. Esto puede llevar mucho tiempo y casi haría que deseara que hubiera una forma más fácil y automatizada de migrar.

Hay una forma mejor de migrar y la hemos creado con Sensei, un complemento de IntelliJ que realiza automáticamente transformaciones de código según las recetas (reglas) definidas por usted. Dedica tu tiempo a definir recetas reutilizables, en lugar de a realizar tareas de migración repetitivas. La automatización no solo transformará tu código heredado de Joda-Time, sino que también ayudará a los equipos a seguir las directrices que aparecen en el IDE a medida que escriben código nuevo.

Para ayudarlo a comenzar con ventaja, hemos creado un libro de cocina público sobre Sensei Estandarización en java.time (JSR-310) que incluye recetas para migrar de Joda-Time a java.time de una manera menos dolorosa. Se trata de un conjunto de recetas cada vez mayor que seguiremos ampliando para añadir más cobertura con más recetas.

Este es un ejemplo de un ejemplo de migración que puede ayudarle a ver cómo Sensei facilita la migración del código heredado.

Vidéo de la définition de l'heure de la date java.time zoned

Desde la migración manual repetitiva hasta las transformaciones de código automatizadas

Veamos un ejemplo de creación de un nuevo DateTime que muestra algunas trampas ocultas al migrar una sola línea de código de Joda-Time a java.time. A continuación, analizaremos una de las recetas de Sensei de nuestro libro de recetas sobre la estandarización de java.time (JSR-310) y mostraremos cómo captura toda esta información para que cualquier desarrollador pueda volver a utilizar esta misma migración una y otra vez.

En este ejemplo, estamos construyendo un Joda-Time DateTime a partir de 7 argumentos int que representan los valores de los campos DateTime.

¿Cómo migramos esto a un equivalente de java.time?

El javadoc en Joda-Time para este constructor dice:

Construye una instancia a partir de los valores de los campos de fecha y hora utilizando IsoChronology en la zona horaria predeterminada.

Al principio, podemos suponer que hay Fecha/hora clase en java.time, pero no hay ninguna. Si buscas en Google «migrar de la hora de Joda a la hora de Java», lo más probable es que encuentres la entrada del blog de Stephen Colebourne Conversión de Joda-Time a java.time.

Esto le da un buen comienzo y nos indica cómo usar java.time.zonedDateTime o java.time.offsetDateTime. Esta es nuestra primera pregunta, ¿cuál uso? Probablemente ZonedDateTime se basa en los comentarios de Stephen.

Buscando el ZonedDateTime javadoc, no podemos ver ningún constructor en absoluto. Volviendo a la entrada del blog de Stephen, leemos más abajo:

Construcción. Joda-Time tiene un constructor que acepta un objeto y realiza la conversión de tipos. java.time solo tiene métodos de fábrica, por lo que la conversión es un problema del usuario, aunque se proporciona un método parse () para las cadenas.

Por lo tanto, debe haber un método de fábrica estático, al buscar los métodos estáticos encontramos uno que se parece bastante, pero no es exactamente el mismo.

Tiene 7 parámetros int como nuestro constructor Joda-Time DateTime original, sin embargo, si no prestas atención, te perderás un detalle importante. El séptimo parámetro ya no representa milisegundos, sino nanosegundos, ya que java.time tiene una precisión mayor que Joda-Time y mide los instantes hasta el nano-segundo. Un detalle importante que podrías haber pasado por alto fácilmente. Además, este método espera un ZoneID, por lo que hace que te preguntes por qué no necesitabas uno antes y por qué lo necesitas ahora.

Recordando el javadoc de nuestro constructor original que mencionaba que usaría la zona horaria predeterminada, ¿tal vez haya una forma de obtener el ZoneID predeterminado?

El javadoc para ZoneID no nos informa sobre ningún constructor de la lista, pero al observar los métodos estáticos vemos que podemos usar Predeterminado del sistema ()

Ahora que hemos resuelto el ZoneID, ¿qué debemos hacer con nuestra conversión de milisegundos a nanosegundos? Tal vez podamos usar java.util.Concurrent.TimeUnit para realizar la conversión.

Este método devuelve un valor long y nuestro método espera un int, por lo que ahora también tenemos que resolver un problema de conversión. Tal vez podríamos probar algo simple. ¿Una multiplicación?

Esto funcionará, pero parece un poco fuera de lugar. Si aún no lo has notado, hemos dedicado una cantidad considerable de tiempo y esfuerzo a migrar una sola línea de código. Pero como puedes imaginar, tenemos muchas ediciones de este tipo que hacer a mano y no hay nada mejor.

Sin embargo, si analizamos un poco más la API java.time, podemos descubrir una solución que parece un poco más fluida.

Aunque ZonedDateTime no tiene una forma obvia de configurar los milisegundos, se puede hacer usando el con el método (campo temporalField, newValue largo), utilizando Cronofield. Mili_de_segundo como TemporalField.

Y el documento de Java menciona que realizará la conversión a nanosegundos por nosotros:

Cuando este campo se usa para establecer un valor, debe comportarse de la misma manera que si se establece NANO_OF_SECOND con el valor multiplicado por 1 000 000.

Así que podemos simplemente especificar 0 para nuestros nanosegundos en el método de fábrica y, a continuación, usar el con método para crear un ZonedDateTime que tenga todos los valores originales, así como los milisegundos.

Al observar nuestro resultado final, parece que solo hemos cambiado una línea de código, ¡realmente no muestra el esfuerzo que se dedicó a investigar solo una migración!

Cree una receta para migrar de forma más rápida y sencilla

Sensei nos proporciona una forma de compartir esta información ganada con tanto esfuerzo con otros desarrolladores. Al crear una receta que recoja todos estos requisitos, permitirá a los usuarios de Sensei realizar esta migración con solo un clic del ratón.

Una receta de Sensei consta de 3 secciones principales:

  • Metadatos
  • Búsqueda
  • Correcciones disponibles

Veamos una receta de Sensei (también se puede ver como una receta de YAML) que nos ayudará a migrar esta llamada a su equivalente en java.time.

DateTime foo = nueva fecha y hora (año, mes del año, día del mes, hora del día, minuto de hora, segundo de minuto, milisegundo de segundo);

Sección de metadatos

La sección de metadatos contiene información sobre la receta y cómo debe usarse.

Sección de búsqueda

La sección de búsqueda de una receta de Sensei especifica a qué elementos de código se debe aplicar esta receta.

buscar:
Creación de instancias:
argumentos:
1:
tipo: int
2:
tipo: int
3:
tipo: int
4:
tipo: int
5:
tipo: int
6:
tipo: int
7:
tipo: int
Recuento de arg: 7
tipo: org.joda.time.DateTime

En esta sección de búsqueda vemos que estamos:

  • En busca de un Creación de instancias, es decir, el uso de un Constructor. Nota: hay muchos otros objetivos de búsqueda disponibles
  • El constructor debe tener 7 argumentos, esto se especifica en Recuento de arg propiedad
  • argumentos 1-7 debe ser de tipo int
  • Estamos buscando a los constructores del tipo org.joda.time.dateTime

Sección de correcciones disponibles

La sección AvailableFixes puede especificar una o más correcciones que se pueden aplicar al elemento de código coincidente. Cada corrección puede tener varias acciones y, en nuestro caso, tenemos una única solución que realiza 2 acciones.

  • El nombre de la solución se muestra al usuario en el menú «Correcciones rápidas» y describe lo que ocurrirá si el usuario aplica esta solución rápida
  • La lista de acciones muestra las acciones que realizará esta solución rápida.
  • El volver a escribir la acción reescribirá el elemento de código utilizando una plantilla de bigote. Puede hacer uso de variables y funciones de reemplazo de cadenas.
  • El Modificar variable asignada action comprobará si este constructor se utiliza para asignar el valor a una variable. Si es así, esta acción modificará la variable para declararla como el tipo especificado por tipo

Uso de la receta para realizar la transformación del código

Con nuestra receta escrita y habilitada, escanea nuestro código y resalta los segmentos a los que se puede aplicar.

En la siguiente captura de pantalla podemos ver que el constructor objetivo ha sido marcado por Sensei. Al pasar el ratón sobre el constructor marcado, aparecen la opción Recipe ShortDescription y Quickfix Migrar a java.time.ZonedDateTime

Migrer la nouvelle date et l'heure

Después de seleccionar el Migrar a java.time.ZonedDateTime Quickfix, el código se transforma de acuerdo con las acciones que especificamos en la receta.

Zonage Date Heure Avec Année Mois Jour Heure

Una migración única y prácticas de codificación uniformes en todos los equipos, con Sensei

En nuestro ejemplo anterior, podemos ver que la migración de una sola línea de código puede implicar un conocimiento adquirido con esfuerzo. Sensei puede convertir ese conocimiento en recetas prácticas o libros de cocina que puedan compartirse entre equipos. Puedes planificar una migración rápida única o adoptar el enfoque de realizar transformaciones instantáneas incrementales a java.time a medida que te encuentres con el código de Joda-Time. Puedes activar o desactivar las recetas para realizar las migraciones por etapas o pasos lógicos e incluso ampliar o reducir el alcance de los archivos analizados por Sensei, con la flexibilidad que hace que las migraciones de código sean menos complicadas.

La migración de bibliotecas es solo un ejemplo de las muchas maneras en las que se puede usar Sensei para estandarizar sus proyectos. Siempre puedes estar atento a los antipatrones o a ciertas transformaciones manuales de código que aparecen con frecuencia en las solicitudes de cambios o mientras codificas tú mismo. Si tienes un conjunto de directrices de codificación que los desarrolladores suelen pasar por alto, podrías convertir las directrices en recetas, lo que permitiría a los desarrolladores aplicar las transformaciones de código aprobadas con confianza.

Si tiene alguna pregunta, ¡nos encantaría saber de usted! Únete a nosotros en Slack en: sensei-scw.slack.com

Table des matières

Télécharger le PDF
Veuillez consulter la ressource
Souhaitez-vous en savoir davantage ?

Cameron est développeur de logiciels senior à Secure Code Warrior. Il a plus de 15 ans d'expérience dans la fourniture de logiciels. Il est passionné par la productivité des développeurs et contribue activement aux logiciels libres.

En savoir plus

Secure Code Warrior là pour aider votre organisation à protéger le code tout au long du cycle de vie du développement logiciel et à créer une culture où la cybersécurité est une priorité. Que vous soyez administrateur AppSec, développeur, CISO ou toute autre personne impliquée dans la sécurité, nous pouvons aider votre organisation à réduire les risques associés à un code non sécurisé.

Veuillez réserver une démonstration.Télécharger
Partager sur :
marques LinkedInSocialLogo x
Centre de ressources

Ressources pour débuter

Plus de publications
Centre de ressources

Ressources pour débuter

Plus de publications