java - Encontrar todas las fechas en que ocurre el evento

CorePress2024-01-16  11

Me dan una fecha de inicio de un evento cuyo formato es yyyy_mm_dd (de forma de cadena) y un entero no negativo n que denota el número de repeticiones del evento. Por ejemplo, si la fecha de inicio es 2020_3_12 y Tengo 3 repeticiones entonces el evento se realizará los días 2020_3_12 y 2020_3_19 y 2020_3_26 y 2020_4_3 (Repetición semanal). Continuamente me dan una fecha y tengo que determinar si la fecha tiene un evento de ese tipo o no, también la repetición puede cambian durante la ejecución del programa. Puedo simplemente almacenar las fechas válidas en una matriz o configurarlas y buscarlas, pero el problema es que encontrar todas las fechas requiere mucho trabajo (cuando tenemos que cambiar el mes o año al agregar 7 días) ¿Existe una buena manera de escapar de estos casos extremos? (Estoy buscando un javasolución. Gracias de antemano). ¿También hay una manera mejor de manejar esto para poder evitar reconstruir la matriz cada vez?



------------------------------------

Hay muchas maneras de lograr el resultado descrito:

String input = "2020_3_12";
int repeat = 3;

LocalDate start = LocalDate.parse(input, DateTimeFormatter.ofPattern("yyyy_M_dd"));

List<LocalDate> eventDates = new ArrayList<>();
for(int i = 0; i <= repeat; i++){
    eventDates.add(start.plusDays(7 * i));
}
System.out.println(eventDates);

Con las secuencias también puedes escribir el ejemplo superior de forma un poco más compacta

List<LocalDate> eventDates2 =  IntStream.rangeClosed(0, repeat)
                                        .mapToObj(i -> start.plusDays(i * 7))
                                        .collect(Collectors.toList());

System.out.println(eventDates2);

También puedes trabajar directamente con LocalDate en el bucle for en lugar de ints

List<LocalDate> eventDates3 = new ArrayList<>();
for(LocalDate date = start; date.isBefore(start.plusDays(repeat*7 +1)); date = date.plusDays(7)){
    eventDates3.add(date);
}

System.out.println(eventDates3);

3

Necesito que el mes tenga siempre dos dígitos. ¿Existe algún método para hacer esto con una pequeña modificación, especialmente para el primero, ya que estoy muy interesado en él?

- Taha Akbari

19/03/2021 a las 16:39

1

No estoy seguro de haberlo hecho bien. Si te refieres a DateTimeFormatter.ofPattern("yyyy_M_dd"), simplemente ajústalo de acuerdo con tu entrada. Si su entrada es como 2020_3_12 use "yyyy_M_dd" o si tiene una entrada como 2020_03_12, utilice "yyyy_MM_dd"

– Eritrea

19/03/2021 a las 16:46

1

Buena respuesta. Un pequeño detalle, no es necesario que hagas tu propia multiplicación por 7 ya que LocalDate tiene un método plusWeeks.

Anónimo

20/03/2021 a las 9:22



------------------------------------

Prueba este código:

    public static void main(String[] a) {
        //Declaration
        String pattern = "yyyy_MM_dd";
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        int n = 3;
        int step = 2;
        
        LocalDate startDate = LocalDate.parse("2021_03_19", formatter);
        
        //It is a incrementing count of days where day 0 is 1970-01-01
        long epochDay = startDate.toEpochDay();
        
        //Test
        LocalDate testDate = startDate;
        for (int i = 1; i <= 10; i++) {
            System.out.println("testDate: " + testDate);
            long offset = testDate.toEpochDay() - epochDay;
            boolean isValid = offset % step == 0 && offset / step < n;
            System.out.println("isValid:  " + isValid);
            testDate = testDate.plusDays(1);
            System.out.println("");
        }
    }

Salida:

testDate: 2021-03-19
isValid:  true

testDate: 2021-03-20
isValid:  false

testDate: 2021-03-21
isValid:  true

testDate: 2021-03-22
isValid:  false

testDate: 2021-03-23
isValid:  true

testDate: 2021-03-24
isValid:  false

testDate: 2021-03-25
isValid:  false

testDate: 2021-03-26
isValid:  false

testDate: 2021-03-27
isValid:  false

testDate: 2021-03-28
isValid:  false

1

Aunque probablemente sea correcto, creo que su código es más complicado de lo necesario.

Anónimo

20/03/2021 a las 9:20

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare