| 1 | |
|
| 2 | |
|
| 3 | |
|
| 4 | |
|
| 5 | |
|
| 6 | |
|
| 7 | |
|
| 8 | |
|
| 9 | |
|
| 10 | |
|
| 11 | |
|
| 12 | |
|
| 13 | |
|
| 14 | |
|
| 15 | |
|
| 16 | |
|
| 17 | |
|
| 18 | |
|
| 19 | |
|
| 20 | |
|
| 21 | |
|
| 22 | |
|
| 23 | |
|
| 24 | |
|
| 25 | |
|
| 26 | |
|
| 27 | |
|
| 28 | |
|
| 29 | |
|
| 30 | |
|
| 31 | |
|
| 32 | |
|
| 33 | |
package net.objectlab.kit.datecalc.joda; |
| 34 | |
|
| 35 | |
import net.objectlab.kit.datecalc.common.PeriodCountBasis; |
| 36 | |
import net.objectlab.kit.datecalc.common.PeriodCountCalculator; |
| 37 | |
|
| 38 | |
import org.joda.time.LocalDate; |
| 39 | |
import org.joda.time.Period; |
| 40 | |
import org.joda.time.PeriodType; |
| 41 | |
|
| 42 | |
|
| 43 | |
|
| 44 | |
|
| 45 | |
|
| 46 | |
|
| 47 | |
|
| 48 | |
|
| 49 | |
|
| 50 | |
|
| 51 | 614 | public class LocalDatePeriodCountCalculator implements PeriodCountCalculator<LocalDate> { |
| 52 | |
|
| 53 | |
public int dayDiff(final LocalDate start, final LocalDate end, final PeriodCountBasis basis) { |
| 54 | 1122 | int diff = 0; |
| 55 | |
|
| 56 | 1 | switch (basis) { |
| 57 | |
case CONV_30_360: |
| 58 | 204 | diff = diffConv30v360(start, end); |
| 59 | 204 | break; |
| 60 | |
|
| 61 | |
case CONV_360E_ISDA: |
| 62 | 204 | diff = diff360EIsda(start, end); |
| 63 | 204 | break; |
| 64 | |
|
| 65 | |
case CONV_360E_ISMA: |
| 66 | 204 | diff = diff360EIsma(start, end); |
| 67 | 204 | break; |
| 68 | |
default: |
| 69 | 510 | final Period p = new Period(start, end, PeriodType.days()); |
| 70 | 512 | diff = p.getDays(); |
| 71 | |
} |
| 72 | |
|
| 73 | 1122 | return diff; |
| 74 | |
} |
| 75 | |
|
| 76 | |
private int diff360EIsma(final LocalDate start, final LocalDate end) { |
| 77 | 204 | int dayStart = start.getDayOfMonth(); |
| 78 | 204 | int dayEnd = end.getDayOfMonth(); |
| 79 | 204 | if (dayEnd == MONTH_31_DAYS) { |
| 80 | 40 | dayEnd = MONTH_30_DAYS; |
| 81 | |
} |
| 82 | 204 | if (dayStart == MONTH_31_DAYS) { |
| 83 | 68 | dayStart = MONTH_30_DAYS; |
| 84 | |
} |
| 85 | 204 | return (end.getYear() - start.getYear()) * YEAR_360 + (end.getMonthOfYear() - start.getMonthOfYear()) * MONTH_30_DAYS + dayEnd - dayStart; |
| 86 | |
} |
| 87 | |
|
| 88 | |
private int diff360EIsda(final LocalDate start, final LocalDate end) { |
| 89 | 204 | int dayStart = start.getDayOfMonth(); |
| 90 | 204 | int dayEnd = end.getDayOfMonth(); |
| 91 | 204 | final int monthStart = start.getMonthOfYear(); |
| 92 | 204 | if ((monthStart == 2 && start.monthOfYear().getMaximumValue() == dayStart) || dayEnd == MONTH_31_DAYS) { |
| 93 | 40 | dayEnd = MONTH_30_DAYS; |
| 94 | |
} |
| 95 | 204 | if (dayStart == MONTH_31_DAYS) { |
| 96 | 68 | dayStart = MONTH_30_DAYS; |
| 97 | |
} |
| 98 | |
|
| 99 | 204 | return (end.getYear() - start.getYear()) * YEAR_360 + (end.getMonthOfYear() - start.getMonthOfYear()) * MONTH_30_DAYS + dayEnd - dayStart; |
| 100 | |
} |
| 101 | |
|
| 102 | |
private int diffConv30v360(final LocalDate start, final LocalDate end) { |
| 103 | 204 | int dayStart = start.getDayOfMonth(); |
| 104 | 204 | int dayEnd = end.getDayOfMonth(); |
| 105 | 204 | if (dayEnd == MONTH_31_DAYS && dayStart >= MONTH_30_DAYS) { |
| 106 | 36 | dayEnd = MONTH_30_DAYS; |
| 107 | |
} |
| 108 | 204 | if (dayStart == MONTH_31_DAYS) { |
| 109 | 68 | dayStart = MONTH_30_DAYS; |
| 110 | |
} |
| 111 | 204 | return (end.getYear() - start.getYear()) * YEAR_360 + (end.getMonthOfYear() - start.getMonthOfYear()) * MONTH_30_DAYS + dayEnd - dayStart; |
| 112 | |
} |
| 113 | |
|
| 114 | |
|
| 115 | |
|
| 116 | |
|
| 117 | |
|
| 118 | |
|
| 119 | |
|
| 120 | |
|
| 121 | |
|
| 122 | |
public double monthDiff(final LocalDate start, final LocalDate end, final PeriodCountBasis basis) { |
| 123 | 0 | return yearDiff(start, end, basis) * MONTHS_IN_YEAR; |
| 124 | |
} |
| 125 | |
|
| 126 | |
public double yearDiff(final LocalDate start, final LocalDate end, final PeriodCountBasis basis) { |
| 127 | 612 | double diff = 0.0; |
| 128 | |
|
| 129 | 612 | switch (basis) { |
| 130 | |
case ACT_ACT: |
| 131 | 102 | final int startYear = start.getYear(); |
| 132 | 102 | final int endYear = end.getYear(); |
| 133 | 102 | if (startYear != endYear) { |
| 134 | 76 | final LocalDate endOfStartYear = start.dayOfYear().withMaximumValue(); |
| 135 | 76 | final LocalDate startOfEndYear = end.withDayOfYear(1); |
| 136 | |
|
| 137 | 76 | final int diff1 = new Period(start, endOfStartYear, PeriodType.days()).getDays(); |
| 138 | 76 | final int diff2 = new Period(startOfEndYear, end, PeriodType.days()).getDays(); |
| 139 | 76 | diff = ((diff1 + 1.0)) / start.dayOfYear().getMaximumValue() + ((endYear - startYear - 1.0)) + ((double) (diff2)) |
| 140 | |
/ (double) end.dayOfYear().getMaximumValue(); |
| 141 | 76 | } |
| 142 | |
break; |
| 143 | |
|
| 144 | |
case CONV_30_360: |
| 145 | |
case CONV_360E_ISDA: |
| 146 | |
case CONV_360E_ISMA: |
| 147 | |
case ACT_360: |
| 148 | 408 | diff = (dayDiff(start, end, basis)) / YEAR_360_0; |
| 149 | 408 | break; |
| 150 | |
|
| 151 | |
case ACT_365: |
| 152 | 102 | diff = (dayDiff(start, end, basis)) / YEAR_365_0; |
| 153 | 102 | break; |
| 154 | |
|
| 155 | |
default: |
| 156 | 0 | throw new UnsupportedOperationException("Sorry ACT_UST is not supported"); |
| 157 | |
} |
| 158 | |
|
| 159 | 612 | return diff; |
| 160 | |
} |
| 161 | |
} |
| 162 | |
|
| 163 | |
|
| 164 | |
|
| 165 | |
|
| 166 | |
|
| 167 | |
|
| 168 | |
|
| 169 | |
|
| 170 | |
|
| 171 | |
|
| 172 | |
|
| 173 | |
|
| 174 | |
|
| 175 | |
|
| 176 | |
|
| 177 | |
|
| 178 | |
|