gt:             DateTime dt = date.toDateTimeAtStartOfDay();
context: /*
   *    Calendula - An assistant for personal medication management.
   *    Copyright (C) 2014-2018 CiTIUS - University of Santiago de Compostela
   *
   *    Calendula is free software; you can redistribute it and/or modify
   *    it under the terms of the GNU General Public License as published by
   *    the Free Software Foundation; either version 3 of the License, or
   *    (at your option) any later version.
   *
   *    This program is distributed in the hope that it will be useful,
   *    but WITHOUT ANY WARRANTY; without even the implied warranty of
   *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *    GNU General Public License for more details.
   *
   *    You should have received a copy of the GNU General Public License
   *    along with this software.  If not, see <http://www.gnu.org/licenses/>.
   */
  
  package es.usc.citius.servando.calendula.persistence;
  
  import android.content.Context;
  import android.text.format.Time;
  
  import com.codetroopers.betterpickers.recurrencepicker.EventRecurrence;
  import com.codetroopers.betterpickers.recurrencepicker.EventRecurrenceFormatter;
  import com.google.ical.values.DateValue;
  import com.google.ical.values.Frequency;
  import com.j256.ormlite.field.DatabaseField;
  import com.j256.ormlite.table.DatabaseTable;
  
  import org.joda.time.DateTime;
  import org.joda.time.LocalDate;
  import org.joda.time.LocalTime;
  
  import java.util.Arrays;
  import java.util.List;
  
  import es.usc.citius.servando.calendula.R;
  import es.usc.citius.servando.calendula.database.DB;
  import es.usc.citius.servando.calendula.persistence.typeSerializers.BooleanArrayPersister;
  import es.usc.citius.servando.calendula.persistence.typeSerializers.LocalDatePersister;
  import es.usc.citius.servando.calendula.persistence.typeSerializers.LocalTimePersister;
  import es.usc.citius.servando.calendula.persistence.typeSerializers.RRulePersister;
  import es.usc.citius.servando.calendula.scheduling.ScheduleUtils;
  import es.usc.citius.servando.calendula.util.LogUtil;
  import es.usc.citius.servando.calendula.util.ScheduleHelper;
  
  
  @DatabaseTable(tableName = "Schedules")
  public class Schedule {
  
      public static final int SCHEDULE_TYPE_EVERYDAY = 0; // DEFAULT
      public static final int SCHEDULE_TYPE_SOMEDAYS = 1;
      public static final int SCHEDULE_TYPE_INTERVAL = 2;
      public static final int SCHEDULE_TYPE_HOURLY = 4;
      public static final int SCHEDULE_TYPE_CYCLE = 5;
  
      public static final String COLUMN_ID = "_id";
      public static final String COLUMN_MEDICINE = "Medicine";
      public static final String COLUMN_DAYS = "Days";
      public static final String COLUMN_RRULE = "Rrule";
      public static final String COLUMN_START = "Start";
      public static final String COLUMN_START_TIME = "Starttime";
      public static final String COLUMN_DOSE = "Dose";
      public static final String COLUMN_TYPE = "Type";
      public static final String COLUMN_CYCLE = "Cycle";
      public static final String COLUMN_SCANNED = "Scanned";
      public static final String COLUMN_PATIENT = "Patient";
      public static final String COLUMN_STATE = "State";
      private static final String TAG = "Schedule";
  
      @DatabaseField(columnName = COLUMN_ID, generatedId = true)
      private Long id;
      @DatabaseField(columnName = COLUMN_MEDICINE, foreign = true, foreignAutoRefresh = true)
      private Medicine medicine;
      @DatabaseField(columnName = COLUMN_DAYS, persisterClass = BooleanArrayPersister.class)
      private boolean[] days = noWeekDays();
      @DatabaseField(columnName = COLUMN_RRULE, persisterClass = RRulePersister.class)
      private RepetitionRule rrule;
      @DatabaseField(columnName = COLUMN_START, persisterClass = LocalDatePersister.class)
      private LocalDate start;
      @DatabaseField(columnName = COLUMN_START_TIME, persisterClass = LocalTimePersister.class)
      private LocalTime startTime;
      @DatabaseField(columnName = COLUMN_DOSE)
      private float dose = 1f;
      @DatabaseField(columnName = COLUMN_TYPE)
      private int type = SCHEDULE_TYPE_EVERYDAY;
      @DatabaseField(columnName = COLUMN_CYCLE)
      private String cycle;
      @DatabaseField(columnName = COLUMN_SCANNED)
      private boolean scanned;
      @DatabaseField(columnName = COLUMN_PATIENT, foreign = true, foreignAutoRefresh = true)
      private Patient patient;
      @DatabaseField(columnName = COLUMN_STATE)
      private ScheduleState state;
  
      public Schedule() {
          rrule = new RepetitionRule(null);
      }
  
      public Schedule(Medicine medicine) {
          this.medicine = medicine;
      }
  
      public Schedule(Medicine medicine, boolean[] days) {
          this.medicine = medicine;
          setDays(days);
      }
  
      public static List<Schedule> findAll() {
          return DB.schedules().findAll();
      }
  
      public static List<Schedule> findByMedicine(Medicine med) {
          return DB.schedules().findByMedicine(med);
      }
  
      public static Schedule findById(long id) {
          return DB.schedules().findById(id);
      }
  
      public static final boolean[] noWeekDays() {
          return new boolean[]{false, false, false, false, false, false, false};
      }
  
      public static final boolean[] allWeekDays() {
          return new boolean[]{true, true, true, true, true, true, true};
      }
  
      public RepetitionRule rule() {
          return rrule;
      }
  
      public void setRepetition(RepetitionRule rrule) {
          this.rrule = rrule;
      }
  
      public int type() {
          return type;
      }
  
      public void setType(int type) {
          if (type < 0 || type > 5) {
              throw new RuntimeException("Invalid schedule type");
          }
          this.type = type;
      }
  
      public Long getId() {
          return id;
      }
  
      public void setId(Long id) {
          this.id = id;
      }
  
      public List<ScheduleItem> items() {
          return DB.scheduleItems().findBySchedule(this);
      }
  
      public List<DateTime> hourlyItemsToday() {
          DateTime today = DateTime.now().withTimeAtStartOfDay();
          // get schedule occurrences for the current day
          return rrule.occurrencesBetween(today, today.plusDays(1), startDateTime());
      }
  
      public List<DateTime> hourlyItemsAt(DateTime d) {
          DateTime date = d.withTimeAtStartOfDay();
          // get schedule occurrences for the current day
          return rrule.occurrencesBetween(date, date.plusDays(1), startDateTime());
      }
  
      public Medicine medicine() {
          return medicine;
      }
  
      public void setMedicine(Medicine medicine) {
          this.medicine = medicine;
      }
  
      public boolean[] days() {
          return rrule.getDays();
      }
  
      public void setDays(boolean[] days) {
          rrule.setDays(days);
      }
  
      public LocalDate start() {
          return start;
      }
  
      // *************************************
      // DB queries
      // *************************************
  
      public void setStart(LocalDate start) {
          this.start = start;
      }
  
      public float dose() {
          return dose;
      }
  
      public Patient patient() {
          return patient;
      }
  
      public void setPatient(Patient patient) {
          this.patient = patient;
      }
  
      public void setDose(float dose) {
          this.dose = dose;
      }
  
      public boolean enabledForDate(LocalDate date) {
  
          if (state == ScheduleState.BLOCKED)
              return false;
  
          if (type == SCHEDULE_TYPE_CYCLE) {
              return cycleEnabledForDate(date);
          } else {
  