powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Расписание входит ли дата
14 сообщений из 14, страница 1 из 1
Расписание входит ли дата
    #39587523
Фотография -=Koba=-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть scheduler DTO

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
@Data
public class Schedule implements Serializable {
...
  private LocalTime time;
  private LocalTime endTime;
  private LocalDate date;
  private int[] days;
...
}



Пример документа из монги
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
  {
    "time": "2018-01-18T00:06:26.000",
    "endTime": "2018-01-18T23:56:26.000",
    "days": [
      1,
      2,
      5,
      6,
      7
    ]
  }




Мне надо проверить входит ли текущая дата в заданный диапозон

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
   */
  public static boolean isScheduledTime(ScheduleEntity schedule, TimeZone timezone) {
    ZoneId zoneId = timezone.toZoneId();
    ZonedDateTime now = ZonedDateTime.now(zoneId);

    ZonedDateTime startTime = schedule.getTime() != null ? ZonedDateTime.of(ZonedDateTime.now(zoneId)
        .toLocalDate(), schedule.getTime(), zoneId) : null;
    ZonedDateTime endTime = schedule.getEndTime() != null ? ZonedDateTime.of(ZonedDateTime.now(zoneId)
        .toLocalDate(), schedule.getEndTime(), zoneId) : null;

    for (int day : schedule.getDays()) {
      if (now.getDayOfWeek() == DayOfWeek.of(day)) {
        return isTime(now, startTime, endTime);
      }
    }
  }

  private static boolean isTime(ZonedDateTime date1, ZonedDateTime date2, ZonedDateTime date3) {
    long diff = MINUTES.between(date1, date2);
    return date3 == null ? (date1.isAfter(date2) || date1.isEqual(date2)) && (diff == 0)
        : (date1.isAfter(date2) || date1.isEqual(date2)) && (date1.isBefore(date3) || date1.isEqual(date3));
  }




Код: java
1.
2.
Вызов
isScheduledTime(scheduleEntity, Calendar.getInstance().getTimeZone())



Если не входит, то нужна функция, которая вернет следующую ближайшую дату


Как выше код можно упростить
И возвращать дату следующую дату

Запутался с временными зонами
...
Рейтинг: 0 / 0
Расписание входит ли дата
    #39587532
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У вас бизнеслогика перемешана с проверками на null и копипастой.
Поэтому понять решительно ничего не возможно.
1. Уберите скопированные куски кода.
2. Отделите бизнес-логику (от что вы действительно хотите сделать) от проверок на null.
3. Дайте переменным осмысленные имена.
...
Рейтинг: 0 / 0
Расписание входит ли дата
    #39587719
Фотография -=Koba=-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BlazkowiczУ вас бизнеслогика перемешана с проверками на null и копипастой.
Поэтому понять решительно ничего не возможно.
1. Уберите скопированные куски кода.
2. Отделите бизнес-логику (от что вы действительно хотите сделать) от проверок на null.
3. Дайте переменным осмысленные имена.

А где делать проверку на наш?
...
Рейтинг: 0 / 0
Расписание входит ли дата
    #39587721
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-=Koba=-BlazkowiczУ вас бизнеслогика перемешана с проверками на null и копипастой.
Поэтому понять решительно ничего не возможно.
1. Уберите скопированные куски кода.
2. Отделите бизнес-логику (от что вы действительно хотите сделать) от проверок на null.
3. Дайте переменным осмысленные имена.

А где делать проверку на наш?Валидация сущностей или DTO-шек.
Либо Assert-ы - будет намного читабельнее.
...
Рейтинг: 0 / 0
Расписание входит ли дата
    #39587989
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Usman-=Koba=-пропущено...


А где делать проверку на наш?Валидация сущностей или DTO-шек.
Либо Assert-ы - будет намного читабельнее.
Вы его щас еще больше запутаете. Он полезет гуглить ассерты и найдет java asserts. А надо
guava asserts или что-то такое.
...
Рейтинг: 0 / 0
Расписание входит ли дата
    #39588683
Фотография -=Koba=-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я с валидацией я понял, вынесу

А с вопросом моим...
...
Рейтинг: 0 / 0
Расписание входит ли дата
    #39588696
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-=Koba=-,

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
ZonedDateTime now = ZonedDateTime.now();
now = now.withZoneSameInstant(ZoneId.of("Africa/Nairobi"));

ZonedDateTime dt = now.plus(1, ChronoUnit.MICROS);
dt = dt.withZoneSameInstant(ZoneId.of("Europe/Moscow"));

ZonedDateTime dtLeft = now;
ZonedDateTime dtRight = dtLeft.plus(10, ChronoUnit.DAYS);

//dtLeft = dtLeft.withZoneSameInstant(dt.getZone());
//dtRight = dtRight.withZoneSameInstant(dt.getZone());

if (dt.isAfter(dtLeft) && dt.isBefore(dtRight)) {
    System.out.printf("%s <= %s <= %s%n", dtLeft, dt, dtRight);
}

Вывод:
Код: java
1.
2018-01-22T21:24:25.668+03:00[Africa/Nairobi] <= 2018-01-22T21:24:25.668001+03:00[Europe/Moscow] <= 2018-02-01T21:24:25.668+03:00[Africa/Nairobi]
...
Рейтинг: 0 / 0
Расписание входит ли дата
    #39588727
andreykaT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сорян, а чеб в обоих полях локалдейттайм не заюзать? или байты экономите? (хотя, не уверен)
...
Рейтинг: 0 / 0
Расписание входит ли дата
    #39588739
Фотография -=Koba=-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Переделал немного, можно ли уменьшить?

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
  public static boolean checkDailyInterval(ScheduleEntity scheduleEntity, ZonedDateTime now) {
    checkNotNull(scheduleEntity.getStartTime());
    checkNotNull(scheduleEntity.getEndTime());

    List<LocalDate> week = datesOfWeekDate(now.toLocalDate(), scheduleEntity.getDays());

    for (LocalDate localDate : week) {
      ZonedDateTime zoneStartTime = ZonedDateTime.of(localDate, scheduleEntity.getStartTime(), now.getZone());
      ZonedDateTime zoneEndTime = ZonedDateTime.of(localDate, scheduleEntity.getEndTime(), now.getZone());
      if (now.isAfter(zoneStartTime) && now.isBefore(zoneEndTime)) {
        return true;
      }
    }

    return false;
  }

  private static List<LocalDate> datesOfWeekDate(LocalDate date, int[] days) {
    LocalDate monday = date.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
    IntStream daysStream = Arrays.stream(days);
    return daysStream.mapToObj(day -> monday.plusDays(day - 1))
        .collect(Collectors.toList());
  }

  public static ZonedDateTime getTimeZoneNow(DeviceTimezone userTimeZone) {
    ZoneId zoneId = ZoneId.of(userTimeZone.getValue());
    return ZonedDateTime.now(zoneId);
  }
...
Рейтинг: 0 / 0
Расписание входит ли дата
    #39588741
Фотография -=Koba=-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreykaTсорян, а чеб в обоих полях локалдейттайм не заюзать? или байты экономите? (хотя, не уверен)

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
  {
    "time": "2018-01-18T00:06:26.000",
    "endTime": "2018-01-18T23:56:26.000",
    "days": [
      1,
      2,
      5,
      6,
      7
    ]
  }



Логика такая была заложена
days день недели, time время

соответственно получается комбинация
Каждый понедельник с .. по ..
Каждый вторник с .. по ..
Каждая пятница с .. по ..
Каждая суббота с .. по ..
Каждое воскресенье с .. по ..
...
Рейтинг: 0 / 0
Расписание входит ли дата
    #39588923
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-=Koba=-
Код: java
1.
2.
3.
4.
5.
6.
      //В наши дни без копипасты никуда.
      ZonedDateTime zoneStartTime = ZonedDateTime.of(localDate, scheduleEntity.getStartTime(), now.getZone());
      //В наши дни без копипасты никуда.
      ZonedDateTime zoneEndTime = ZonedDateTime.of(localDate, scheduleEntity.getEndTime(), now.getZone());
      //Если сложное условие вынести в переменную или метод с осмысленным именем, то читаться будет лучше
      if (now.isAfter(zoneStartTime) && now.isBefore(zoneEndTime)) {
...
Рейтинг: 0 / 0
Расписание входит ли дата
    #39588929
Фотография -=Koba=-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо еще вопрос мне надо получать следующую дату из расписания, если текущая не попадает в диапазон

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
  public static Entry<LocalDateTime, LocalDateTime> getNextkDailyInterval(ScheduleEntity scheduleEntity,
      ZonedDateTime now) {
    checkNotNull(scheduleEntity.getStartTime());
    checkNotNull(scheduleEntity.getEndTime());

    LocalDateTime nowDateTime = now.toLocalDateTime();
    int[] days = scheduleEntity.getDays();
    if (days.length > 0) {
      List<Integer> dayList = Arrays.stream(days)
          .sorted()
          .boxed()
          .collect(Collectors.toList());
      dayList.add(dayList.get(0) + 7);
      days = dayList.stream()
          .mapToInt(i -> i)
          .toArray();

      List<LocalDate> week = datesOfWeekDate(now.toLocalDate(), days);
      for (LocalDate localDate : week) {
        LocalDateTime localStartDateTime = LocalDateTime.of(localDate, scheduleEntity.getStartTime());
        LocalDateTime localEndDateTime = LocalDateTime.of(localDate, scheduleEntity.getEndTime());
        if (nowDateTime.isBefore(localStartDateTime) && nowDateTime.isBefore(localEndDateTime)) {
          return new SimpleEntry<>(localStartDateTime, localEndDateTime);
        }
      }
    }
    return new SimpleEntry<>(nowDateTime, nowDateTime);
  }


Приходится в массив days добавлять еще неделю если текущая дата превышает последнюю в расписании
От этого можно избавиться?
...
Рейтинг: 0 / 0
Расписание входит ли дата
    #39589000
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-=Koba=-
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
      //Это, извинит, пипец какой-то. 
      List<Integer> dayList = Arrays.stream(days)
          .sorted()
          .boxed()
          .collect(Collectors.toList());


      //Что за магические констаны? Почему именно 7?
      dayList.add(dayList.get(0) + 7);
      
      //Продолжаю плакать над явным боксингом.
      days = dayList.stream()
          .mapToInt(i -> i)
          .toArray();

      List<LocalDate> week = datesOfWeekDate(now.toLocalDate(), days);
      for (LocalDate localDate : week) {
        //Почему не назвать переменные просто start и end? Нахрена столько мусора??
        LocalDateTime localStartDateTime = LocalDateTime.of(localDate, scheduleEntity.getStartTime());
        //Почему бы в scheduleEntity не добавить метод, который сразу вернет LocalDateTime . Зачем все эти бесмыссленные преобразования?
        LocalDateTime localEndDateTime = LocalDateTime.of(localDate, scheduleEntity.getEndTime());
        //сделайте introduce variable или introduce method в условии
        if (nowDateTime.isBefore(localStartDateTime) && nowDateTime.isBefore(localEndDateTime)) { 
          return new SimpleEntry<>(localStartDateTime, localEndDateTime);
        }
      }
    }
    return new SimpleEntry<>(nowDateTime, nowDateTime);
  }



Из такого кода тяжело понять что именно хотел сказать автор. Куча бесмысленного мусора и ни слова из предметной области. Где-то далеко заплакал Robert C Martin.

Ваш метод должен содержать переменные и вызывать методы имена которых бы говорили что именно происходит. Он должен читаться как алгоритм записанный на английском языке. Достигается это путём использования переменных и методов вашего кода, а не только JSE.

Весь ваш код сводится вот к чему:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
public static Entry<LocalDateTime, LocalDateTime> getNextkDailyInterval(ScheduleEntity scheduleEntity) {
    validatePeriod(scheduleEntity);
    //Нахрена вообще мы сюда попали если дни пустые? Это тоже в валидацию.
    if (days.length > 0) {
      sort(days);
      addFirstDayIncreasedWith(days, 7);//Здесь нужно внятное имя метода которое бы объясняло что и почему мы делаем
      List<LocalDate> week = convertToWeekDates(days);//Тоже нужно имя из предметной области попонятнее 
      for (LocalDate localDate : week) {
        if (scheduleEntity.rangeIncludes(date)) {
          return new SimpleEntry<>(scheduleEntity);
        }
      }
    }
    return new SimpleEntry<>();
  }



Ещё вам везде приходится таскать за собой переменную now потому что метод у вас статический. Хотя гораздо проще было бы создать объект, записать туда now в поле в конструкторе и потом во всех методах использовать, а не захламлять код.
...
Рейтинг: 0 / 0
Расписание входит ли дата
    #39589218
Фотография Usman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
-=Koba=-Если не входит, то нужна функция, которая вернет следующую ближайшую датуздесь нужно уточнить
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Расписание входит ли дата
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]