Skip to content

Instantly share code, notes, and snippets.

@jarenal
Forked from avar/30-income-calculon.pl
Created January 10, 2016 20:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jarenal/f6517c05f8dca90c9ad3 to your computer and use it in GitHub Desktop.
Save jarenal/f6517c05f8dca90c9ad3 to your computer and use it in GitHub Desktop.
Calculate your income in The Netherlands with and without a 30% ruling.
# To check if this is up-to-date with the tax rates go to
# http://www.expatax.nl/tax-rates-2015.php and see if there's anything
# newer there.
#
# I make no guarantees that any of this is correct. I calculated this
# at the time and have been updating it when new tax rates come along
# because people keep finding this useful.
#
# There's also an interactive JS version of this created by
# @stevermeister at
# https://github.com/stevermeister/dutch-tax-income-calculator
# although the two seem to show conflicting values and I have no idea
# which one is correct...
use strict;
use warnings;
use Text::TabularDisplay;
use List::Util qw(sum);
my $start = 30_000 || $ARGV[0];
my $end = 100_000 || $ARGV[1];
my $step = 1_000 || $ARGV[2];
my @data;
for ( my $salary = $start ; $salary <= $end ; $salary += $step ) {
push @data => [
# Your Gross income
eurofy($salary),
# Without 30% ruling
eurofy( $salary - taxes_for($salary) ),
percentify( taxes_for($salary), $salary ),
# With 30% ruling
eurofy( $salary - taxes_for( $salary * .7 ) ),
percentify( taxes_for( $salary * .7 ), $salary ),
];
}
my $table = Text::TabularDisplay->new(
"Gross income\n(before taxes)",
"Net income\n(after taxes)",
"Tax rate",
"Net income\n(after taxes,\nwith 30% ruling)",
"Tax rate",
);
$table->add(@$_) for @data;
print $table->render, "\n";
exit;
sub taxes_for {
my $income = shift;
my @tax_brackets = (
# difference tax rate
[ 19_822 => .3650 ],
[ 57_585 - 19_822 => .42 ],
[ 0 => .52 ],
);
my $money_left = $income;
my $taxes = 0;
foreach my $bracket (@tax_brackets) {
my ( $progressive_amount, $taxes_for ) = @$bracket;
my $taxable_amount = $money_left;
if ( $taxable_amount > $progressive_amount ) {
$taxable_amount = $progressive_amount if $progressive_amount;
}
$money_left -= $taxable_amount;
$taxes += $taxable_amount * $taxes_for;
last unless $money_left;
}
return $taxes;
}
# From perlfaq5
sub commify {
local $_ = shift;
1 while s/^([-+]?\d+)(\d{3})/$1,$2/;
return $_;
}
sub percentify {
my ( $amount, $total ) = @_;
return sprintf "%.1f%%" => ( ( 100 * $amount ) / $total );
}
sub eurofy {
my ($number) = @_;
# Round it
$number = int $number;
return sprintf( "%s EUR", commify($number) );
}
__DATA__
$ perl 30-income-calculon.pl
+----------------+---------------+----------+------------------+----------+
| Gross income | Net income | Tax rate | Net income | Tax rate |
| (before taxes) | (after taxes) | | (after taxes, | |
| | | | with 30% ruling) | |
+----------------+---------------+----------+------------------+----------+
| 30,000 EUR | 18,490 EUR | 38.4% | 22,270 EUR | 25.8% |
| 31,000 EUR | 19,070 EUR | 38.5% | 22,976 EUR | 25.9% |
| 32,000 EUR | 19,650 EUR | 38.6% | 23,682 EUR | 26.0% |
| 33,000 EUR | 20,230 EUR | 38.7% | 24,388 EUR | 26.1% |
| 34,000 EUR | 20,810 EUR | 38.8% | 25,094 EUR | 26.2% |
| 35,000 EUR | 21,390 EUR | 38.9% | 25,800 EUR | 26.3% |
| 36,000 EUR | 21,970 EUR | 39.0% | 26,506 EUR | 26.4% |
| 37,000 EUR | 22,550 EUR | 39.1% | 27,212 EUR | 26.5% |
| 38,000 EUR | 23,130 EUR | 39.1% | 27,918 EUR | 26.5% |
| 39,000 EUR | 23,710 EUR | 39.2% | 28,624 EUR | 26.6% |
| 40,000 EUR | 24,290 EUR | 39.3% | 29,330 EUR | 26.7% |
| 41,000 EUR | 24,870 EUR | 39.3% | 30,036 EUR | 26.7% |
| 42,000 EUR | 25,450 EUR | 39.4% | 30,742 EUR | 26.8% |
| 43,000 EUR | 26,030 EUR | 39.5% | 31,448 EUR | 26.9% |
| 44,000 EUR | 26,610 EUR | 39.5% | 32,154 EUR | 26.9% |
| 45,000 EUR | 27,190 EUR | 39.6% | 32,860 EUR | 27.0% |
| 46,000 EUR | 27,770 EUR | 39.6% | 33,566 EUR | 27.0% |
| 47,000 EUR | 28,350 EUR | 39.7% | 34,272 EUR | 27.1% |
| 48,000 EUR | 28,930 EUR | 39.7% | 34,978 EUR | 27.1% |
| 49,000 EUR | 29,510 EUR | 39.8% | 35,684 EUR | 27.2% |
| 50,000 EUR | 30,090 EUR | 39.8% | 36,390 EUR | 27.2% |
| 51,000 EUR | 30,670 EUR | 39.9% | 37,096 EUR | 27.3% |
| 52,000 EUR | 31,250 EUR | 39.9% | 37,802 EUR | 27.3% |
| 53,000 EUR | 31,830 EUR | 39.9% | 38,508 EUR | 27.3% |
| 54,000 EUR | 32,410 EUR | 40.0% | 39,214 EUR | 27.4% |
| 55,000 EUR | 32,990 EUR | 40.0% | 39,920 EUR | 27.4% |
| 56,000 EUR | 33,570 EUR | 40.1% | 40,626 EUR | 27.5% |
| 57,000 EUR | 34,150 EUR | 40.1% | 41,332 EUR | 27.5% |
| 58,000 EUR | 34,688 EUR | 40.2% | 42,038 EUR | 27.5% |
| 59,000 EUR | 35,168 EUR | 40.4% | 42,744 EUR | 27.6% |
| 60,000 EUR | 35,648 EUR | 40.6% | 43,450 EUR | 27.6% |
| 61,000 EUR | 36,128 EUR | 40.8% | 44,156 EUR | 27.6% |
| 62,000 EUR | 36,608 EUR | 41.0% | 44,862 EUR | 27.6% |
| 63,000 EUR | 37,088 EUR | 41.1% | 45,568 EUR | 27.7% |
| 64,000 EUR | 37,568 EUR | 41.3% | 46,274 EUR | 27.7% |
| 65,000 EUR | 38,048 EUR | 41.5% | 46,980 EUR | 27.7% |
| 66,000 EUR | 38,528 EUR | 41.6% | 47,686 EUR | 27.7% |
| 67,000 EUR | 39,008 EUR | 41.8% | 48,392 EUR | 27.8% |
| 68,000 EUR | 39,488 EUR | 41.9% | 49,098 EUR | 27.8% |
| 69,000 EUR | 39,968 EUR | 42.1% | 49,804 EUR | 27.8% |
| 70,000 EUR | 40,448 EUR | 42.2% | 50,510 EUR | 27.8% |
| 71,000 EUR | 40,928 EUR | 42.4% | 51,216 EUR | 27.9% |
| 72,000 EUR | 41,408 EUR | 42.5% | 51,922 EUR | 27.9% |
| 73,000 EUR | 41,888 EUR | 42.6% | 52,628 EUR | 27.9% |
| 74,000 EUR | 42,368 EUR | 42.7% | 53,334 EUR | 27.9% |
| 75,000 EUR | 42,848 EUR | 42.9% | 54,040 EUR | 27.9% |
| 76,000 EUR | 43,328 EUR | 43.0% | 54,746 EUR | 28.0% |
| 77,000 EUR | 43,808 EUR | 43.1% | 55,452 EUR | 28.0% |
| 78,000 EUR | 44,288 EUR | 43.2% | 56,158 EUR | 28.0% |
| 79,000 EUR | 44,768 EUR | 43.3% | 56,864 EUR | 28.0% |
| 80,000 EUR | 45,248 EUR | 43.4% | 57,570 EUR | 28.0% |
| 81,000 EUR | 45,728 EUR | 43.5% | 58,276 EUR | 28.1% |
| 82,000 EUR | 46,208 EUR | 43.6% | 58,982 EUR | 28.1% |
| 83,000 EUR | 46,688 EUR | 43.7% | 59,636 EUR | 28.1% |
| 84,000 EUR | 47,168 EUR | 43.8% | 60,272 EUR | 28.2% |
| 85,000 EUR | 47,648 EUR | 43.9% | 60,908 EUR | 28.3% |
| 86,000 EUR | 48,128 EUR | 44.0% | 61,544 EUR | 28.4% |
| 87,000 EUR | 48,608 EUR | 44.1% | 62,180 EUR | 28.5% |
| 88,000 EUR | 49,088 EUR | 44.2% | 62,816 EUR | 28.6% |
| 89,000 EUR | 49,568 EUR | 44.3% | 63,452 EUR | 28.7% |
| 90,000 EUR | 50,048 EUR | 44.4% | 64,088 EUR | 28.8% |
| 91,000 EUR | 50,528 EUR | 44.5% | 64,724 EUR | 28.9% |
| 92,000 EUR | 51,008 EUR | 44.6% | 65,360 EUR | 29.0% |
| 93,000 EUR | 51,488 EUR | 44.6% | 65,996 EUR | 29.0% |
| 94,000 EUR | 51,968 EUR | 44.7% | 66,632 EUR | 29.1% |
| 95,000 EUR | 52,448 EUR | 44.8% | 67,268 EUR | 29.2% |
| 96,000 EUR | 52,928 EUR | 44.9% | 67,904 EUR | 29.3% |
| 97,000 EUR | 53,408 EUR | 44.9% | 68,540 EUR | 29.3% |
| 98,000 EUR | 53,888 EUR | 45.0% | 69,176 EUR | 29.4% |
| 99,000 EUR | 54,368 EUR | 45.1% | 69,812 EUR | 29.5% |
| 100,000 EUR | 54,848 EUR | 45.2% | 70,448 EUR | 29.6% |
+----------------+---------------+----------+------------------+----------+
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment