文件获取地址:https://wenshushu.vip/pan/index.php?id=36 提取码:7bf9

在开始编码之前,我们先了解一下中国个人所得税的计算规则:
TaxCalculator/
├── src/
│ ├── model/
│ │ ├── TaxProfile.java # 纳税人信息
│ │ ├── IncomeRecord.java # 收入记录
│ │ └── Deduction.java # 扣除项
│ ├── tax/
│ │ ├── TaxCalculator.java # 个税计算器接口
│ │ ├── ChinaTaxCalculator.java # 中国个税计算
│ │ └── TaxRateTable.java # 税率表
│ ├── util/
│ │ └── DateUtil.java # 日期工具类
│ └── Main.java # 主程序首先定义基础的数据模型:
package model;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
/**
* 纳税人信息
*/
public class TaxProfile {
private String name; // 姓名
private String idNumber; // 身份证号
private LocalDate employmentDate; // 入职日期
private String city; // 工作城市
private BigDecimal basicDeduction; // 基本减除费用(起征点)
// 专项附加扣除
private BigDecimal childrenEducation; // 子女教育
private BigDecimal continuingEducation; // 继续教育
private BigDecimal housingLoanInterest; // 住房贷款利息
private BigDecimal housingRent; // 住房租金
private BigDecimal elderlySupport; // 赡养老人
private BigDecimal infantCare; // 3岁以下婴幼儿照护
private BigDecimal seriousIllness; // 大病医疗
public TaxProfile() {
this.basicDeduction = new BigDecimal("5000");
this.childrenEducation = BigDecimal.ZERO;
this.continuingEducation = BigDecimal.ZERO;
this.housingLoanInterest = BigDecimal.ZERO;
this.housingRent = BigDecimal.ZERO;
this.elderlySupport = BigDecimal.ZERO;
this.infantCare = BigDecimal.ZERO;
this.seriousIllness = BigDecimal.ZERO;
}
// 计算专项附加扣除总额
public BigDecimal getTotalSpecialDeduction() {
return childrenEducation.add(continuingEducation)
.add(housingLoanInterest)
.add(housingRent)
.add(elderlySupport)
.add(infantCare)
.add(seriousIllness);
}
// getters 和 setters
// ...
}
/**
* 月度收入记录
*/
public class IncomeRecord {
private int year;
private int month;
private BigDecimal salary; // 工资收入
private BigDecimal yearEndBonus; // 年终奖
private BigDecimal socialInsurance; // 社保
private BigDecimal housingFund; // 公积金
private BigDecimal otherDeductions; // 其他扣除
public IncomeRecord(int year, int month) {
this.year = year;
this.month = month;
this.salary = BigDecimal.ZERO;
this.yearEndBonus = BigDecimal.ZERO;
this.socialInsurance = BigDecimal.ZERO;
this.housingFund = BigDecimal.ZERO;
this.otherDeductions = BigDecimal.ZERO;
}
// 计算应纳税所得额前的扣除总额
public BigDecimal getTotalPreTaxDeduction() {
return socialInsurance.add(housingFund).add(otherDeductions);
}
// getters 和 setters
// ...
}package tax;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
* 中国个人所得税税率表(综合所得)
*/
public class ChinaTaxRateTable {
public static class TaxBracket {
private int level; // 级数
private BigDecimal lowerBound; // 下限
private BigDecimal upperBound; // 上限(null表示无穷大)
private BigDecimal rate; // 税率
private BigDecimal quickDeduction; // 速算扣除数
public TaxBracket(int level, String lowerBound, String upperBound,
String rate, String quickDeduction) {
this.level = level;
this.lowerBound = new BigDecimal(lowerBound);
this.upperBound = upperBound == null ? null : new BigDecimal(upperBound);
this.rate = new BigDecimal(rate);
this.quickDeduction = new BigDecimal(quickDeduction);
}
}
// 2023年中国个税税率表(年度税率表)
private static final List<TaxBracket> ANNUAL_BRACKETS = new ArrayList<>();
static {
// 全年应纳税所得额 = 年度收入 - 60000 - 专项扣除 - 专项附加扣除 - 其他扣除
ANNUAL_BRACKETS.add(new TaxBracket(1, "0", "36000", "0.03", "0"));
ANNUAL_BRACKETS.add(new TaxBracket(2, "36000", "144000", "0.10", "2520"));
ANNUAL_BRACKETS.add(new TaxBracket(3, "144000", "300000", "0.20", "16920"));
ANNUAL_BRACKETS.add(new TaxBracket(4, "300000", "420000", "0.25", "31920"));
ANNUAL_BRACKETS.add(new TaxBracket(5, "420000", "660000", "0.30", "52920"));
ANNUAL_BRACKETS.add(new TaxBracket(6, "660000", "960000", "0.35", "85920"));
ANNUAL_BRACKETS.add(new TaxBracket(7, "960000", null, "0.45", "181920"));
}
// 月度税率表(用于某些特殊计算)
private static final List<TaxBracket> MONTHLY_BRACKETS = new ArrayList<>();
static {
MONTHLY_BRACKETS.add(new TaxBracket(1, "0", "3000", "0.03", "0"));
MONTHLY_BRACKETS.add(new TaxBracket(2, "3000", "12000", "0.10", "210"));
MONTHLY_BRACKETS.add(new TaxBracket(3, "12000", "25000", "0.20", "1410"));
MONTHLY_BRACKETS.add(new TaxBracket(4, "25000", "35000", "0.25", "2660"));
MONTHLY_BRACKETS.add(new TaxBracket(5, "35000", "55000", "0.30", "4410"));
MONTHLY_BRACKETS.add(new TaxBracket(6, "55000", "80000", "0.35", "7160"));
MONTHLY_BRACKETS.add(new TaxBracket(7, "80000", null, "0.45", "15160"));
}
public static List<TaxBracket> getAnnualBrackets() {
return ANNUAL_BRACKETS;
}
public static List<TaxBracket> getMonthlyBrackets() {
return MONTHLY_BRACKETS;
}
/**
* 根据应纳税所得额查找适用的税率和速算扣除数
*/
public static TaxBracket findApplicableBracket(BigDecimal taxableIncome, boolean isAnnual) {
List<TaxBracket> brackets = isAnnual ? ANNUAL_BRACKETS : MONTHLY_BRACKETS;
for (TaxBracket bracket : brackets) {
boolean lowerCondition = taxableIncome.compareTo(bracket.getLowerBound()) >= 0;
boolean upperCondition = bracket.getUpperBound() == null ||
taxableIncome.compareTo(bracket.getUpperBound()) < 0;
if (lowerCondition && upperCondition) {
return bracket;
}
}
// 如果找不到,返回最高税率档
return brackets.get(brackets.size() - 1);
}
}package tax;
import model.TaxProfile;
import model.IncomeRecord;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
/**
* 中国个人所得税计算器(累计预扣法)
*/
public class ChinaTaxCalculator implements TaxCalculator {
private static final BigDecimal ANNUAL_BASIC_DEDUCTION = new BigDecimal("60000");
private static final BigDecimal MONTHLY_BASIC_DEDUCTION = new BigDecimal("5000");
@Override
public BigDecimal calculateMonthlyTax(TaxProfile profile, List<IncomeRecord> records, int targetMonth) {
if (records == null || records.isEmpty()) {
return BigDecimal.ZERO;
}
// 按月份排序
Map<String, IncomeRecord> sortedRecords = new TreeMap<>();
for (IncomeRecord record : records) {
String key = String.format("%04d-%02d", record.getYear(), record.getMonth());
sortedRecords.put(key, record);
}
// 计算累计应纳税所得额
BigDecimal cumulativeTaxableIncome = BigDecimal.ZERO;
BigDecimal cumulativeTaxPaid = BigDecimal.ZERO;
for (Map.Entry<String, IncomeRecord> entry : sortedRecords.entrySet()) {
IncomeRecord record = entry.getValue();
int currentMonth = record.getMonth();
// 计算到当前月份为止的累计值
BigDecimal monthSalary = record.getSalary();
BigDecimal monthPreTaxDeduction = record.getTotalPreTaxDeduction();
BigDecimal monthSpecialDeduction = profile.getTotalSpecialDeduction();
// 累计收入
BigDecimal cumulativeIncome = getCumulativeIncome(sortedRecords, currentMonth);
// 累计扣除
BigDecimal cumulativeDeduction = getCumulativeDeduction(
profile, sortedRecords, currentMonth);
// 累计应纳税所得额 = 累计收入 - 累计基本减除费用 - 累计专项扣除 - 累计专项附加扣除 - 累计其他扣除
cumulativeTaxableIncome = cumulativeIncome
.subtract(MONTHLY_BASIC_DEDUCTION.multiply(new BigDecimal(currentMonth)))
.subtract(cumulativeDeduction);
if (cumulativeTaxableIncome.compareTo(BigDecimal.ZERO) <= 0) {
// 如果累计应纳税所得额<=0,不需要交税
record.setTaxAmount(BigDecimal.ZERO);
continue;
}
// 根据累计应纳税所得额计算累计应缴税额
ChinaTaxRateTable.TaxBracket bracket =
ChinaTaxRateTable.findApplicableBracket(cumulativeTaxableIncome, false);
BigDecimal cumulativeTax = cumulativeTaxableIncome
.multiply(bracket.getRate())
.subtract(bracket.getQuickDeduction());
// 本月应补(退)税额 = 累计应缴税额 - 已缴税额
BigDecimal taxForMonth = cumulativeTax.subtract(cumulativeTaxPaid);
// 如果是目标月份,返回税额
if (currentMonth == targetMonth) {
return taxForMonth.max(BigDecimal.ZERO); // 确保不为负数
}
// 更新已缴税额
cumulativeTaxPaid = cumulativeTaxPaid.add(taxForMonth.max(BigDecimal.ZERO));
}
return BigDecimal.ZERO;
}
@Override
public BigDecimal calculateAnnualTax(TaxProfile profile, List<IncomeRecord> records, int year) {
// 计算年度总收入
BigDecimal annualIncome = BigDecimal.ZERO;
BigDecimal annualDeductions = BigDecimal.ZERO;
for (IncomeRecord record : records) {
if (record.getYear() == year) {
annualIncome = annualIncome.add(record.getSalary());
annualDeductions = annualDeductions.add(record.getTotalPreTaxDeduction());
}
}
// 计算年度应纳税所得额
BigDecimal annualTaxableIncome = annualIncome
.subtract(ANNUAL_BASIC_DEDUCTION) // 基本减除费用
.subtract(annualDeductions) // 专项扣除
.subtract(profile.getTotalSpecialDeduction().multiply(new BigDecimal("12"))); // 专项附加扣除
if (annualTaxableIncome.compareTo(BigDecimal.ZERO) <= 0) {
return BigDecimal.ZERO;
}
// 使用年度税率表计算税额
ChinaTaxRateTable.TaxBracket bracket =
ChinaTaxRateTable.findApplicableBracket(annualTaxableIncome, true);
BigDecimal annualTax = annualTaxableIncome
.multiply(bracket.getRate())
.subtract(bracket.getQuickDeduction());
return annualTax.max(BigDecimal.ZERO);
}
/**
* 计算年终奖个税(可选择并入综合所得或单独计税)
* @param bonus 年终奖金额
* @param mergeWithSalary 是否并入综合所得
* @param annualTaxableIncome 年度综合所得应纳税所得额(如果mergeWithSalary为false时使用)
*/
public BigDecimal calculateYearEndBonusTax(BigDecimal bonus, boolean mergeWithSalary,
BigDecimal annualTaxableIncome) {
if (mergeWithSalary) {
// 并入综合所得,直接使用综合所得税率
ChinaTaxRateTable.TaxBracket bracket =
ChinaTaxRateTable.findApplicableBracket(
annualTaxableIncome.add(bonus), true);
return annualTaxableIncome.add(bonus)
.multiply(bracket.getRate())
.subtract(bracket.getQuickDeduction());
} else {
// 单独计税:年终奖/12,找月度税率,再乘以12
BigDecimal monthlyBonus = bonus.divide(new BigDecimal("12"), 2, RoundingMode.HALF_UP);
ChinaTaxRateTable.TaxBracket bracket =
ChinaTaxRateTable.findApplicableBracket(monthlyBonus, false);
return bonus.multiply(bracket.getRate())
.subtract(bracket.getQuickDeduction().multiply(new BigDecimal("12")));
}
}
private BigDecimal getCumulativeIncome(Map<String, IncomeRecord> records, int upToMonth) {
BigDecimal total = BigDecimal.ZERO;
for (Map.Entry<String, IncomeRecord> entry : records.entrySet()) {
if (entry.getValue().getMonth() <= upToMonth) {
total = total.add(entry.getValue().getSalary());
}
}
return total;
}
private BigDecimal getCumulativeDeduction(TaxProfile profile,
Map<String, IncomeRecord> records,
int upToMonth) {
BigDecimal total = BigDecimal.ZERO;
for (Map.Entry<String, IncomeRecord> entry : records.entrySet()) {
if (entry.getValue().getMonth() <= upToMonth) {
total = total.add(entry.getValue().getTotalPreTaxDeduction());
}
}
// 加上专项附加扣除
total = total.add(profile.getTotalSpecialDeduction().multiply(new BigDecimal(upToMonth)));
return total;
}
}package tax;
import model.TaxProfile;
import model.IncomeRecord;
import java.math.BigDecimal;
import java.util.List;
/**
* 个税计算器接口
*/
public interface TaxCalculator {
/**
* 计算月度个税(累计预扣法)
*/
BigDecimal calculateMonthlyTax(TaxProfile profile, List<IncomeRecord> records, int month);
/**
* 计算年度个税(汇算清缴)
*/
BigDecimal calculateAnnualTax(TaxProfile profile, List<IncomeRecord> records, int year);
/**
* 验证纳税人信息
*/
default boolean validateProfile(TaxProfile profile) {
return profile != null &&
profile.getName() != null &&
!profile.getName().trim().isEmpty();
}
}import model.TaxProfile;
import model.IncomeRecord;
import tax.ChinaTaxCalculator;
import tax.TaxCalculator;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
System.out.println("===== 个人所得税计算器 =====");
// 创建纳税人信息
TaxProfile profile = new TaxProfile();
profile.setName("张三");
profile.setCity("北京");
profile.setEmploymentDate(LocalDate.of(2020, 1, 1));
// 设置专项附加扣除
profile.setChildrenEducation(new BigDecimal("1000")); // 子女教育1000元/月
profile.setHousingLoanInterest(new BigDecimal("1000")); // 住房贷款利息1000元/月
profile.setElderlySupport(new BigDecimal("2000")); // 赡养老人2000元/月
// 创建收入记录(2023年1-12月)
List<IncomeRecord> records = new ArrayList<>();
// 示例:1月收入
IncomeRecord janRecord = new IncomeRecord(2023, 1);
janRecord.setSalary(new BigDecimal("20000")); // 月薪20000
janRecord.setSocialInsurance(new BigDecimal("2000")); // 社保
janRecord.setHousingFund(new BigDecimal("2400")); // 公积金
records.add(janRecord);
// 示例:2月收入
IncomeRecord febRecord = new IncomeRecord(2023, 2);
febRecord.setSalary(new BigDecimal("22000")); // 月薪22000
febRecord.setSocialInsurance(new BigDecimal("2200"));
febRecord.setHousingFund(new BigDecimal("2640"));
records.add(febRecord);
// 可以继续添加其他月份...
// 创建计算器
TaxCalculator calculator = new ChinaTaxCalculator();
// 计算1月个税
BigDecimal janTax = calculator.calculateMonthlyTax(profile, records, 1);
System.out.printf("2023年1月个税: ¥%.2f%n", janTax);
// 计算2月个税
BigDecimal febTax = calculator.calculateMonthlyTax(profile, records, 2);
System.out.printf("2023年2月个税: ¥%.2f%n", febTax);
// 计算年度个税
BigDecimal annualTax = calculator.calculateAnnualTax(profile, records, 2023);
System.out.printf("2023年年度个税: ¥%.2f%n", annualTax);
// 计算年终奖个税
ChinaTaxCalculator chinaCalculator = (ChinaTaxCalculator) calculator;
BigDecimal bonus = new BigDecimal("50000"); // 年终奖50000
BigDecimal bonusTax = chinaCalculator.calculateYearEndBonusTax(
bonus, false, new BigDecimal("100000"));
System.out.printf("年终奖个税(单独计税): ¥%.2f%n", bonusTax);
// 显示详细计算过程
displayCalculationDetails(profile, records, janTax, 1);
}
private static void displayCalculationDetails(TaxProfile profile,
List<IncomeRecord> records,
BigDecimal tax, int month) {
System.out.println("\n===== 计算明细 =====");
System.out.printf("计算月份: %d月%n", month);
System.out.printf("纳税人: %s%n", profile.getName());
BigDecimal monthlySalary = BigDecimal.ZERO;
BigDecimal totalDeduction = BigDecimal.ZERO;
for (IncomeRecord record : records) {
if (record.getMonth() == month) {
monthlySalary = record.getSalary();
totalDeduction = record.getTotalPreTaxDeduction();
break;
}
}
System.out.printf("月收入: ¥%.2f%n", monthlySalary);
System.out.printf("专项扣除(社保公积金等): ¥%.2f%n", totalDeduction);
System.out.printf("专项附加扣除总额: ¥%.2f%n", profile.getTotalSpecialDeduction());
System.out.printf("应纳税额: ¥%.2f%n", tax);
// 计算税后收入
BigDecimal afterTaxIncome = monthlySalary.subtract(totalDeduction).subtract(tax);
System.out.printf("税后收入: ¥%.2f%n", afterTaxIncome);
// 计算税率
if (monthlySalary.compareTo(BigDecimal.ZERO) > 0) {
BigDecimal taxRate = tax.divide(monthlySalary, 4, BigDecimal.ROUND_HALF_UP)
.multiply(new BigDecimal("100"));
System.out.printf("实际税率: %.2f%%%n", taxRate);
}
}
}我们可以扩展这个系统来支持多个国家的个税计算:
package tax;
import model.TaxProfile;
import model.IncomeRecord;
import java.math.BigDecimal;
import java.util.List;
/**
* 美国个人所得税计算器(简化版)
*/
public class USATaxCalculator implements TaxCalculator {
// 美国2023年税率表(单身)
private static final BigDecimal[] BRACKETS = {
new BigDecimal("0"),
new BigDecimal("11000"),
new BigDecimal("44725"),
new BigDecimal("95375"),
new BigDecimal("182100"),
new BigDecimal("231250"),
new BigDecimal("578125")
};
private static final BigDecimal[] RATES = {
new BigDecimal("0.10"),
new BigDecimal("0.12"),
new BigDecimal("0.22"),
new BigDecimal("0.24"),
new BigDecimal("0.32"),
new BigDecimal("0.35"),
new BigDecimal("0.37")
};
@Override
public BigDecimal calculateMonthlyTax(TaxProfile profile, List<IncomeRecord> records, int month) {
// 美国个税通常按年计算,月度为预扣
// 这里简化处理,直接计算年度税的1/12
BigDecimal annualTax = calculateAnnualTax(profile, records, 2023);
return annualTax.divide(new BigDecimal("12"), 2, BigDecimal.ROUND_HALF_UP);
}
@Override
public BigDecimal calculateAnnualTax(TaxProfile profile, List<IncomeRecord> records, int year) {
// 计算年度总收入
BigDecimal annualIncome = BigDecimal.ZERO;
for (IncomeRecord record : records) {
if (record.getYear() == year) {
annualIncome = annualIncome.add(record.getSalary().multiply(new BigDecimal("12")));
}
}
// 美国标准扣除额(2023年单身)
BigDecimal standardDeduction = new BigDecimal("13850");
BigDecimal taxableIncome = annualIncome.subtract(standardDeduction);
if (taxableIncome.compareTo(BigDecimal.ZERO) <= 0) {
return BigDecimal.ZERO;
}
// 累进计算
BigDecimal tax = BigDecimal.ZERO;
for (int i = 1; i < BRACKETS.length; i++) {
if (taxableIncome.compareTo(BRACKETS[i]) > 0) {
BigDecimal bracketAmount = BRACKETS[i].subtract(BRACKETS[i-1]);
tax = tax.add(bracketAmount.multiply(RATES[i-1]));
} else {
BigDecimal lastBracketAmount = taxableIncome.subtract(BRACKETS[i-1]);
tax = tax.add(lastBracketAmount.multiply(RATES[i-1]));
break;
}
}
// 如果超过最高档
if (taxableIncome.compareTo(BRACKETS[BRACKETS.length-1]) > 0) {
BigDecimal excess = taxableIncome.subtract(BRACKETS[BRACKETS.length-1]);
tax = tax.add(excess.multiply(RATES[RATES.length-1]));
}
return tax;
}
}为确保计算准确性,我们应该编写单元测试:
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import java.math.BigDecimal;
class ChinaTaxCalculatorTest {
@Test
void testCalculateMonthlyTax() {
TaxProfile profile = new TaxProfile();
profile.setName("测试用户");
profile.setChildrenEducation(new BigDecimal("1000"));
List<IncomeRecord> records = new ArrayList<>();
IncomeRecord record = new IncomeRecord(2023, 1);
record.setSalary(new BigDecimal("20000"));
record.setSocialInsurance(new BigDecimal("2000"));
record.setHousingFund(new BigDecimal("2400"));
records.add(record);
ChinaTaxCalculator calculator = new ChinaTaxCalculator();
BigDecimal tax = calculator.calculateMonthlyTax(profile, records, 1);
// 验证计算结果
assertTrue(tax.compareTo(BigDecimal.ZERO) > 0);
assertEquals(new BigDecimal("258.00"), tax);
}
@Test
void testLowIncomeNoTax() {
TaxProfile profile = new TaxProfile();
profile.setName("低收入测试");
List<IncomeRecord> records = new ArrayList<>();
IncomeRecord record = new IncomeRecord(2023, 1);
record.setSalary(new BigDecimal("4000")); // 低于起征点
records.add(record);
ChinaTaxCalculator calculator = new ChinaTaxCalculator();
BigDecimal tax = calculator.calculateMonthlyTax(profile, records, 1);
assertEquals(BigDecimal.ZERO, tax);
}
}原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。