1. はじめに
この「年収手取り計算機」は、額面の年収や月給から、実際に受け取れる手取り額(可処分所得)をシミュレーションするツールです。社会保険料(健康保険、厚生年金、雇用保険、介護保険)および税金(所得税、住民税)を自動計算し、月々の手取り額と年間の総手取り額を算出します。
年収手取り計算機
給与条件入力
※ボーナス込みの想定年収
※空欄時は年収から自動逆算
※空欄時は月給から自動設定
月々の手取り
年間手取り総額
月次明細
標準報酬: 0円| 社会保険料計 | 0円 |
| 健康保険 | 0円 |
| 厚生年金 | 0円 |
| 介護保険 | 0円 |
| 雇用保険 | 0円 |
| 源泉所得税 | 0円 |
| 住民税 (概算) | 0円 |
ボーナス手取り
0円| 総支給額 | 0円 |
| 社会保険料 | 0円 |
| 源泉所得税 | 0円 |
特徴: 面倒な計算式を覚える必要はありません。金額を入力するだけで、リアルタイムに結果が反映されます。また、入力値は自動保存されるため、次回アクセス時も続きから検討できます。
2. 入力項目の入力方法
金額はすべて「万円単位」で入力します(例:400万円なら「400」と入力)。
① 年収・ボーナス
基本となる年収(総支給額)を入力します。ボーナスがある場合は、年間のボーナス総額も入力してください。
※月給が未入力の場合、この年収とボーナスから月々の給与が自動的に逆算されます。
② 月額基本給(優先入力)
毎月の額面給与が決まっている場合は、ここに入力してください。この項目に入力がある場合、年収欄の入力にかかわらず、こちらの月額給与をベースに社会保険料や源泉税が計算されます。
これにより、「年収は高いが月給は低い(ボーナス偏重)」や「年俸制」など、多様な給与体系に対応した正確な手取り計算が可能になります。
③ 標準報酬月額
社会保険料の等級決定に使われる金額です。通常は月額給与から自動的に推定されますが、通勤手当が含まれる場合など、実際の等級と異なる場合は手動で修正できます。
④ 年齢・扶養人数
- 年齢: 40歳以上65歳未満の方は「介護保険料」が発生するため、手取り額が減ります。正確な年齢を入力してください。
- 扶養人数: 配偶者や子供などの扶養親族の人数です。所得税や住民税の控除額に大きく影響します。独身の場合は「0人」を選択してください。
3. 計算結果の見方
月々の手取り
毎月の銀行振込額の目安です。額面給与から社会保険料と源泉所得税、住民税(概算月割)を引いた金額です。
年間手取り総額
1年間に実際に手元に残る現金の総額です。(月々の手取り × 12) + ボーナス手取り で算出されます。
画面下部の明細テーブルでは、健康保険、厚生年金、雇用保険、所得税、住民税それぞれの控除額を確認できます。どの項目でいくら引かれているかを把握するのに役立ちます。
4. 詳細設定・カスタマイズ
画面右上の 設定ボタンから、より詳細なパラメータを変更可能です。
- 社会保険料率: お住まいの都道府県や加入している健保組合によって料率が異なるため、厳密に計算したい場合はここを修正してください(デフォルトは協会けんぽ東京支部の料率等を参考に設定されています)。
- 税金計算パラメータ: 住民税の均等割額や基礎控除額など、自治体によって異なる微細な数字を調整できます。
5. 便利機能
$D83D$DCC4 PDF保存機能計算結果をPDFファイルとしてダウンロードできます。ライフプランの検討資料として印刷したり、パートナーと共有したりするのに便利です。$D83D$DCBE 自動保存入力したデータはブラウザに自動的に保存されます。ページを閉じても、次回開いたときに直前の入力状態から再開できます。
免責事項
本ツールの計算結果はあくまで概算シミュレーションであり、実際の給与明細や確定申告の結果と完全に一致することを保証するものではありません。 特に住民税は前年の所得に基づいて決定されるため、就職・転職1年目などは実際の手取りと大きく異なる場合があります(本ツールでは、現在の年収ベースで翌年支払う住民税相当額を月割で引いて計算しています)。 正確な税額計算が必要な場合は、税理士や所轄の税務署にご相談ください。
import html2canvas from ‘html2canvas’; import { jsPDF } from ‘jspdf’; // — Configuration & Constants — const DEFAULTS = { healthRate: 4.96, // % (Employee share) pensionRate: 9.15, // % (Employee share) nursingRate: 0.795, // % (Employee share) empRate: 0.6, // % (Employee share) bonusTaxRate: 10.21, // % resBasicDed: 430000, // Yen (Local tax basic deduction) resDepDed: 330000, // Yen (Local tax dependent deduction) resPerCapita: 5000, // Yen (Annual per capita) }; // — Calculation Functions — /** * Calculate Social Insurance Premiums */ function calculateSocialInsurance(stdMonthly, grossSalary, age, settings) { const health = Math.floor(stdMonthly * (settings.healthRate / 100)); const pension = Math.floor(stdMonthly * (settings.pensionRate / 100)); let nursing = 0; if (age >= 40 && age < 65) { nursing = Math.floor(stdMonthly * (settings.nursingRate / 100)); } const employment = Math.floor(grossSalary * (settings.empRate / 100)); return { health, pension, nursing, employment, total: health + pension + nursing + employment }; } /** * Calculate Monthly Withholding Tax (Income Tax) * シンプルな近似版:扶養によるズレは無視し、課税対象額に対してのみ源泉税を計算 */ function calculateMonthlyWithholdingTax(salaryAfterSocialIns, dependents) { // 課税対象額(社会保険料控除後の金額) const taxableBase = salaryAfterSocialIns; // そもそも課税ライン未満なら 0 円 if (taxableBase < 88000) return 0; let tax = 0; // ★扶養による控除はここでは行わず、 // 単純に課税額に対する源泉税を近似計算します。 // (細かい扶養差は住民税・年税側で調整する前提) if (taxableBase < 152500) { tax = (taxableBase - 88000) * 0.05105; } else if (taxableBase < 292500) { tax = (taxableBase - 152500) * 0.1021 + 3292; } else if (taxableBase < 642500) { tax = (taxableBase - 292500) * 0.2042 + 17586; } else if (taxableBase < 725000) { tax = (taxableBase - 642500) * 0.23483 + 89056; } else if (taxableBase < 1500000) { tax = (taxableBase - 725000) * 0.3063 + 108427; } else { tax = (taxableBase - 1500000) * 0.35 + 345800; } // 小数点以下切り捨て(円未満) return Math.floor(tax); } /** * Calculate Employment Income Deduction (Annual) */ function calculateEmploymentIncomeDeduction(annualGross) { if (annualGross <= 1625000) return 550000; if (annualGross <= 1800000) return annualGross * 0.4 - 100000; if (annualGross <= 3600000) return annualGross * 0.3 + 80000; if (annualGross <= 6600000) return annualGross * 0.2 + 440000; if (annualGross <= 8500000) return annualGross * 0.1 + 1100000; return 1950000; // Cap } /** * Calculate Resident Tax (Estimated) */ function calculateResidentTax(annualGross, annualSocialIns, dependents, settings) { const empDeduction = calculateEmploymentIncomeDeduction(annualGross); const netIncome = Math.max(0, annualGross - empDeduction); // Deductions const basicDed = settings.resBasicDed; const depDed = dependents * settings.resDepDed; const socDed = annualSocialIns; // Full deduction const totalDed = basicDed + depDed + socDed; const taxableIncome = Math.max(0, netIncome - totalDed); // Standard Rate 10% + Per Capita const incomeLevy = Math.floor(taxableIncome * 0.10); const totalTax = incomeLevy + settings.resPerCapita; return { annual: totalTax, monthly: Math.floor(totalTax / 12) }; } // --- Main Logic & UI Wiring --- const state = { settings: { ...DEFAULTS } }; function getNumber(id) { const val = document.getElementById(id).value; return val ? parseFloat(val) : 0; } function setContent(id, value) { const el = document.getElementById(id); if (el) el.textContent = value.toLocaleString(); } function updateSettingsFromUI() { state.settings.healthRate = parseFloat(document.getElementById('cfg-health').value) || DEFAULTS.healthRate; state.settings.pensionRate = parseFloat(document.getElementById('cfg-pension').value) || DEFAULTS.pensionRate; state.settings.nursingRate = parseFloat(document.getElementById('cfg-nursing').value) || DEFAULTS.nursingRate; state.settings.empRate = parseFloat(document.getElementById('cfg-emp').value) || DEFAULTS.empRate; state.settings.bonusTaxRate = parseFloat(document.getElementById('cfg-bonus-tax-rate').value) || DEFAULTS.bonusTaxRate; state.settings.resBasicDed = parseFloat(document.getElementById('cfg-res-basic').value) || DEFAULTS.resBasicDed; state.settings.resDepDed = parseFloat(document.getElementById('cfg-res-dep').value) || DEFAULTS.resDepDed; state.settings.resPerCapita = parseFloat(document.getElementById('cfg-res-per-capita').value) || DEFAULTS.resPerCapita; } function calculate() { // 1. Gather Inputs const monthlyGross = getNumber('input-monthly-salary'); let stdMonthly = getNumber('input-std-monthly'); const bonusAnnual = getNumber('input-bonus-annual'); // const bonusFreq = getNumber('input-bonus-freq'); // Used for display logic if needed const dependents = getNumber('input-dependents'); const age = getNumber('input-age'); // Auto-set Std Monthly if empty or zero (UX helper) if (!stdMonthly && monthlyGross > 0) { stdMonthly = Math.floor(monthlyGross / 1000) * 1000; // rough rounding document.getElementById(‘input-std-monthly’).value = stdMonthly; } // 2. Monthly Calculation const mSoc = calculateSocialInsurance(stdMonthly, monthlyGross, age, state.settings); const mTaxable = Math.max(0, monthlyGross – mSoc.total); const mIncomeTax = calculateMonthlyWithholdingTax(mTaxable, dependents); // Resident Tax (Annual Estimate / 12) // We need annual estimate first to get resident tax // Annual Estimate: const estAnnualGross = (monthlyGross * 12) + bonusAnnual; const estAnnualSoc = (mSoc.total * 12) + (bonusAnnual * 0.15); // Rough approx for bonus soc ins // We need accurate bonus soc ins for better calc // Bonus Soc Ins: // Bonus uses standard rate but applied to the bonus amount (Standard Bonus Amount). // Usually capped but we ignore cap for simplicity or assume standard range. const bSoc = { health: Math.floor(bonusAnnual * (state.settings.healthRate / 100)), pension: Math.floor(bonusAnnual * (state.settings.pensionRate / 100)), nursing: (age >= 40 && age < 65) ? Math.floor(bonusAnnual * (state.settings.nursingRate / 100)) : 0, employment: Math.floor(bonusAnnual * (state.settings.empRate / 100)), }; bSoc.total = bSoc.health + bSoc.pension + bSoc.nursing + bSoc.employment; const annualSocTotal = (mSoc.total * 12) + bSoc.total; const mResident = calculateResidentTax(estAnnualGross, annualSocTotal, dependents, state.settings); // Monthly Net const mTotalDed = mSoc.total + mIncomeTax + mResident.monthly; const mNet = monthlyGross - mTotalDed; // 3. Bonus Calculation // Bonus Tax const bTaxable = Math.max(0, bonusAnnual - bSoc.total); const bIncomeTax = Math.floor(bTaxable * (state.settings.bonusTaxRate / 100)); const bNet = bonusAnnual - bSoc.total - bIncomeTax; // 4. Annual Total const annualNet = (mNet * 12) + bNet; // 5. Update UI setContent('disp-std-monthly', stdMonthly); // Monthly setContent('res-monthly-net', mNet); setContent('res-monthly-gross', monthlyGross); setContent('res-health', mSoc.health); setContent('res-pension', mSoc.pension); setContent('res-nursing', mSoc.nursing); setContent('res-emp', mSoc.employment); setContent('res-soc-total', mSoc.total); setContent('res-income-tax', mIncomeTax); setContent('res-resident-tax', mResident.monthly); setContent('res-total-deduction', mTotalDed); // Bonus setContent('res-bonus-net', bNet); setContent('res-bonus-gross', bonusAnnual); setContent('res-bonus-soc', bSoc.total); setContent('res-bonus-tax', bIncomeTax); // Annual Results // Display Annual Net in Man-yen (e.g. 450.5) const annualNetMan = annualNet / 10000; setContent('res-annual-net', Math.round(annualNetMan * 100) / 100); // Show/Hide Nursing Row based on age const nursingRow = document.getElementById('row-nursing'); if (nursingRow) { nursingRow.style.display = (age >= 40 && age < 65) ? 'table-row' : 'none'; } // Save inputs saveInputs(); } // --- Persistence --- function saveInputs() { const data = { monthly: document.getElementById('input-monthly-salary').value, std: document.getElementById('input-std-monthly').value, bonus: document.getElementById('input-bonus-annual').value, freq: document.getElementById('input-bonus-freq').value, deps: document.getElementById('input-dependents').value, age: document.getElementById('input-age').value }; localStorage.setItem('calc_inputs', JSON.stringify(data)); } function loadInputs() { const saved = localStorage.getItem('calc_inputs'); if (saved) { try { const data = JSON.parse(saved); if (data.monthly) document.getElementById('input-monthly-salary').value = data.monthly; if (data.std) document.getElementById('input-std-monthly').value = data.std; if (data.bonus) document.getElementById('input-bonus-annual').value = data.bonus; if (data.freq) document.getElementById('input-bonus-freq').value = data.freq; if (data.deps) document.getElementById('input-dependents').value = data.deps; if (data.age) document.getElementById('input-age').value = data.age; } catch (e) { console.error("Failed to load inputs", e); } } } // --- PDF Generation --- async function generatePDF() { const btn = document.getElementById('btn-pdf'); const originalText = btn.innerHTML; btn.textContent = '生成中...'; btn.disabled = true; try { const element = document.getElementById('results-area'); const canvas = await html2canvas(element, { scale: 2 }); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF('p', 'mm', 'a4'); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = (canvas.height * pdfWidth) / canvas.width; pdf.text("年収手取り計算結果", 10, 10); pdf.addImage(imgData, 'PNG', 0, 20, pdfWidth, pdfHeight); pdf.save("salary-calculation.pdf"); } catch (err) { console.error(err); alert('PDF生成に失敗しました'); } finally { btn.innerHTML = originalText; btn.disabled = false; } } // --- Initialization --- window.addEventListener('DOMContentLoaded', () => { // 1. Load saved loadInputs(); // 2. Attach listeners to all inputs const inputs = document.querySelectorAll(‘input, select’); inputs.forEach(input => { input.addEventListener(‘input’, calculate); input.addEventListener(‘change’, calculate); }); // 3. Settings Modal const modal = document.getElementById(‘modal-settings’); const btnSettings = document.getElementById(‘btn-settings’); const btnClose = document.getElementById(‘btn-close-settings’); const btnReset = document.getElementById(‘btn-reset-settings’); btnSettings.addEventListener(‘click’, () => { modal.classList.remove(‘hidden’); setTimeout(() => modal.classList.remove(‘opacity-0’), 10); }); const closeSettings = () => { updateSettingsFromUI(); calculate(); modal.classList.add(‘opacity-0’); setTimeout(() => modal.classList.add(‘hidden’), 300); }; btnClose.addEventListener(‘click’, closeSettings); btnReset.addEventListener(‘click’, () => { // Reset inputs to default values document.getElementById(‘cfg-health’).value = DEFAULTS.healthRate; document.getElementById(‘cfg-pension’).value = DEFAULTS.pensionRate; document.getElementById(‘cfg-nursing’).value = DEFAULTS.nursingRate; document.getElementById(‘cfg-emp’).value = DEFAULTS.empRate; document.getElementById(‘cfg-bonus-tax-rate’).value = DEFAULTS.bonusTaxRate; document.getElementById(‘cfg-res-basic’).value = DEFAULTS.resBasicDed; document.getElementById(‘cfg-res-dep’).value = DEFAULTS.resDepDed; document.getElementById(‘cfg-res-per-capita’).value = DEFAULTS.resPerCapita; }); // 4. PDF document.getElementById(‘btn-pdf’).addEventListener(‘click’, generatePDF); // 5. Initial Calc updateSettingsFromUI(); calculate(); });

コメント