All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.ical.iter.Util Maven / Gradle / Ivy

The newest version!
// Copyright (C) 2006 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.ical.iter;

import com.google.ical.util.DTBuilder;
import com.google.ical.values.Weekday;
import com.google.ical.values.WeekdayNum;
import com.google.ical.values.DateValue;

/**
 * a dumping ground for utility functions that don't fit anywhere else.
 *
 * @author [email protected] (Mike Samuel)
 */
class Util {

  /**
   * advances builder to the earliest day on or after builder that falls on
   * wkst.
   * @param builder non null.
   * @param wkst the day of the week that the week starts on
   */
  static void rollToNextWeekStart(DTBuilder builder, Weekday wkst) {
    DateValue bd = builder.toDate();
    builder.day += (7 - ((7 + (Weekday.valueOf(bd).javaDayNum
                               - wkst.javaDayNum))
                         % 7)) % 7;
    builder.normalize();
  }

  /**
   * the earliest day on or after d that falls on wkst.
   * @param wkst the day of the week that the week starts on
   */
  static DateValue nextWeekStart(DateValue d, Weekday wkst) {
    DTBuilder builder = new DTBuilder(d);
    builder.day += (7 - ((7 + (Weekday.valueOf(d).javaDayNum
                               - wkst.javaDayNum)) % 7))
                   % 7;
    return builder.toDate();
  }

  /** returns a sorted unique copy of ints. */
  static int[] uniquify(int[] ints) {
    return uniquify(ints, 0, ints.length);
  }

  /** returns a sorted unique copy of ints. */
  static int[] uniquify(int[] ints, int start, int end) {
    IntSet iset = new IntSet();
    for (int i = end; --i >= start;) {
      iset.add(ints[i]);
    }
    return iset.toIntArray();
  }

  /**
   * given a weekday number, such as -1SU, returns the day of the month that it
   * falls on.
   * The weekday number may be refer to a week in the current month in some
   * contexts or a week in the current year in other contexts.
   * @param dow0 the day of week of the first day in the current year/month.
   * @param nDays the number of days in the current year/month.
   *   In [28,29,30,31,365,366].
   * @param weekNum -1SU in the example above.
   * @param d0 the number of days between the 1st day of the current
   *   year/month and the current month.
   * @param nDaysInMonth the number of days in the current month.
   * @return 0 indicates no such day
   */
  static int dayNumToDate(Weekday dow0, int nDays, int weekNum,
                          Weekday dow, int d0, int nDaysInMonth) {
    // if dow is wednesday, then this is the date of the first wednesday
    int firstDateOfGivenDow = 1 + ((7 + dow.javaDayNum - dow0.javaDayNum) % 7);

    int date;
    if (weekNum > 0) {
      date = ((weekNum - 1) * 7) + firstDateOfGivenDow - d0;
    } else {  // count weeks from end of month
      // calculate last day of the given dow.
      // Since nDays <= 366, this should be > nDays
      int lastDateOfGivenDow = firstDateOfGivenDow + (7 * 54);
      lastDateOfGivenDow -= 7 * ((lastDateOfGivenDow - nDays + 6) / 7);
      date = lastDateOfGivenDow + 7 * (weekNum + 1) - d0;
    }
    if (date <= 0 || date > nDaysInMonth) { return 0; }
    return date;
  }

  /**
   * Compute an absolute week number given a relative one.
   * The day number -1SU refers to the last Sunday, so if there are 5 Sundays
   * in a period that starts on dow0 with nDays, then -1SU is 5SU.
   * Depending on where its used it may refer to the last Sunday of the year
   * or of the month.
   *
   * @param weekdayNum -1SU in the example above.
   * @param dow0 the day of the week of the first day of the week or month.
   *   One of the RRULE_WDAY_* constants.
   * @param nDays the number of days in the month or year.
   * @return an abolute week number, e.g. 5 in the example above.
   *   Valid if in [1,53].
   */
  static int invertWeekdayNum(
      WeekdayNum weekdayNum, Weekday dow0, int nDays) {
    assert weekdayNum.num < 0;
    // how many are there of that week?
    return countInPeriod(weekdayNum.wday, dow0, nDays) + weekdayNum.num + 1;
  }

  /**
   * the number of occurences of dow in a period nDays long where the first day
   * of the period has day of week dow0.
   */
  static int countInPeriod(Weekday dow, Weekday dow0, int nDays) {
    // Two cases
    //    (1a) dow >= dow0: count === (nDays - (dow - dow0)) / 7
    //    (1b) dow < dow0:  count === (nDays - (7 - dow0 - dow)) / 7
    if (dow.javaDayNum >= dow0.javaDayNum) {
      return 1 + ((nDays - (dow.javaDayNum - dow0.javaDayNum) - 1) / 7);
    } else {
      return 1 + ((nDays - (7 - (dow0.javaDayNum - dow.javaDayNum)) - 1) / 7);
    }
  }

  private Util() {
    // uninstantiable
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy