计算按揭明细记录的类:
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author Alfoo Liu <dmcpxy@Gmail.com>
* @since 2011-11-01 09:58
*/
public class MortgageCalculator {
final static String default_config_file_name = "MortgageCalculator.properties";
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
DecimalFormat df = new DecimalFormat("0.00");
DecimalFormat dfl = new DecimalFormat("0.0000");
private Properties configuration = new Properties();
public MortgageCalculator(String configFilePath) {
df.setRoundingMode(RoundingMode.UP);
dfl.setRoundingMode(RoundingMode.UP);
loadProperties(configFilePath);
}
public void loadProperties(String filePath) {
try {
FileInputStream fileInputStream = new FileInputStream(filePath);
configuration.load(fileInputStream);
} catch (FileNotFoundException fnfe) {
InputStream resourceAsStream = getClass().getResourceAsStream(default_config_file_name);
try {
configuration.load(resourceAsStream);
} catch (IOException e) {
System.err.println("failed read config file: " + default_config_file_name + " from classpath "
+ this.getClass().getPackage().getName());
}
} catch (IOException ioe) {
System.err.println("failed read config file: " + filePath);
}
}
public Properties getConfiguration() {
return configuration;
}
public void printMortgageDetailInfo(List<MortgageBean> payList) {
for (MortgageBean bean : payList) {
System.out.println(bean.toString());
}
}
/**
* calculte method: (total - benjin_money * cur_month) * rate_month + benjin_money;
* @return List pay list;
*/
public List<MortgageBean> calculate() {
List<MortgageBean> payList = new ArrayList<MortgageBean>();
int period = getPeriod(), restPeriod;
double totalPrincipal = getTotalPrincipal();
String currentDateStr = getFirstPayDate();
double restPrincipal = totalPrincipal, interest, principal, rate, monthRate;
rate = getFirstPayRate();
Date currentDate;
MortgageBean mortgageBean;
for (int i = 1; i <= period; i++) {
monthRate = toDouble( dfl.format( rate / 12 ) );
restPeriod = period - i + 1;
principal = toDouble( df.format( (restPrincipal / restPeriod) ) );
String tiqianhuankuanDate = getConfiguration().getProperty("tiqianhuankuanDate");
if (null != tiqianhuankuanDate && tiqianhuankuanDate.equals(currentDateStr)) {
principal += toDouble( getConfiguration().getProperty("tiqianhuankuanMoney", "0") );
}
interest = toDouble( df.format( (restPrincipal - principal) * monthRate ) );
restPrincipal = toDouble(df.format(restPrincipal - principal));
currentDate = getDate(currentDateStr);
mortgageBean = new MortgageBean(currentDate, i, rate, toDouble( df.format(principal + interest) ),
principal, interest, restPrincipal);
payList.add(mortgageBean);
currentDateStr = getNextPayDate(currentDate);
rate = toDouble( dfl.format( getNextPayRate(currentDate, rate) ) );
}
return payList;
}
protected double toDouble(String dv) {
return Double.parseDouble(dv);
}
private double getDiscount() {
return Double.parseDouble(getConfiguration().getProperty("rateDiscount"));
}
private int getPeriod() {
return Integer.parseInt( getConfiguration().getProperty("periods") );
}
private double getTotalPrincipal() {
return Double.parseDouble(getConfiguration().getProperty("totalPrincipal"));
}
private String getFirstPayDate() {
return configuration.getProperty("firstMortgageDate");
}
private Date getDate(String date) {
try {
return format.parse(date);
} catch (ParseException e) {
System.err.println("invalid date format: " + date);
return null;
}
}
private double getFirstPayRate() {
String firstPayDate = "MortgageRate." + getFirstPayDate();
String firstRateStr = configuration.getProperty(firstPayDate);
double v = Double.parseDouble(firstRateStr)/100 * getDiscount();
return toDouble( dfl.format(v) );
}
private String getNextPayDate(Date date) {
GregorianCalendar gc = new GregorianCalendar(Locale.SIMPLIFIED_CHINESE);
gc.setTime(date);
gc.add(Calendar.MONTH, 1);
Date nextMonth = gc.getTime();
return format.format(nextMonth);
}
private double getNextPayRate(Date date, double lastPayRate) {
String property = configuration.getProperty("MortgageRate." + getNextPayDate(date));
if (null == property) {
return lastPayRate;
}
double v = Double.parseDouble(property) * getDiscount() / 100;
return toDouble( dfl.format(v) );
}
public static void main(String[] args) {
MortgageCalculator calculator = new MortgageCalculator("");
calculator.loadProperties("");
List<MortgageBean> mortgageBeanList = calculator.calculate();
calculator.printMortgageDetailInfo(mortgageBeanList);
}
}
按揭的Bean类:
import java.io.Serializable;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @author Alfoo Liu <dmcpxy@Gmail.com>
* @since 2011-11-01 10:36
*/
public class MortgageBean implements Serializable {
DecimalFormat df = new DecimalFormat("0.00");
DecimalFormat dfl = new DecimalFormat("0.00%");
final static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
final static String DELIMETER = "\t\t";
private Date mortgageDate;
private int mortgageNumber;
private double rate;
/*当前月份还的款总额*/
private double currentMonthPay;
/*当前月份还的本金*/
private double currentMonthPrincipal;
/*当前月还的利息*/
private double currentMonthInterest;
/*剩余本金*/
private double restPrincipal;
public MortgageBean(Date mortgageDate, int mortgageNumber, double rate, double currentMonthPay,
double currentMonthPrincipal, double currentMonthInterest, double restPrincipal) {
this.mortgageDate = mortgageDate;
this.mortgageNumber = mortgageNumber;
this.rate = rate;
this.currentMonthPay = currentMonthPay;
this.currentMonthPrincipal = currentMonthPrincipal;
this.currentMonthInterest = currentMonthInterest;
this.restPrincipal = restPrincipal;
}
public Date getMortgageDate() {
return mortgageDate;
}
public void setMortgageDate(Date mortgageDate) {
this.mortgageDate = mortgageDate;
}
public int getMortgageNumber() {
return mortgageNumber;
}
public void setMortgageNumber(int mortgageNumber) {
this.mortgageNumber = mortgageNumber;
}
public double getRate() {
return rate;
}
public void setRate(float rate) {
this.rate = rate;
}
public double getCurrentMonthPay() {
return currentMonthPay;
}
public void setCurrentMonthPay(float currentMonthPay) {
this.currentMonthPay = currentMonthPay;
}
public double getCurrentMonthPrincipal() {
return currentMonthPrincipal;
}
public void setCurrentMonthPrincipal(float currentMonthPrincipal) {
this.currentMonthPrincipal = currentMonthPrincipal;
}
public double getCurrentMonthInterest() {
return currentMonthInterest;
}
public void setCurrentMonthInterest(float currentMonthInterest) {
this.currentMonthInterest = currentMonthInterest;
}
public double getRestPrincipal() {
return restPrincipal;
}
public void setRestPrincipal(float restPrincipal) {
this.restPrincipal = restPrincipal;
}
@Override public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(format.format( getMortgageDate() ));
sb.append(DELIMETER);
sb.append( getMortgageNumber() );
sb.append(DELIMETER);
sb.append( dfl.format(getRate()) );
sb.append(DELIMETER);
sb.append( df.format(getCurrentMonthPay()) );
sb.append(DELIMETER);
sb.append( df.format(getCurrentMonthPrincipal()) );
sb.append(DELIMETER);
sb.append( df.format(getCurrentMonthInterest()) );
sb.append(DELIMETER);
sb.append( df.format(getRestPrincipal()) );
return sb.toString();
}
}
配置文件,放在这个类相同的目录下:
#如果你家的还款日期是26号,则把日期的末两位全部改成26,日期格式为yyyyMMdd
#format: yyyyMMdd
firstMortgageDate=20100326
#第一次还款的利率
firstMortgageRate=5.94
#利率折扣
rateDiscount=0.7
#Unit: Month
periods=240
#Unit: yuan
totalPrincipal=300000
#提前还款月份
tiqianhuankuanDate=20111226
#Unit: yuan
tiqianhuankuanMoney=80000
#各期还款利率
MortgageRate.20100326=5.94
MortgageRate.20101026=6.14
MortgageRate.20101226=6.40
MortgageRate.20110226=6.60
MortgageRate.20110426=6.80
MortgageRate.20110726=7.05