Extract birth date from Italian tax code

Dear all,
The Italian tax code is built this way: AAAAAAYYMDDAAAAA, where:
“A” characters aren’t relevant for this issue (name, surname, place of birth, control letter)
“YY” is the year of birth (there’s an ambiguity; it’s the same if you were born in 1924 or 2024, but for this issue, we can assume everybody was born after 1924)
“M” is a letter that indicates the month of birth; from Jan to Dec, the letters are ABCDEHLMPRST (A for January, T for December)
“D” is the day of birth, plus 40 if the code belongs to a woman.
So, if I was a woman born on November 15, 1965, my tax code would be something like NMESRN65S55X000Y
How can I extract from this code the date of birth of the person who inserts it in the form?
Thanks for your help!

This is what I did till now, but it’s a mess:

type name label hint read_only required calculation constraint
start start
end end
select_one regione regione Regione Inserire la regione in cui si trova l’Istituto e non quella di residenza true
select_one istituto istituto Istituto di appartenenza true
text CF Codice Fiscale Utilizza solo caratteri maiuscoli true regex(., '[1]{6}\d{2}[A-Z]\d{2}[A-Z]\d{3}[A-Z])
calculate anno_nascita number(substr(${CF},6,8))
calculate mese_nascita_l substr(${CF},8,9)
calculate mese_nascita_i translate(${mese_nascita_l},ABCDEHLMPRST,123456789abc)
calculate mese_nascita_x if(${mese_nascita_i}=a,10,if(${mese_nascita_i}=b,11,if(${mese_nascita_i}=c,12,${mese_nascita_i})))
calculate mese_nascita_n number(${mese_nascita_x})
calculate giorno_nascita number(substr(${CF},9,11))
calculate giorno_nascita_n if(${giorno_nascita}>35,${giorno_nascita}-40,${giorno_nascita})
calculate anno_nascita_n if(${anno_nascita}<=25,${anno_nascita}+2000,${anno_nascita}+1900)
calculate data_nascita concat(${giorno_nascita_n},/,${mese_nascita_n},/,${anno_nascita_n})
note datanascita Data di nascita La tua data di nascita è ${data_nascita}. Se non è corretta, verifica di aver inserito correttamente il tuo codice fiscale

  1. A-Z ↩︎

Try this; it is maybe a bit less of a ‘mess’ as there are really only 4 (actually only 3) core calculations required :slight_smile:

taxdecode.xlsx (6.2 KB)

I simplified a few of your calculations, and I left in some extraneous Notes to show the intermediate workings; these can be safely removed. Please have a play and let me know if it suits your purpose.

  • Gareth
2 Likes

Yours is better than mine, but in the meanwhile I found this other solution that seems to work (I added eta and status that I needed for other purposes, and the date-format DD-MM-YYYY)

type name label hint read_only required calculation constraint
text codice_fiscale Codice Fiscale Utilizzare solo caratteri maiuscoli true regex(., ‘[1]{6}\d{2}[A-Z]\d{2}[A-Z]\d{3}[A-Z]$’)
calculate anno_nascita substring(${codice_fiscale},7,2)
calculate mese_nascita substring(${codice_fiscale},9,1)
calculate giorno_nascita if(number(substring(${codice_fiscale}, 10, 2)) > 31, number(substring(${codice_fiscale}, 10, 2)) - 40, substring(${codice_fiscale}, 10, 2))
calculate mese_nascita_num if(${mese_nascita} = ‘A’, ‘01’, if(${mese_nascita} = ‘B’, ‘02’, if(${mese_nascita} = ‘C’, ‘03’, if(${mese_nascita} = ‘D’, ‘04’, if(${mese_nascita} = ‘E’, ‘05’, if(${mese_nascita} = ‘H’, ‘06’, if(${mese_nascita} = ‘L’, ‘07’, if(${mese_nascita} = ‘M’, ‘08’, if(${mese_nascita} = ‘P’, ‘09’, if(${mese_nascita} = ‘R’, ‘10’, if(${mese_nascita} = ‘S’, ‘11’, ‘12’)))))))))))
calculate secolo if(number(${anno_nascita}) < 30, ‘20’, ‘19’)
calculate data_nascita concat(${secolo}, ${anno_nascita}, ‘-’, ${mese_nascita_num}, ‘-’, if(string-length(${giorno_nascita}) = 1, concat(‘0’, ${giorno_nascita}), ${giorno_nascita}))
calculate data_nascita_2 format-date(${data_nascita},‘%e-%n-%Y’)
calculate eta int((today() - date(${data_nascita})) div 365.25)
calculate status if(${eta} < 18, ‘minorenne’, if(${eta} <= 20, ‘maggiorenne’, ‘docente’))

  1. A-Z ↩︎

I posted the wrong one, check this:

text codice_fiscale Codice Fiscale Utilizzare solo caratteri maiuscoli true regex(., ‘[1]{6}\d{2}[A-Z]\d{2}[A-Z]\d{3}[A-Z]$’)
calculate anno_nascita substr(${codice_fiscale},6,8)
calculate mese_nascita substr(${codice_fiscale},8,9)
calculate giorno_nascita if(number(substr(${codice_fiscale}, 9, 11)) > 31, number(substr(${codice_fiscale}, 9, 11)) - 40, substr(${codice_fiscale}, 9, 11))
calculate mese_nascita_num if(${mese_nascita} = ‘A’, ‘01’, if(${mese_nascita} = ‘B’, ‘02’, if(${mese_nascita} = ‘C’, ‘03’, if(${mese_nascita} = ‘D’, ‘04’, if(${mese_nascita} = ‘E’, ‘05’, if(${mese_nascita} = ‘H’, ‘06’, if(${mese_nascita} = ‘L’, ‘07’, if(${mese_nascita} = ‘M’, ‘08’, if(${mese_nascita} = ‘P’, ‘09’, if(${mese_nascita} = ‘R’, ‘10’, if(${mese_nascita} = ‘S’, ‘11’, ‘12’)))))))))))
calculate secolo if(number(${anno_nascita}) < 30, ‘20’, ‘19’)
calculate data_nascita concat(${secolo}, ${anno_nascita}, ‘-’, ${mese_nascita_num}, ‘-’, if(string-length(${giorno_nascita}) = 1, concat(‘0’, ${giorno_nascita}), ${giorno_nascita}))
calculate data_nascita_2 format-date(${data_nascita},‘%e-%n-%Y’)
calculate eta int((today() - date(${data_nascita})) div 365.25)
calculate status if(${eta} < 18, ‘minorenne’, if(${eta} <= 20, ‘maggiorenne’, ‘docente’))

  1. A-Z ↩︎