如何移除Calendar类,改用LocalDateTime实现日期偏移功能?
Refactoring to Replace
Calendar with LocalDateTime Got it, let's fix this code to ditch the old Calendar class entirely and use Java 8+'s modern LocalDateTime API. The original code had a hidden compilation issue (you can't pass a LocalDateTime directly to Calendar.setTime()), so we'll clean that up while preserving every bit of your intended logic.
First, let's break down the original behavior we need to keep:
- Only process if
fechaDesdeisn'tnull - Apply a date offset based on the
tipoDesplazamiento(originally usingCalendarconstants likeCalendar.MONTH) - If the offset type is month, subtract an extra day after applying the main offset
- Return the modified date (or
nullif input isnull)
Here's the refactored code using only LocalDateTime:
import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; public static LocalDateTime obtenerDesplazamientoFecha(LocalDateTime fechaDesde, int tipoDesplazamiento, int desplazamiento) { if (fechaDesde == null) { return null; } // Map legacy Calendar constants to modern ChronoUnit types ChronoUnit offsetUnit = switch (tipoDesplazamiento) { case java.util.Calendar.YEAR -> ChronoUnit.YEARS; case java.util.Calendar.MONTH -> ChronoUnit.MONTHS; case java.util.Calendar.DAY_OF_MONTH -> ChronoUnit.DAYS; case java.util.Calendar.HOUR_OF_DAY -> ChronoUnit.HOURS; case java.util.Calendar.MINUTE -> ChronoUnit.MINUTES; case java.util.Calendar.SECOND -> ChronoUnit.SECONDS; // Add other Calendar constants here if your use case needs them default -> throw new IllegalArgumentException("Tipo de desplazamiento no soportado: " + tipoDesplazamiento); }; // Apply the main offset (LocalDateTime is immutable, so we get a new instance) LocalDateTime resultado = fechaDesde.plus(desplazamiento, offsetUnit); // Apply the extra day subtraction for month offsets (matches original logic) if (tipoDesplazamiento == java.util.Calendar.MONTH) { resultado = resultado.minus(1, ChronoUnit.DAYS); } return resultado; }
Key improvements & notes:
- No more
Calendarbloat: We useChronoUnit, the type-safe, modern replacement forCalendar's messy integer constants - Fixes compilation errors: The original code tried to pass
LocalDateTimetoCalendar.setTime()(which requires aDate), we eliminate this entirely - Immutability:
LocalDateTimedoesn't modify the original object—every operation returns a new instance, avoiding side effects - Clear error handling: The switch case throws a meaningful error if an unsupported offset type is passed
- 1:1 logic match: We keep the extra day subtraction for month offsets exactly as your original code intended
Bonus: Remove all Calendar references entirely
If you want to cut ties with Calendar completely, replace the integer tipoDesplazamiento parameter with a custom enum for better type safety:
public enum TipoDesplazamiento { YEAR, MONTH, DAY, HOUR, MINUTE, SECOND } public static LocalDateTime obtenerDesplazamientoFecha(LocalDateTime fechaDesde, TipoDesplazamiento tipoDesplazamiento, int desplazamiento) { if (fechaDesde == null) { return null; } ChronoUnit offsetUnit = switch (tipoDesplazamiento) { case YEAR -> ChronoUnit.YEARS; case MONTH -> ChronoUnit.MONTHS; case DAY -> ChronoUnit.DAYS; case HOUR -> ChronoUnit.HOURS; case MINUTE -> ChronoUnit.MINUTES; case SECOND -> ChronoUnit.SECONDS; }; LocalDateTime resultado = fechaDesde.plus(desplazamiento, offsetUnit); if (TipoDesplazamiento.MONTH == tipoDesplazamiento) { resultado = resultado.minus(1, ChronoUnit.DAYS); } return resultado; }
This makes the code self-documenting and prevents callers from passing invalid integer values.
内容的提问来源于stack exchange,提问作者Jose Gimeno
相关产品推荐
相关产品推荐

