Coming from here, I have now the following data and must say I'm quite puzzled.

Which value is correct now?

  • #1 Given the reference data from a German software company specializing on tax software. In their sample loan paychecks, they give for example for a monthly brutto income of EUR 4926.59 (all further values in euro, and always Lohnsteuerklasse I). This corresponds to the Lohnsteuer tax fee 1000.75.

  • #2 Then if you take the popular site brutto-netto-rechner.info it gives you 1003.16.

  • #3 There are also official government documents for tax deduction available as XML which an open source project can transform to program code in some popular languages. My take on it with its Python product outputs 1247.91.

  • #4 Official German tax tool gives 1027.

  • #5 Finally, my own take on the Wikipedia formula with Python gives 936.91.

This can't be?! I must really think of the Blue Tigers story by J.L.Borges.

UPDATE after the question was answered / solution

Thanks to this community the following code works for me based on #3; in #2 it works as well but they have rounding errors. Others I have not double-checked.

def test_lohnexample1(self):

        # source: https://www.lohnexperte.de/files/root-pdfs/pdf/Muster.pdf

        brutto = 4926.59 * 100 # Brutto in ¢ent

        l = Lohnsteuer2018()
        l.setRe4(brutto) # cent

        l.setStkl(1) # Steuerklasse
        l.setLzz(2) # Lohnzahlungszeitraum, 2 = Monat

        l.setZkf(1) # Kinder

        l.setPkv(0) # GKV (default)
        l.setKvz(1.5) # Krankenkassenzusatzbeitrag (1.50%) 
        l.setKrv(0) # RV-WEST (default)

        l.setAlter1(0) # setze 1, wenn das 64. Lebensjahr zu Beginn des Kalenderjahres vollendet wurde
        l.setAf(0) # # 1, wenn die Anwendung des Faktorverfahrens gewählt wurden (nur in Steuerklasse IV)
        l.setF(1) # Faktor
        l.setPvs(0) # Nur wenn in Sachsen
        l.setR(0) # Religion ja/nein
        l.setLzzhinzu(0) # Hinzurechnungsbetrag auf der Lohnsteuerkarte
        l.setPvz(0) # 1, wenn Zuschlag zur sozialen Pflegeversicherung

        print("results lohnexample1:")

        steuer = math.floor(float(l.getLstlzz()) + float(l.getStv()) + float(l.getSts())) / 100.0
        soli = math.floor(float(l.getSolzlzz()) + float(l.getSolzs()) + float(l.getSolzv())) / 100
        stges = steuer + soli

        assert steuer == 1000.75
        assert soli == 42.20
  • If there's indeed such variance on the subject, I would consult a licensed in German tax law advisor than listen to anything further on an online forum tbh. – Leon Dec 12 '18 at 12:33
  • 1
    There are a lot of dependencies like children, Freibetraege, etc., but the government publishes tables (not a formula), which are binding. I would trust those most. – Aganju Dec 12 '18 at 14:16
  • @Aganju I used governmental XML description of calculation workflows, so the formulae are there, see link above. – J. Doe Dec 12 '18 at 14:49

Aganju has it right that there are many variables. Consider in particular Kinderfreibetrag (Kfb) and Krankenkassenzusatzbeitrag (1.50%) in your first source. Put exactly the same variables into your second source and the result is the same, to the cent. I expect that the same will be true for the 4th source.

  • thank you @WerKater now it works for me! Adding the two facts you have pointed out in the source code based on the source #3, I get exactly same values as in #1. With #2 it works as well but I think they have some rounding errors. For those who is interested in more detailed I added a summary as an update to the question. – J. Doe Dec 13 '18 at 6:07

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.