计算按揭明细记录的类:
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 <[email protected]> * @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); } }
import java.io.Serializable; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.Date; /** * @author Alfoo Liu <[email protected]> * @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