/** * Exactly divides this frequency by another. * * <p>This calculates the integer division of this frequency by the specified frequency. If the * result is not an integer, an exception is thrown. * * <p>Month-based and year-based periodic frequencies are calculated by dividing the total number * of months. For example, P6M divided by P3M results in 2, and P2Y divided by P6M returns 4. * * <p>Day-based and week-based periodic frequencies are calculated by dividing the total number of * days. For example, P26W divided by P13W results in 2, and P2W divided by P1D returns 14. * * <p>The 'Term' frequency throws an exception. * * @param other the other frequency to divide into this one * @return this frequency divided by the other frequency * @throws IllegalArgumentException if the frequency does not exactly divide into this one */ public int exactDivide(Frequency other) { ArgChecker.notNull(other, "other"); if (isMonthBased() && other.isMonthBased()) { long paymentMonths = getPeriod().toTotalMonths(); long accrualMonths = other.getPeriod().toTotalMonths(); if ((paymentMonths % accrualMonths) == 0) { return Math.toIntExact(paymentMonths / accrualMonths); } } else if (period.toTotalMonths() == 0 && other.period.toTotalMonths() == 0) { long paymentDays = getPeriod().getDays(); long accrualDays = other.getPeriod().getDays(); if ((paymentDays % accrualDays) == 0) { return Math.toIntExact(paymentDays / accrualDays); } } throw new IllegalArgumentException( Messages.format("Frequency '{}' is not a multiple of '{}'", this, other)); }
/** * Parses a formatted string representing the frequency. * * <p>The format can either be based on ISO-8601, such as 'P3M' or without the 'P' prefix e.g. * '2W'. * * <p>The period must be positive and non-zero. * * @param toParse the string representing the frequency * @return the frequency * @throws IllegalArgumentException if the frequency cannot be parsed */ @FromString public static Frequency parse(String toParse) { ArgChecker.notNull(toParse, "toParse"); if (toParse.equalsIgnoreCase("Term")) { return TERM; } String prefixed = toParse.startsWith("P") ? toParse : "P" + toParse; try { return Frequency.of(Period.parse(prefixed)); } catch (DateTimeParseException ex) { throw new IllegalArgumentException(ex); } }
/** * Normalizes the months and years of this tenor. * * <p>This method returns a tenor of an equivalent length but with any number of months greater * than 12 normalized into a combination of months and years. * * @return the normalized tenor */ public Frequency normalized() { Period norm = period.normalized(); return (norm != period ? Frequency.of(norm) : this); }