docs: public static Calendar previousInterval(final long ts, final int interval, 
        final int unit, final TimeZone tz) {
      if (ts < 0) {
        throw new IllegalArgumentException("Timestamp cannot be less than zero");
      }
      if (interval < 1) {
        throw new IllegalArgumentException("Interval must be greater than zero");
      }
      
      int unit_override = unit;
      int interval_override = interval;
      final Calendar calendar;
      if (tz == null) {
        calendar = Calendar.getInstance(timezones.get(UTC_ID));
      } else {
        calendar = Calendar.getInstance(tz);
      }
      
      switch (unit_override) {
      case Calendar.MILLISECOND:
        if (1000 % interval_override == 0) {
          calendar.setTimeInMillis(ts);
          calendar.set(Calendar.MILLISECOND, 0);
          if (interval_override > 1000) {
            calendar.add(Calendar.MILLISECOND, -interval_override);
          }
        } else {
          // from top of minute
          calendar.setTimeInMillis(ts);
          calendar.set(Calendar.MILLISECOND, 0);
          calendar.set(Calendar.SECOND, 0);
        }
        break;
      case Calendar.SECOND:
        if (60 % interval_override == 0) {
          calendar.setTimeInMillis(ts);
          calendar.set(Calendar.MILLISECOND, 0);
          calendar.set(Calendar.SECOND, 0);
          if (interval_override > 60) {
            calendar.add(Calendar.SECOND, -interval_override);
          }
        } else {
          // from top of hour
          calendar.setTimeInMillis(ts);
          calendar.set(Calendar.MILLISECOND, 0);
          calendar.set(Calendar.SECOND, 0);
          calendar.set(Calendar.MINUTE, 0);
        }
        break;
      case Calendar.MINUTE:
        if (60 % interval_override == 0) {
          calendar.setTimeInMillis(ts);
          calendar.set(Calendar.MILLISECOND, 0);
          calendar.set(Calendar.SECOND, 0);
          calendar.set(Calendar.MINUTE, 0);
          if (interval_override > 60) {
            calendar.add(Calendar.MINUTE, -interval_override);
          }
        } else {
          // from top of day
          calendar.setTimeInMillis(ts);
          calendar.set(Calendar.MILLISECOND, 0);
          calendar.set(Calendar.SECOND, 0);
          calendar.set(Calendar.MINUTE, 0);
          calendar.set(Calendar.HOUR_OF_DAY, 0);
        }
        break;
      case Calendar.HOUR_OF_DAY:
        if (24 % interval_override == 0) {
          calendar.setTimeInMillis(ts);
          calendar.set(Calendar.MILLISECOND, 0);
          calendar.set(Calendar.SECOND, 0);
          calendar.set(Calendar.MINUTE, 0);
          calendar.set(Calendar.HOUR_OF_DAY, 0);
          if (interval_override > 24) {
            calendar.add(Calendar.HOUR_OF_DAY, -interval_override);
          }
        } else {
          // from top of month
          calendar.setTimeInMillis(ts);
          calendar.set(Calendar.MILLISECOND, 0);
          calendar.set(Calendar.SECOND, 0);
          calendar.set(Calendar.MINUTE, 0);
          calendar.set(Calendar.HOUR_OF_DAY, 0);
          calendar.set(Calendar.DAY_OF_MONTH, 1);
        }
        break;
      case Calendar.DAY_OF_MONTH:
        if (interval_override == 1) {
          calendar.setTimeInMillis(ts);
          calendar.set(Calendar.MILLISECOND, 0);
          calendar.set(Calendar.SECOND, 0);
          calendar.set(Calendar.MINUTE, 0);
          calendar.set(Calendar.HOUR_OF_DAY, 0);
          calendar.set(Calendar.DAY_OF_MONTH, 1);
        } else {
          // from top of year
          calendar.setTimeInMillis(ts);
          calendar.set(Calendar.MILLISECOND, 0);
          calendar.set(Calendar.SECOND, 0);
          calendar.set(Calendar.MINUTE, 0);
          calendar.set(Calendar.HOUR_OF_DAY, 0);
          calendar.set(Calendar.DAY_OF_MONTH, 1);
          calendar.set(Calendar.MONTH, 0);
        }
        break;
      case Calendar.DAY_OF_WEEK:
        if (2 % interval_override == 0) {
          calendar.setTimeInMillis(ts);
          calendar.set(Calendar.MILLISECOND, 0);
          calendar.set(Calendar.SECOND, 0);
          calendar.set(Calendar.MINUTE, 0);
          calendar.set(Calendar.HOUR_OF_DAY, 0);
          calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());
        } else {
          // from top of year
          calendar.setTimeInMillis(ts);
          calendar.set(Calendar.MILLISECOND, 0);
          calendar.set(Calendar.SECOND, 0);
          calendar.set(Calendar.MINUTE, 0);
          calendar.set(Calendar.HOUR_OF_DAY, 0);
          calendar.set(Calendar.MONTH, 0);
          calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());
        }
        unit_override = Calendar.DAY_OF_MONTH;
        interval_override = 7;
        break;
      case Calendar.WEEK_OF_YEAR:
        // from top of year
        calendar.setTimeInMillis(ts);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.MONTH, 0);
        break;
      case Calendar.MONTH:
      case Calendar.YEAR:
        calendar.setTimeInMillis(ts);
        calendar.set(Calendar.MILLISECOND, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.MONTH, 0);
        break;
      default:
        throw new IllegalArgumentException("Unexpected unit_overrides of type: "
            + unit_override);
      }
      
      if (calendar.getTimeInMillis() == ts) {
        return calendar;
      }
      // TODO optimize a bit. We probably don't need to go past then back.
      while (calendar.getTimeInMillis() <= ts) {
        calendar.add(unit_override, interval_override);
      }
      calendar.add(unit_override, -interval_override);
      return calendar;
    }