Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Расписание входит ли дата / 14 сообщений из 14, страница 1 из 1
20.01.2018, 15:17
    #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
20.01.2018, 15:41
    #39587532
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расписание входит ли дата
У вас бизнеслогика перемешана с проверками на null и копипастой.
Поэтому понять решительно ничего не возможно.
1. Уберите скопированные куски кода.
2. Отделите бизнес-логику (от что вы действительно хотите сделать) от проверок на null.
3. Дайте переменным осмысленные имена.
...
Рейтинг: 0 / 0
21.01.2018, 02:22
    #39587719
-=Koba=-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расписание входит ли дата
BlazkowiczУ вас бизнеслогика перемешана с проверками на null и копипастой.
Поэтому понять решительно ничего не возможно.
1. Уберите скопированные куски кода.
2. Отделите бизнес-логику (от что вы действительно хотите сделать) от проверок на null.
3. Дайте переменным осмысленные имена.

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

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


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

А с вопросом моим...
...
Рейтинг: 0 / 0
22.01.2018, 21:26
    #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
22.01.2018, 22:31
    #39588727
andreykaT
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расписание входит ли дата
сорян, а чеб в обоих полях локалдейттайм не заюзать? или байты экономите? (хотя, не уверен)
...
Рейтинг: 0 / 0
22.01.2018, 23:07
    #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
22.01.2018, 23:09
    #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
23.01.2018, 10:56
    #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
23.01.2018, 11:08
    #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
23.01.2018, 11:53
    #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
23.01.2018, 15:25
    #39589218
Usman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Расписание входит ли дата
-=Koba=-Если не входит, то нужна функция, которая вернет следующую ближайшую датуздесь нужно уточнить
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Расписание входит ли дата / 14 сообщений из 14, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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