
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
Cameron ist ein leitender Softwareentwickler bei Secure Code Warrior. Er verfügt über mehr als 15 Jahre Erfahrung in der Bereitstellung von Software. Er setzt sich leidenschaftlich für die Produktivität von Entwicklern ein und trägt aktiv zu Open-Source-Software bei.

Secure Code Warrior hier, um Ihrem Unternehmen dabei zu helfen, den Code während des gesamten Lebenszyklus der Softwareentwicklung zu schützen und eine Kultur zu schaffen, in der Cybersicherheit oberste Priorität hat. Ganz gleich, ob Sie AppSec-Administrator, Entwickler, CISO oder in einem anderen Bereich der Sicherheit tätig sind – wir können Ihrem Unternehmen dabei helfen, die mit unsicherem Code verbundenen Risiken zu reduzieren.
Eine Vorführung buchenCameron ist ein leitender Softwareentwickler bei Secure Code Warrior. Er verfügt über mehr als 15 Jahre Erfahrung in der Bereitstellung von Software. Er setzt sich leidenschaftlich für die Produktivität von Entwicklern ein und trägt aktiv zu Open-Source-Software bei.

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

Klicken Sie auf den untenstehenden Link und laden Sie die PDF-Datei dieser Ressource herunter.
Secure Code Warrior hier, um Ihrem Unternehmen dabei zu helfen, den Code während des gesamten Lebenszyklus der Softwareentwicklung zu schützen und eine Kultur zu schaffen, in der Cybersicherheit oberste Priorität hat. Ganz gleich, ob Sie AppSec-Administrator, Entwickler, CISO oder in einem anderen Bereich der Sicherheit tätig sind – wir können Ihrem Unternehmen dabei helfen, die mit unsicherem Code verbundenen Risiken zu reduzieren.
Bericht anzeigenEine Vorführung buchenCameron ist ein leitender Softwareentwickler bei Secure Code Warrior. Er verfügt über mehr als 15 Jahre Erfahrung in der Bereitstellung von Software. Er setzt sich leidenschaftlich für die Produktivität von Entwicklern ein und trägt aktiv zu Open-Source-Software bei.
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
Inhaltsverzeichnis
Cameron ist ein leitender Softwareentwickler bei Secure Code Warrior. Er verfügt über mehr als 15 Jahre Erfahrung in der Bereitstellung von Software. Er setzt sich leidenschaftlich für die Produktivität von Entwicklern ein und trägt aktiv zu Open-Source-Software bei.

Secure Code Warrior hier, um Ihrem Unternehmen dabei zu helfen, den Code während des gesamten Lebenszyklus der Softwareentwicklung zu schützen und eine Kultur zu schaffen, in der Cybersicherheit oberste Priorität hat. Ganz gleich, ob Sie AppSec-Administrator, Entwickler, CISO oder in einem anderen Bereich der Sicherheit tätig sind – wir können Ihrem Unternehmen dabei helfen, die mit unsicherem Code verbundenen Risiken zu reduzieren.
Eine Vorführung buchenHerunterladenRessourcen für den Einstieg
Themen und Inhalte der Schulung zum Thema sicherer Code
Unsere branchenführenden Inhalte werden ständig weiterentwickelt, um sich an die sich wandelnde Landschaft der Softwareentwicklung anzupassen und dabei Ihre Rolle zu berücksichtigen. Es werden Themen angeboten, die von KI bis hin zu XQuery-Injektion reichen und sich an verschiedene Positionen richten, von Architekten und Ingenieuren bis hin zu Produktmanagern und Qualitätskontrolleuren. Verschaffen Sie sich einen Überblick über unser Angebot an Inhalten nach Thema und Funktion.
Die Kamer van Koophandel setzt Maßstäbe für entwicklergesteuerte Sicherheit in großem Maßstab
Die Kamer van Koophandel berichtet, wie sie sicheres Codieren durch rollenbasierte Zertifizierungen, Trust Score-Benchmarking und eine Kultur der gemeinsamen Verantwortung für Sicherheit in die tägliche Entwicklungsarbeit integriert hat.
Bedrohungsmodellierung mit KI: So wird jeder Entwickler zum Bedrohungsmodellierer
Sie werden besser gerüstet sein, um Entwicklern dabei zu helfen, Ideen und Techniken zur Bedrohungsmodellierung mit den KI-Tools zu kombinieren, die sie bereits verwenden, um die Sicherheit zu erhöhen, die Zusammenarbeit zu verbessern und von Anfang an widerstandsfähigere Software zu entwickeln.
Ressourcen für den Einstieg
Cybermon ist zurück: Die KI-Missionen von Beat the Boss sind jetzt auf Abruf verfügbar.
Cybermon 2025 Beat the Boss ist jetzt das ganze Jahr über bei SCW verfügbar. Implementieren Sie fortschrittliche KI- und LLM-Sicherheitsherausforderungen, um die sichere Entwicklung von KI in großem Maßstab zu stärken.
Erläuterung des Gesetzes zur Cyberresilienz: Was bedeutet es für die Entwicklung sicherer Software?
Entdecken Sie, was das EU-Gesetz zur Cyberresilienz (CRA) verlangt, für wen es gilt und wie sich Ingenieurteams mit sicheren Designpraktiken, der Vermeidung von Schwachstellen und der Entwicklung von Fähigkeiten für Entwickler darauf vorbereiten können.
SCW feiert sein 11-jähriges Bestehen: eine Lektion in Echtzeit über Anpassungsfähigkeit und kontinuierliche Verbesserung
2025 war ein großartiges Jahr für KI, Cybersicherheit und SCW. Ich gehe mit ruhiger Zuversicht und dem Optimismus, den nur harte und lohnende Arbeit mit sich bringen kann, auf das Jahr 2026 zu.




%20(1).avif)
.avif)
