-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Internationalisation #8
Comments
This should give you a rough idea of how I envisioned it working (run in your console to see the output). /**
* Parse and extract our subset of the ICU DecimalFormat pattern
* to some kind of sane formatting object.
*
* @param string pattern The formatting pattern.
*
* @return object A "formatting object".
*/
function parsePattern(pattern) {
let
format = {
decimalPlaces: 0,
leftConcat: '',
rightConcat: '',
groupLengths: [],
zeros: 0
},
groupLength = 0;
pattern = pattern.split(';')[0]
for(let i = pattern.length - 1; i >= 0; i--) {
let ch = pattern[i];
switch(ch) {
case '#':
groupLength++;
break;
case ',':
format.groupLengths.push(groupLength);
groupLength = 0;
break;
case '0':
format.zeros++;
if(format.decimalPlaces > 0) {
groupLength++;
}
break;
case '.':
if(format.groupLengths.length === 0) {
format.decimalPlaces = format.zeros;
}
break;
default:
if(format.decimalPlaces > 0) {
format.leftConcat = ch + format.leftConcat;
} else {
format.rightConcat = ch + format.rightConcat;
}
break;
}
}
return format;
}
/**
* Take a number and a "currency object" and format our number accordingly.
*
* @param string num The number to format
* @param object curr The currency object.
*
* @return string The number formatted based on our currency object.
*/
function format(num, curr) {
if(isNaN(num)) {
console.error('"num" is not a number');
}
let
// we wouldn't be doing this at all in our real implementation
n = parseFloat(num),
fm = parsePattern(curr.format);
// remove decimal point, round if necessary and convert to string
n = Math.round(n * Math.pow(10, fm.decimalPlaces)) + '';
let
value = '',
group = 0,
count = 0;
const offset = n.length - fm.decimalPlaces;
for(let i = n.length - 1; i >= 0; i--) {
value = n[i] + value;
if(offset - i === 0) {
value = curr.decimalSymbol + value;
}
if(offset - i > 0) {
count++;
if(count % fm.groupLengths[group] === 0 && i !== 0) {
if(group + 1 < fm.groupLengths.length) {
group++;
}
value = curr.thousandsSeparator + value;
count = 0;
}
}
}
return (fm.leftConcat + value + fm.rightConcat).replace(/¤/g, curr.symbol);
}
const currencies = {
'uk': {
symbol: '£',
format: '¤#,##0.00',
thousandsSeparator: ',',
decimalSymbol: '.'
},
'germany': {
symbol: '€',
format: '#,##0.00 ¤',
thousandsSeparator: '.',
decimalSymbol: ','
},
'poland': {
symbol: 'zł',
format: '#,##0.00 ¤',
thousandsSeparator: ' ',
decimalSymbol: ','
},
'latvia': {
symbol: '€',
format: '¤#,##0.00',
thousandsSeparator: ' ',
decimalSymbol: ','
},
'netherlands': {
symbol: '€',
format: '¤ #,##0.00;¤ #,##0.00-',
thousandsSeparator: '.',
decimalSymbol: ','
}
};
for(var country in currencies) {
console.log(
format('1000000.896264567890000', currencies[country]),
country
);
} |
I ran it. That's cool. Using a pattern seem like a good way to go. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Think about how we would format different currencies based on the locale.
We could just replicate a subset of the functionality in ICU; in particular their patterns for formatting numbers would be useful for outputting currencies in different locales.
The text was updated successfully, but these errors were encountered: