
Migración de Joda-Time a java.time
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.

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

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.

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

Migre Joda-Time a java.time de forma cómoda
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.

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.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.

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.

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

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.

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

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.

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

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.

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 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.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.
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.

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

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.

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
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.

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échargerRessources pour débuter
Thèmes et contenu de la formation sur le code sécurisé
Notre contenu de pointe évolue constamment afin de s'adapter au paysage changeant du développement logiciel, en tenant compte de votre rôle. Nous proposons des thèmes allant de l'IA à l'injection XQuery pour différents postes, des architectes et ingénieurs aux chefs de produit et responsables de l'assurance qualité. Découvrez un aperçu de ce que notre catalogue de contenu a à offrir par thème et par fonction.
La Chambre de commerce établit la norme en matière de sécurité à grande échelle axée sur les développeurs
La Chambre de commerce néerlandaise explique comment elle a intégré le codage sécurisé dans le développement quotidien grâce à des certifications basées sur les rôles, à l'évaluation comparative du Trust Score et à une culture de responsabilité partagée en matière de sécurité.
Modélisation des menaces avec l'IA : transformer chaque développeur en modélisateur de menaces
Vous repartirez mieux équipé pour aider les développeurs à combiner les idées et les techniques de modélisation des menaces avec les outils d'IA qu'ils utilisent déjà pour renforcer la sécurité, améliorer la collaboration et créer des logiciels plus résilients dès le départ.
Ressources pour débuter
Cybermon est de retour : les missions IA de Beat the Boss sont désormais disponibles à la demande.
Cybermon 2025 Beat the Boss est désormais disponible toute l'année chez SCW. Mettez en œuvre des défis de sécurité avancés basés sur l'IA et le LLM afin de renforcer le développement sécurisé de l'IA à grande échelle.
Explication de la loi sur la cyber-résilience : implications pour le développement de logiciels sécurisés dès leur conception
Découvrez les exigences de la loi européenne sur la cyber-résilience (CRA), à qui elle s'applique et comment les équipes d'ingénierie peuvent se préparer grâce à des pratiques de conception sécurisées, à la prévention des vulnérabilités et au développement des compétences des développeurs.
Facilitateur 1 : Critères de réussite définis et mesurables
Le catalyseur n° 1 inaugure notre série en 10 parties intitulée « Les catalyseurs de la réussite », qui montre comment relier la codification sécurisée aux résultats commerciaux, tels que la réduction des risques et la rapidité d'atteinte de la maturité du programme à long terme.




%20(1).avif)
.avif)
