一般信用贷款会提供两种还款方式:每月等额或者先息后本。每月等额,就是每月归还等同的部分本金和利息,你手里在使用的本金其实是逐月减少的。先息后本就是先还利息,到期归还本金。
每月等额
1 import java.math.BigDecimal;
2 import java.util.Calendar;
3 import java.util.Date;
4
5 /**
6 * <p>Title: 等额本息还款工具类</p>
7 *
8 */
9 public class CPMUtils{
10
11 /**
12 * <p>Description: 每月还款总额。〔贷款本金×月利率×(1+月利率)^还款月数〕÷〔(1+月利率)^还款月数-1〕</p>
13 * @param principal 贷款本金
14 * @param monthlyInterestRate 月利率
15 * @param amount 期数
16 * @return
17 */
18 public static BigDecimal monthlyRepayment(BigDecimal principal, BigDecimal monthlyInterestRate, int amount){
19 //(1+月利率)^还款月数
20 BigDecimal temp = monthlyInterestRate.add(MoneyUtils.ONE).pow(amount);
21 return principal.multiply(monthlyInterestRate)
22 .multiply(temp)
23 .divide(temp.subtract(MoneyUtils.ONE), MoneyUtils.MATHCONTEXT);
24 }
25
26 /**
27 * <p>Description: 月还款利息。(贷款本金×月利率-月还款额)*(1+月利率)^(当前期数-1)+月还款额</p>
28 * @param principal 贷款本金
29 * @param monthlyInterestRate 月利率
30 * @param monthlyRepayment 月还款额
31 * @param number 当前期数
32 * @return
33 */
34 public static BigDecimal monthlyInterest(BigDecimal principal, BigDecimal monthlyInterestRate, BigDecimal monthlyRepayment, int number){
35 //(1+月利率)^(当前期数-1)
36 BigDecimal temp = monthlyInterestRate.add(MoneyUtils.ONE).pow(number - 1);
37 return principal.multiply(monthlyInterestRate)
38 .subtract(monthlyRepayment)
39 .multiply(temp).add(monthlyRepayment, MoneyUtils.MATHCONTEXT);
41 }
42
43 /**
44 * <p>Description: 还款总利息。期数×贷款本金×月利率×(1+月利率)^期数÷〔(1+月利率)^期数-1〕-贷款本金 </p>
45 * @param principal 贷款本金
46 * @param monthlyInterestRate 月利率
47 * @param amount 还款期数
48 * @return
49 */
50 public static BigDecimal interest(BigDecimal principal, BigDecimal monthlyInterestRate, int amount){
51 //(1+月利率)^期数
52 BigDecimal temp = monthlyInterestRate.add(MoneyUtils.ONE).pow(amount);
53 return new BigDecimal(amount)
54 .multiply(principal)
55 .multiply(monthlyInterestRate)
56 .multiply(temp)
57 .divide(temp.subtract(MoneyUtils.ONE), MoneyUtils.MATHCONTEXT)
58 .subtract(principal, MoneyUtils.MATHCONTEXT);
59 }
60
61 /**
62 * <p>Description: 月还款本金。已经精确到分位,未做单位换算</p>
63 * @param principal 贷款本金
64 * @param monthlyInterestRate 月利率
65 * @param monthlyRepayment 月还款额
66 * @param number 当前期数
67 * @return
68 */
69 public static BigDecimal monthlyPrincipal(BigDecimal principal, BigDecimal monthlyInterestRate, BigDecimal monthlyRepayment, int number){
70 BigDecimal monthInterest = monthlyInterest(principal, monthlyInterestRate, monthlyRepayment, number);
71 //月还款额-月还款利息
72 return monthlyRepayment.subtract(monthInterest).setScale(MoneyUtils.MONEYSHOWSCALE, MoneyUtils.SAVEROUNDINGMODE);
73 }
74
75 /**
76 * <p>Description: 月还款本金。已经精确到分位,未做单位换算</p>
77 * @param monthRepayment 月还款总额
78 * @param monthInterest 月还款利息
79 * @return
80 */
81 public static BigDecimal monthPrincipal(BigDecimal monthRepayment, BigDecimal monthInterest){
82 //月还款总额-月还款利息
83 return monthRepayment.subtract(monthInterest).setScale(MoneyUtils.MONEYSHOWSCALE, MoneyUtils.SAVEROUNDINGMODE);
84 }
85
86 }
先息后本
1 import java.math.BigDecimal;
2
3 /**
4 * <p>Title: 先息后本还款方式工具类型</p>
5 */
6 public class BIAPPUtils extends RepaymentUtils {
7
8 /**
9 * <p>Description: 月还款利息 贷款本金×月利率 </p>
10 * @param loan 贷款本金
11 * @param monthlyInterestRate 月利率
12 * @return
13 */
14 public static BigDecimal monthlyInterest(BigDecimal loan, BigDecimal monthlyInterestRate){
15 return loan.multiply(monthlyInterestRate, MoneyUtils.MATHCONTEXT);
16 }
17 /**
18 * <p>Description: 还款总利息 贷款本金×月利率×期数</p>
19 * @param loan 贷款本金
20 * @param monthlyInterestRate 月利率
21 * @param number 期数
22 * @return
23 */
24 public static BigDecimal interest(BigDecimal loan, BigDecimal monthlyInterestRate, int number){
25 return loan.multiply(monthlyInterestRate).multiply(new BigDecimal(number), MoneyUtils.MATHCONTEXT);
26 }
27 /**
28 * <p>Description: 月还款额</p>
29 * @param loan 贷款本金
30 * @param monthlyInterestRate 月利率
31 * @param amount 期数
32 * @param curNumber 当前期数
33 * @return
34 */
35 public static BigDecimal monthlyRepayment(BigDecimal loan, BigDecimal monthlyInterestRate, int amount, int curNumber){
36 BigDecimal monthlyInterest = monthlyInterest(loan, monthlyInterestRate);
37 if(amount == curNumber){
38 return monthlyInterest.add(loan, MoneyUtils.MATHCONTEXT);//最后月还款额
39 }else{
40 return monthlyInterest;
41 }
42 }
43 }
*金额计算工具类
1 import java.math.BigDecimal;
2 import java.math.MathContext;
3 import java.math.RoundingMode;
4 import java.text.NumberFormat;
5
6 public class MoneyUtils {
7 /**
8 * 标度(小数位数)
9 */
10 public static final int SCALE = 10;
11
12 /**
13 * 金钱显示标度(小数位数)
14 */
15 public static final int MONEYSHOWSCALE = 2;
16
17 /**
18 * 利率显示标度(小数位数)
19 */
20 public static final int INTERESTRATESHOWSCALE = 4;
21
22 /**
23 * 精度
24 */
25 public static final int PRECISION = 30;
26
27 /**
28 * 保存舍入规则
29 */
30 public static final RoundingMode SAVEROUNDINGMODE = RoundingMode.HALF_UP;
31
32 /**
33 * 是否舍去小数点最后的零
34 */
35 public static boolean STRIPTRAILINGZEROS = true;
36
37 /**
38 * 运算上下文(设置精度、舍入规则)
39 */
40 public static final MathContext MATHCONTEXT = new MathContext(PRECISION, SAVEROUNDINGMODE);
41
42 /**
43 * 每年天数
44 */
45 public static final String YEARDAYS = "360";
46
47 /**
48 * 每年月数
49 */
50 public static final String YEARMOTHS = "12";
51
52 /**
53 * 每月天数
54 */
55 public static final String MOTHDAYS = "30";
56
57 /**
58 * 数字“1”
59 */
60 public static final BigDecimal ONE = new BigDecimal(1);
61
62 /**
63 * 数字“100”
64 */
65 public static final BigDecimal HUNDRED = new BigDecimal(100);
66
67 /**
68 * 数字“0.01”
69 */
70 public static final BigDecimal ONEHUNDREDTH = new BigDecimal(0.01);
71
72 public static BigDecimal newBigDecimal(String str){
73 return (str == null || str.trim().isEmpty()) ? BigDecimal.ZERO : new BigDecimal(str);
74 }
75
76 /**
77 * <p>Description: 加法返回格式化结果数字</p>
78 * @param addend
79 * @param augend
80 * @return
81 */
82 public static BigDecimal add(BigDecimal addend, BigDecimal augend){
83 return formatMoney(addend.add(augend, MATHCONTEXT));
84 }
85
86 /**
87 * <p>Description: 加法返回格式化结果数字</p>
88 * @param addend
89 * @param augend
90 * @return
91 */
92 public static BigDecimal add(String addend, String augend){
93 BigDecimal decimalAddend = newBigDecimal(addend);
94 BigDecimal decimalAugend = newBigDecimal(augend);
95 return formatMoney(decimalAddend.add(decimalAugend, MATHCONTEXT));
96 }
97
98 /**
99 * <p>Description: 加法返回格式化结果字符串</p>
100 * @param addend
101 * @param augend
102 * @return
103 */
104 public static String addToString(BigDecimal addend, BigDecimal augend){
105 return formatToString(addend.add(augend, MATHCONTEXT));
106 }
107
108 /**
109 * <p>Description: 加法返回格式化结果字符串</p>
110 * @param addend
111 * @param augend
112 * @return
113 */
114 public static String addToString(String addend, String augend){
115 BigDecimal decimalAddend = newBigDecimal(addend);
116 BigDecimal decimalAugend = newBigDecimal(augend);
117 return formatToString(decimalAddend.add(decimalAugend, MATHCONTEXT));
118 }
119
120 /**
121 * <p>Description: 减法返回格式化结果数字</p>
122 * @param minuend
123 * @param subtrahend
124 * @return
125 */
126 public static BigDecimal subtract(BigDecimal minuend, BigDecimal subtrahend){
127 return formatMoney(minuend.subtract(subtrahend, MATHCONTEXT));
128 }
129
130
131 /**
132 * <p>Description: 减法返回格式化结果数字</p>
133 * @param minuend
134 * @param subtrahend
135 * @return
136 */
137 public static BigDecimal subtract(String minuend, String subtrahend){
138 BigDecimal decimalMinuend = newBigDecimal(minuend);
139 BigDecimal decimalSubtrahend = newBigDecimal(subtrahend);
140 return formatMoney(decimalMinuend.subtract(decimalSubtrahend, MATHCONTEXT));
141 }
142
143 /**
144 * <p>Description: 减法返回格式化结果字符串</p>
145 * @param minuend
146 * @param subtrahend
147 * @return
148 */
149 public static String subtractToString(BigDecimal minuend, BigDecimal subtrahend){
150 return formatToString(minuend.subtract(subtrahend, MATHCONTEXT));
151 }
152 /**
153 * <p>Description: 减法返回格式化结果字符串</p>
154 * @param minuend
155 * @param subtrahend
156 * @return
157 */
158 public static String subtractToString(String minuend, String subtrahend){
159 BigDecimal decimalMinuend = newBigDecimal(minuend);
160 BigDecimal decimalSubtrahend = newBigDecimal(subtrahend);
161 return formatToString(decimalMinuend.subtract(decimalSubtrahend, MATHCONTEXT));
162 }
163
164 /**
165 * <p>Description: 乘法返回格式化结果数字</p>
166 * @param multiplier
167 * @param multiplicand
168 * @return
169 */
170 public static BigDecimal multiply(BigDecimal multiplier, BigDecimal multiplicand){
171 return formatMoney(multiplier.multiply(multiplicand, MATHCONTEXT));
172 }
173
174
175 /**
176 * <p>Description: 乘法返回格式化结果数字</p>
177 * @param multiplier
178 * @param multiplicand
179 * @return
180 */
181 public static BigDecimal multiply(String multiplier, String multiplicand){
182 BigDecimal decimalMultiplier = newBigDecimal(multiplier);
183 BigDecimal decimalMultiplicand = newBigDecimal(multiplicand);
184 return formatMoney(decimalMultiplier.multiply(decimalMultiplicand, MATHCONTEXT));
185 }
186
187 /**
188 * <p>Description: 乘法返回格式化结果字符串</p>
189 * @param multiplier
190 * @param multiplicand
191 * @return
192 */
193 public static String multiplyToString(BigDecimal multiplier, BigDecimal multiplicand){
194 return formatToString(multiplier.multiply(multiplicand, MATHCONTEXT));
195 }
196 /**
197 * <p>Description: 乘法返回格式化结果字符串</p>
198 * @param multiplier
199 * @param multiplicand
200 * @return
201 */
202 public static String multiplyToString(String multiplier, String multiplicand){
203 BigDecimal decimalMultiplier = newBigDecimal(multiplier);
204 BigDecimal decimalMultiplicand = newBigDecimal(multiplicand);
205 return formatToString(decimalMultiplier.multiply(decimalMultiplicand, MATHCONTEXT));
206 }
207
208 /**
209 * <p>Description: 除法返回格式化结果数字</p>
210 * @param dividend
211 * @param divisor
212 * @return
213 */
214 public static BigDecimal divide(BigDecimal dividend, BigDecimal divisor){
215 return formatMoney(dividend.divide(divisor, MATHCONTEXT));
216 }
217 /**
218 * <p>Description: 除法返回格式化结果数字</p>
219 * @param dividend
220 * @param divisor
221 * @return
222 */
223 public static BigDecimal divide(String dividend, String divisor){
224 BigDecimal decimalDividend = newBigDecimal(dividend);
225 BigDecimal decimalDivisor = newBigDecimal(divisor);
226 return formatMoney(decimalDividend.divide(decimalDivisor, MATHCONTEXT));
227 }
228
229 /**
230 * <p>Description: 除法返回格式化结果字符串</p>
231 * @param dividend
232 * @param divisor
233 * @return
234 */
235 public static String divideToString(BigDecimal dividend, BigDecimal divisor){
236 return formatToString(dividend.divide(divisor, MATHCONTEXT));
237 }
238
239 /**
240 * <p>Description: 除法返回格式化结果字符串</p>
241 * @param dividend
242 * @param divisor
243 * @return
244 */
245 public static String divideToString(String dividend, String divisor){
246 BigDecimal decimalDividend = newBigDecimal(dividend);
247 BigDecimal decimalDivisor = newBigDecimal(divisor);
248 return formatToString(decimalDividend.divide(decimalDivisor, MATHCONTEXT));
249 }
250 /**
251 * <p>Description: 月利率计算</p>
252 * @param yearInterestRate
253 * @return
254 */
255 public static BigDecimal monthInterestRate(BigDecimal yearInterestRate){
256 BigDecimal dayInterestRate = MoneyUtils.divide(yearInterestRate, YEARDAYS).setScale(5, RoundingMode.CEILING);
257 System.err.println(dayInterestRate);
258 BigDecimal monthInterestRate = dayInterestRate.multiply(newBigDecimal(MOTHDAYS));
259 System.err.println(monthInterestRate);
260 return monthInterestRate;
261 }
262
263 /**
264 * <p>Description: 按既定小数位数格式化金额保存</p>
265 * @param result
266 * @return
267 */
268 public static BigDecimal formatMoney(BigDecimal result){
269 return result.setScale(SCALE, SAVEROUNDINGMODE);
270 }
271
272 /**
273 * <p>Description: 按既定小数位数格式化金额显示</p>
274 * @param resultStr 要格式化的数
275 * @param multiple 乘以的倍数
276 * @return
277 */
278 public static String formatMoneyToShow(String resultStr, BigDecimal multiple){
279 BigDecimal result = newBigDecimal(resultStr);
280 return MoneyUtils.formatToString(MoneyUtils.formatMoneyToShow(result, multiple));
281 }
282
283 /**
284 * <p>Description: 按既定小数位数格式化金额显示</p>
285 * @param result 要格式化的数
286 * @param multiple 乘以的倍数
287 * @return
288 */
289 public static BigDecimal formatMoneyToShow(BigDecimal result, BigDecimal multiple){
290 return result.multiply(multiple).setScale(MONEYSHOWSCALE, SAVEROUNDINGMODE);
291 }
292
293 /**
294 * <p>Description: 按既定小数位数格式化利率显示</p>
295 * @param result 要格式化的数
296 * @param multiple 乘以的倍数
297 * @return
298 */
299 public static BigDecimal formatInterestRateToShow(BigDecimal result, BigDecimal multiple){
300 return result.multiply(multiple).setScale(INTERESTRATESHOWSCALE, SAVEROUNDINGMODE);
301 }
302
303 /**
304 * <p>Description: 按既定小数位数格式化显示</p>
305 * @param result 要格式化的数
306 * @param scale 显示标度(小数位数)
307 * @return
308 */
309 public static BigDecimal formatToShow(BigDecimal result, int scale){
310 return result.setScale(scale, SAVEROUNDINGMODE);
311 }
312
313 /**
314 * <p>Description: 格式化为字符串,进行去零不去零操作</p>
315 * @param result
316 * @return
317 */
318 public static String formatToString(BigDecimal result){
319 if(result == null){
320 return "";
321 }else{
322 return STRIPTRAILINGZEROS ? result.stripTrailingZeros().toPlainString() : result.toPlainString();
323 }
324 }
325
326 /**
327 * <p>Description: 按既定小数位数格式化为货币格式</p>
328 * @param result
329 * @return
330 */
331 public static String formatToCurrency(BigDecimal result){
332 BigDecimal temp = result.divide(HUNDRED, SAVEROUNDINGMODE);
333 NumberFormat numberFormat = NumberFormat.getCurrencyInstance();
334 return numberFormat.format(STRIPTRAILINGZEROS ? temp.stripTrailingZeros() : temp);
335 }
336
337 public static String formatToPercent(BigDecimal result){
338 BigDecimal temp = result.divide(HUNDRED, SAVEROUNDINGMODE);
339 NumberFormat numberFormat = NumberFormat.getPercentInstance();
340 return numberFormat.format(STRIPTRAILINGZEROS ? temp.stripTrailingZeros() : temp);
341 }
342
343 /**
344 * <p>Description:格式化数字为千分位显示; </p>
345 * @param text
346 * @return
347 */
348 public static String fmtMicrometer(String text){
349 DecimalFormat df = null;
350 if(text.indexOf(".") > 0) {
351 if(text.length() - text.indexOf(".")-1 == 0){
352 df = new DecimalFormat("###,##0.");
353 }else if(text.length() - text.indexOf(".")-1 == 1){
354 df = new DecimalFormat("###,##0.0");
355 }else {
356 df = new DecimalFormat("###,##0.00");
357 }
358 }else{
359 df = new DecimalFormat("###,##0.00");
360 }
361 double number = 0.0;
362 try {
363 number = Double.parseDouble(text);
364 } catch (Exception e) {
365 number = 0.0;
366 }
367 return df.format(number);
368 }
369
370 }