Development Class Java

//package jsslib.util;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
/**
 * Dieses Objekt repräsentiert einen Zeitraum
 * 
 * @author Robert Schuster
 */
public class TimePeriod implements Serializable {
  private static final long serialVersionUID = 814416355886171850L;
  public GregorianCalendar from;
  public GregorianCalendar to;
  // Konstanten für der Typ des Zeitraums
  public final static int TODAY = 0;
  public final static int YESTERDAY = 1;
  public final static int THIS_WEEK = 2;
  public final static int LAST_WEEK = 3;
  public final static int THIS_MONTH = 4;
  public final static int LAST_MONTH = 5;
  public final static int THIS_JEAR = 6;
  public final static int LAST_JEAR = 7;
  public final static int EVER = 8;
  public int typ = -1;
  public int from_typ = -1;
  public int to_typ = -1;
  // Ein Tag in Millisekunden:
  public final static long ONE_DAY = 86400000L;
  // One hour in ms
  public final static long ONE_HOUR = 3600000L;
  // One minute in ms
  public final static long ONE_MIN = 60000L;
  /**
   * Ohne einen Parameter wird von und bis auf jetzt gesetzt
   */
  public TimePeriod() {
    from = new GregorianCalendar();
    to = new GregorianCalendar();
  }
  /**
   * Von und bis werden auf einen Zeitraum gesetzt, der durch den typ bestimmt
   * ist
   * 
   * @param typ
   *            siehe Konstanten!
   */
  public TimePeriod(int typ) {
    this.typ = typ;
    this.from_typ = typ;
    this.to_typ = typ;
    setFromTyp(typ);
    setToTyp(typ);
  }
  /**
   * Setzt den von-Wert auf einen der Standard-Typen
   * 
   * @param neuertyp
   */
  public void setFromTyp(int neuertyp) {
    this.from_typ = neuertyp;
    if (from_typ != to_typ)
      typ = -1;
    else
      typ = neuertyp;
    switch (neuertyp) {
    case TODAY:
      from = new GregorianCalendar();
      setMidnight(from);
      break;
    case YESTERDAY:
      from = new GregorianCalendar();
      setMidnight(from);
      from.setTimeInMillis(from.getTimeInMillis() - ONE_DAY);
      break;
    case THIS_WEEK:
      from = new GregorianCalendar();
      setMidnight(from);
      int day_of_week = from.get(Calendar.DAY_OF_WEEK);
      // unsere Woche beginnt am Montag. Montag hat den Wert 2
      int day_offset_von;
      // wenn es sonntag ist, wird die zurück liegende woche betrachtet
      if (day_of_week == 1) {
        day_offset_von = -6;
      } else {
        day_offset_von = 2 - day_of_week;
      }
      // bis ist logischerweise 6-Tage nach von
      from.setTimeInMillis(from.getTimeInMillis() + ONE_DAY
          * day_offset_von);
      break;
    case LAST_WEEK:
      // wie diese woche, nur 7 tage weiter zurück
      from = new GregorianCalendar();
      setMidnight(from);
      int day_of_week2 = from.get(Calendar.DAY_OF_WEEK);
      // unsere Woche beginnt am Montag. Montag hat den Wert 2
      int day_offset_von2;
      // wenn es sonntag ist, wird die zurück liegende woche betrachtet
      if (day_of_week2 == 1) {
        day_offset_von2 = -13;
      } else {
        day_offset_von2 = -5 - day_of_week2;
      }
      from.setTimeInMillis(from.getTimeInMillis() + ONE_DAY
          * day_offset_von2);
      break;
    case THIS_MONTH:
      from = new GregorianCalendar();
      setMidnight(from);
      from.set(Calendar.DAY_OF_MONTH, 1);
      break;
    case LAST_MONTH:
      from = new GregorianCalendar();
      setMidnight(from);
      from.set(Calendar.DAY_OF_MONTH, 1);
      // der erste tag des letzten Monats ist vielleicht nicht mehr in
      // diesem Jahr, also
      // rückwärts laufen, bis wieder ein erster Tag gefunden wird
      from.setTimeInMillis(from.getTimeInMillis() - ONE_DAY);
      while (from.get(Calendar.DAY_OF_MONTH) != 1)
        from.setTimeInMillis(from.getTimeInMillis() - ONE_DAY);
      break;
    case THIS_JEAR:
      from = new GregorianCalendar();
      setMidnight(from);
      from.set(Calendar.DAY_OF_MONTH, 1);
      from.set(Calendar.MONTH, 0);
      break;
    case LAST_JEAR:
      from = new GregorianCalendar();
      int jahr = from.get(Calendar.YEAR);
      jahr--;
      setMidnight(from);
      from.set(Calendar.DAY_OF_MONTH, 1);
      from.set(Calendar.MONTH, 0);
      from.set(Calendar.YEAR, jahr);
      break;
    case EVER:
      from = new GregorianCalendar();
      int jahr2 = from.get(Calendar.YEAR);
      setMidnight(from);
      from.set(2000, 0, 1, 0, 0, 0);
      break;
    }
    // Von darf nicht nach bis liegen, ist bis schon initialisiert, so muss
    // es angepasst werden
    if (to != null)
      if (to.before(from)) {
        to.setTimeInMillis(from.getTimeInMillis());
        set2359(to);
        if (from_typ == TODAY)
          to_typ = TODAY;
      }
  }
  /**
   * Setzt den bis-Wert auf einen der Standard-Typen
   * 
   * @param neuertyp
   */
  public void setToTyp(int neuertyp) {
    this.to_typ = neuertyp;
    if (from_typ != to_typ)
      typ = -1;
    else
      typ = neuertyp;
    switch (neuertyp) {
    case TODAY:
      to = new GregorianCalendar();
      set2359(to);
      break;
    case YESTERDAY:
      to = new GregorianCalendar();
      set2359(to);
      to.setTimeInMillis(to.getTimeInMillis() - ONE_DAY);
      break;
    case THIS_WEEK:
      to = new GregorianCalendar();
      int day_of_week = to.get(Calendar.DAY_OF_WEEK);
      // unsere Woche beginnt am Montag. Montag hat den Wert 2
      int day_offset_von;
      // wenn es sonntag ist, wird die zurück liegende woche betrachtet
      if (day_of_week == 1) {
        day_offset_von = -6;
      } else {
        day_offset_von = 2 - day_of_week;
      }
      // bis ist logischerweise 6-Tage nach von
      int day_offset_bis = day_offset_von + 6;
      set2359(to);
      to.setTimeInMillis(to.getTimeInMillis() + ONE_DAY * day_offset_bis);
      break;
    case LAST_WEEK:
      // wie diese woche, nur 7 tage weiter zurück
      to = new GregorianCalendar();
      int day_of_week2 = to.get(Calendar.DAY_OF_WEEK);
      // unsere Woche beginnt am Montag. Montag hat den Wert 2
      int day_offset_von2;
      // wenn es sonntag ist, wird die zurück liegende woche betrachtet
      if (day_of_week2 == 1) {
        day_offset_von2 = -13;
      } else {
        day_offset_von2 = -5 - day_of_week2;
      }
      // bis ist logischerweise 6-Tage nach von
      int day_offset_bis2 = day_offset_von2 + 6;
      set2359(to);
      to.setTimeInMillis(to.getTimeInMillis() + ONE_DAY * day_offset_bis2);
      break;
    case THIS_MONTH:
      GregorianCalendar temp = new GregorianCalendar();
      setMidnight(temp);
      temp.set(Calendar.DAY_OF_MONTH, 1);
      to = new GregorianCalendar();
      set2359(to);
      // wann der letzte tag im monat ist ist unklar, also solange weiter
      // gehen,
      // bis der neue monat anfängt, dann einen tag zurück
      while (to.get(Calendar.MONTH) == temp.get(Calendar.MONTH))
        to.setTimeInMillis(to.getTimeInMillis() + ONE_DAY);
      // Jetzt wieder einen tag zurück
      to.setTimeInMillis(to.getTimeInMillis() - ONE_DAY);
      break;
    case LAST_MONTH:
      GregorianCalendar temp2 = new GregorianCalendar();
      setMidnight(temp2);
      temp2.set(Calendar.DAY_OF_MONTH, 1);
      // der erste tag des letzten Monats ist vielleicht nicht mehr in
      // diesem Jahr, also
      // rückwärts laufen, bis wieder ein erster Tag gefunden wird
      temp2.setTimeInMillis(temp2.getTimeInMillis() - ONE_DAY);
      to = new GregorianCalendar();
      to.setTimeInMillis(temp2.getTimeInMillis());
      set2359(to);
      break;
    case THIS_JEAR:
      to = new GregorianCalendar();
      set2359(to);
      to.set(Calendar.MONTH, 11);
      to.set(Calendar.DAY_OF_MONTH, 31);
      break;
    case LAST_JEAR:
      to = new GregorianCalendar();
      int jahr = to.get(Calendar.YEAR);
      jahr--;
      set2359(to);
      to.set(Calendar.MONTH, 11);
      to.set(Calendar.DAY_OF_MONTH, 31);
      to.set(Calendar.YEAR, jahr);
      break;
    case EVER:
      to = new GregorianCalendar();
      int jahr2 = to.get(Calendar.YEAR);
      set2359(to);
      to.set(Calendar.MONTH, 11);
      to.set(Calendar.DAY_OF_MONTH, 31);
      to.set(Calendar.YEAR, jahr2);
      break;
    }
    // Von darf nicht nach bis liegen, ist bis schon initialisiert, so muss
    // es angepasst werden
    if (from != null)
      if (to.before(from)) {
        from.setTimeInMillis(to.getTimeInMillis());
        setMidnight(from);
        from_typ = to_typ;
      }
  }
  /**
   * Erniedrigt den Von-Wert um einen Tag und prüft, ob es sich dabei dann um
   * heute handelt.
   */
  public void setFromMinusOneDay() {
    from.setTimeInMillis(from.getTimeInMillis() - ONE_DAY);
    GregorianCalendar heute = new GregorianCalendar();
    setMidnight(heute);
    if (from.getTimeInMillis() == heute.getTimeInMillis())
      from_typ = TODAY;
    else
      from_typ = -1;
    if (to.before(from)) {
      to.setTimeInMillis(from.getTimeInMillis());
      set2359(to);
      to_typ = from_typ;
    }
  }
  /**
   * Erhöht den Von-Wert um einen Tag und prüft, ob es sich dabei dann um
   * heute handelt.
   */
  public void setFromPlusOneDay() {
    from.setTimeInMillis(from.getTimeInMillis() + ONE_DAY);
    GregorianCalendar heute = new GregorianCalendar();
    setMidnight(heute);
    if (from.getTimeInMillis() == heute.getTimeInMillis())
      from_typ = TODAY;
    else
      from_typ = -1;
    // Bis darf nicht vor von liegen! Falls es doch der Fall sein sollte,
    // wird auch bis angepasst
    if (to.before(from)) {
      to.setTimeInMillis(from.getTimeInMillis());
      set2359(to);
      to_typ = from_typ;
    }
  }
  /**
   * Erniedrigt den Von-Wert um einen Tag und prüft, ob es sich dabei dann um
   * heute handelt.
   */
  public void setToMinusOneDay() {
    to.setTimeInMillis(to.getTimeInMillis() - ONE_DAY);
    GregorianCalendar heute = new GregorianCalendar();
    set2359(heute);
    if (to.getTimeInMillis() == heute.getTimeInMillis())
      to_typ = TODAY;
    else
      to_typ = -1;
    // Bis darf nicht vor von liegen! Falls es doch der Fall sein sollte,
    // wird auch von angepasst
    if (to.before(from)) {
      from.setTimeInMillis(to.getTimeInMillis());
      setMidnight(from);
      from_typ = to_typ;
    }
  }
  /**
   * Erhöht den Von-Wert um einen Tag und prüft, ob es sich dabei dann um
   * heute handelt.
   */
  public void setToPlusOneDay() {
    to.setTimeInMillis(to.getTimeInMillis() + ONE_DAY);
    GregorianCalendar heute = new GregorianCalendar();
    set2359(heute);
    if (to.getTimeInMillis() == heute.getTimeInMillis())
      to_typ = TODAY;
    else
      to_typ = -1;
    // Bis darf nicht vor von liegen! Falls es doch der Fall sein sollte,
    // wird auch von angepasst
    if (to.before(from)) {
      from.setTimeInMillis(to.getTimeInMillis());
      setMidnight(from);
    }
  }
  /**
   * Setzt die Uhr des Übergebenen Kalenders auf 00:00:00:000
   * 
   * @param cal
   */
  public void setMidnight(GregorianCalendar cal) {
    cal.set(Calendar.HOUR_OF_DAY, 0);
    cal.set(Calendar.MINUTE, 0);
    cal.set(Calendar.SECOND, 0);
    cal.set(Calendar.MILLISECOND, 0);
  }
  /**
   * Setzt die Uhr des Übergebenen Kalenders auf 23:59:59:999
   * 
   * @param cal
   */
  public void set2359(GregorianCalendar cal) {
    cal.set(Calendar.HOUR_OF_DAY, 23);
    cal.set(Calendar.MINUTE, 59);
    cal.set(Calendar.SECOND, 59);
    cal.set(Calendar.MILLISECOND, 999);
  }
  /**
   * Gibt das Datum des von-Objekts als String zurück
   * 
   * @return Format:
   */
  public String getFromString() {
    if (from == null)
      return "null";
    SimpleDateFormat formater = new SimpleDateFormat("dd.MM.yyyy HH:mm");
    return formater.format(from.getTime());
  }
  /**
   * Gibt das Datum des von-Objekts als String zurück
   * 
   * @return Format:
   */
  public String getToString() {
    if (to == null)
      return "null";
    SimpleDateFormat formater = new SimpleDateFormat("dd.MM.yyyy HH:mm");
    return formater.format(to.getTime());
  }
  public String getFromToTimeOfDayString() {
    if (to == null || from == null)
      return "null";
    SimpleDateFormat formater = new SimpleDateFormat("HH:mm");
    return formater.format(from.getTime()) + " - "
        + formater.format(to.getTime());
  }
  /**
   * Gibt das Von-Datum in der Formatierung für die Datenbank zurück
   * 
   * @return 'yyyy-MM-dd HH:mm:ss'
   */
  public String getDatabaseFromString() {
    if (from == null)
      return "0000-01-01 00:00:00";
    SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    return "'" + formater.format(from.getTime()) + "'";
  }
  /**
   * Gibt das Bis-Datum in der Formatierung für die Datenbank zurück
   * 
   * @return 'yyyy-MM-dd HH:mm:ss'
   */
  public String getDatabaseToString() {
    if (to == null)
      return "0000-01-01 00:00:00";
    SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    return "'" + formater.format(to.getTime()) + "'";
  }
  /**
   * Gibt die den Zeitabstand zwischen von und bis in Millisekunden zurück
   * 
   * @return
   */
  public long getDurationInMillis() {
    return to.getTimeInMillis() - from.getTimeInMillis();
  }
  /**
   * Gibt die den Zeitabstand zwischen von und bis in Minuten zurück
   * 
   * @return
   */
  public int getDurationInMinutes() {
    return (int) ((to.getTimeInMillis() - from.getTimeInMillis()) / 60000);
  }
  public int getDurationInDays() {
    int ergebnis = 0;
    int bistag = (int) (to.getTimeInMillis() / ONE_DAY);
    int vontag = (int) (from.getTimeInMillis() / ONE_DAY);
    ergebnis = bistag - vontag + 1;
    return ergebnis;
  }
  /**
   * Kürzt den zeitraum, so das nur ganze Monate übrig bleiben
   */
  public void setOnlyCompleteMonth() {
    // Auf den Beginn des nächsten monats setzen
    if (from.get(Calendar.DAY_OF_MONTH) != 1) {
      while (from.get(Calendar.DAY_OF_MONTH) != 1) {
        from.setTimeInMillis(from.getTimeInMillis() + ONE_DAY);
      }
      setMidnight(from);
    }
    // Auf das Ende des Vorherigen Monats setzen
    GregorianCalendar temp = new GregorianCalendar();
    temp.setTimeInMillis(to.getTimeInMillis() + ONE_DAY);
    if (temp.get(Calendar.MONTH) == to.get(Calendar.MONTH)) {
      while (to.get(Calendar.MONTH) == temp.get(Calendar.MONTH)) {
        to.setTimeInMillis(to.getTimeInMillis() - ONE_DAY);
      }
      set2359(to);
    }
  }
  /**
   * Gibt die Anzahl der Monate zurück, dabei wird aufgerundet
   * 
   * @return anzahl der angefangenen Monate, also die Monate, die einen Anteil
   *         an diesem Zeitraum haben
   */
  public int getDurationInMonth() {
    int ergebnis = 0;
    int startmonat = from.get(GregorianCalendar.MONTH);
    int startjahr = from.get(GregorianCalendar.YEAR);
    int endmonat = to.get(GregorianCalendar.MONTH);
    int endjahr = to.get(GregorianCalendar.YEAR);
    int start = startjahr * 12 + startmonat;
    int ende = endjahr * 12 + endmonat;
    ergebnis = ende - start + 1;
    return ergebnis;
  }
  /**
   * gibt von_bis-Objekte zurück, die die an diesem Zeitraum beteiligten
   * Monate enthalten
   * 
   * @return
   */
  public ArrayList getMonth() {
    ArrayList ergebnis = new ArrayList();
    int anzahl = getDurationInMonth();
    int startmonat = from.get(GregorianCalendar.MONTH);
    int startjahr = from.get(GregorianCalendar.YEAR);
    for (int i = 0; i < anzahl; i++) {
      TimePeriod temp = new TimePeriod();
      temp.setMidnight(temp.from);
      // temp.set2359(temp.bis);
      temp.from.set(Calendar.MONTH, startmonat);
      temp.from.set(Calendar.YEAR, startjahr);
      temp.from.set(Calendar.DAY_OF_MONTH, 1);
      temp.to.set(Calendar.MONTH, startmonat);
      temp.to.set(Calendar.YEAR, startjahr);
      temp.to.set(Calendar.DAY_OF_MONTH, 28);
      // wann der letzte tag im monat ist ist unklar, also solange weiter
      // gehen,
      // bis der neue monat anfängt, dann einen tag zurück
      while (temp.to.get(Calendar.MONTH) == temp.from.get(Calendar.MONTH))
        temp.to.setTimeInMillis(temp.to.getTimeInMillis() + ONE_DAY);
      // Jetzt wieder einen tag zurück
      temp.to.setTimeInMillis(temp.to.getTimeInMillis() - ONE_DAY);
      temp.set2359(temp.to);
      // Fertig! den Monat in die ArrayListe einfügen
      ergebnis.add(temp);
      // weiter zum nächsten Monat
      startmonat++;
      if (startmonat == 12) {
        startmonat = 0;
        startjahr++;
      }
    }
    return ergebnis;
  }
  /**
   * Gibt zurück, wie oft der übergebene Wochentag im Zeitraum vorkommt.
   * 
   * @param wochentag
   *            Sonntag = 1
   * @return
   */
  public int getNumberOfWeekdays(int wochentag) {
    int ergebnis = 0;
    GregorianCalendar temp = new GregorianCalendar();
    temp.setTime(from.getTime());
    // Schleife über alle Tage
    int aktuellerTag;
    while (temp.before(to)) {
      aktuellerTag = temp.get(Calendar.DAY_OF_WEEK);
      if (aktuellerTag == wochentag)
        ergebnis++;
      temp.setTimeInMillis(temp.getTimeInMillis() + ONE_DAY);
    }
    return ergebnis;
  }
}