Skip to content

Instantly share code, notes, and snippets.

@alainperry
Last active March 16, 2017 01:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alainperry/d473644986770eff111b56711b484207 to your computer and use it in GitHub Desktop.
Save alainperry/d473644986770eff111b56711b484207 to your computer and use it in GitHub Desktop.
Code groovy plutôt sale (mais très fonctionnel) adapté de http://stackoverflow.com/a/3911987/1168698 pour convertir un montant (peut en réalité être utilisé pour tout nombre) en lettres.
Number.metaClass.formatAsCurrency { withWords = false ->
def puissances = ["", "mille", "million", "milliard", "billion", "billiard", "trillion", "trilliard"]
def dizaines = ["", "", "vingt", "trente", "quarante", "cinquante", "soixante", "soixante", "quatre-vingt", "quatre-vingt"]
def unites = ["", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf", "dix", "onze", "douze", "treize", "quatorze", "quinze", "seize", "dix-sept", "dix-huit", "dix-neuf"]
def chiffres = ["", ""] + unites[2..10]
def unitesEnLettres = { nombre ->
// débrayage immédiat pour 80, ce qui simplifie le code ensuite
if (nombre == 80)
return dizaines[8] + 's'
int dizaine = nombre / 10
int unite = nombre % 10
unite += dizaine in [1, 7, 9] ? 10 : 0 // 1x, 7x et 9x sont des dizaines particulières
def sep
if (unite == 0)
sep = ''
else if (unite == 1 && dizaine == 8) // 81
sep = '-'
else if (unite == 1 || (unite == 11 && dizaine == 7)) // dizaines "et un" + 71 (mais pas 91)
sep = ' et '
else if (dizaine > 1) // autres cas >= 20
sep = '-'
else
sep = '' // < 20
return "${dizaine > 0 ? dizaines[dizaine] + sep : ''}${unites[unite]}"
}
def centainesEnLettres = { nombre ->
int centaines = nombre / 100
int reste = nombre % 100
def resultat = ''
resultat += centaines > 0 ? "${chiffres[centaines]} cent" : ''
resultat += reste > 0 ? " ${unitesEnLettres(reste)}" : centaines > 1 ? 's' : ''
return resultat
}
def nombreEnLettres = { nombre ->
if (nombre == 0)
return "zéro"
def valeurs = [:]
for (int i in (puissances.size()..0)) {
def val = ((nombre / (10 as BigInteger).pow(i * 3)) as BigInteger) % 1000
if (val) valeurs[i] = val
}
def resultat = ''
valeurs.each { p, v ->
switch (p) {
case 1:
resultat += (v > 1 ? "${centainesEnLettres(v)} " : '')
resultat += (v > 0 ? 'mille ' : '')
break
case 0:
resultat += centainesEnLettres(v)
break
default:
resultat += "${centainesEnLettres(v)} ${puissances[p]}${v > 1 ? 's' : ''} "
}
}
return resultat.toString()
}
if (!withWords) {
java.text.NumberFormat.currencyInstance.format(delegate)
} else {
def montantEntier = (delegate as BigDecimal).setScale(0, java.math.RoundingMode.FLOOR) as BigInteger
def res = "${nombreEnLettres(montantEntier as BigInteger)} ${montantEntier % 1000000 == 0 && montantEntier > 0 ? "d'" : ''}euro${montantEntier > 1 ? 's' : ''}"
def montantDecimal = ((delegate as BigDecimal) - montantEntier) * 100
res += montantDecimal > 0 ? "${montantEntier > 0 ? ' et ' : ''} ${unitesEnLettres(montantDecimal as int)} centime${montantDecimal > 1 ? 's' : ''}" : ""
res.replaceAll(/\s+/, " ").trim()
}
}
def tests = [0.13, 1.76, 9.11, 19.02, 21.15, 28.17, 71.16, 72.13, 80.18, 81.19, 89.99, 90.45, 91.81, 97.83, 100.93, 101.80, 110.07, 111.01, 120, 200, 201, 232, 999, 1000, 1001, 10000, 10001, 100000, 2000000, 3000000000, 2147483647, 2147483647824, 2147483647824584, 2147483647824584568, 2147483647824584341864.15, 700000000000000000000000.76]
tests.each { n ->
println "${n.formatAsCurrency()} -> ${n.formatAsCurrency(true)}"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment