Get currency ISO 4217 code based on locale - php

Say, if I parse HTTP Accept-Language header with Locale::acceptFromHttp is there an easy and reliable way to get user's preferred currency based on this locale identifier? Like "USD" for "en-US".
I wish there was a way to do this with PHP intl extension but so far was unable to find my answer in the manual. I saw Zend Framework can do this with Zend_Currency but it's just too bloated for my particular software.
Any other libs or ways of achieving this? Since there must be a lot of locale identifiers a simple switch is a bit of overkill.

You can do this in both PHP 4 and PHP 5 using setlocale() and localeconv():
$locale = Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);
setlocale(LC_MONETARY, $locale);
print_r(localeconv());
Sample output:
Array
(
[decimal_point] => .
[thousands_sep] =>
[int_curr_symbol] => EUR
[currency_symbol] => €
[mon_decimal_point] => ,
[mon_thousands_sep] =>
[positive_sign] =>
[negative_sign] => -
[int_frac_digits] => 2
[frac_digits] => 2
[p_cs_precedes] => 1
[p_sep_by_space] => 1
[n_cs_precedes] => 1
[n_sep_by_space] => 1
[p_sign_posn] => 1
[n_sign_posn] => 2
[grouping] => Array
(
)
[mon_grouping] => Array
(
[0] => 3
[1] => 3
)
)
The ISO 4217 code is contained within the resulting array's int_curr_symbol key.

A bit late but you can get it with \NumberFormatter:
<?php
$currencyPerLocale = array_reduce(
\ResourceBundle::getLocales(''),
function (array $currencies, string $locale) {
$currencies[$locale] = \NumberFormatter::create(
$locale,
\NumberFormatter::CURRENCY
)->getTextAttribute(\NumberFormatter::CURRENCY_CODE);
return $currencies;
},
[]
);

Related

php array_diff not working on this compare

I have two arrays:
(
[lineCode] => C
[serviceRequest] => Ext, Warr auth.#19091100102 for $650.64 to be paid by c/card(fax#817-785-6700). Cust owes balance
[skillCode] => 90SB
[opCode] => 90SB
[jobType] => CUSTOMER
[techNo] =>
[lineStatus] => C
)
(
[id] => 755350
[rid] => 252178
[lineCode] => C
[serviceRequest] => Ext, Warr auth.#19091100102 for $650.64 to be paid by c/card(fax#817-785-6700). Cust owes balance
[skillCode] => 90SB
[opCode] => 90SB
[jobType] => CUSTOMER
[techNo] =>
[lineStatus] => W
[timeA] => 1575497139
[timeC] => 0
)
When i perform $diff = array_diff($arry1, $arry2);, it does not find the lineStatus to be different. Could it be because of service Request line with special characters? Although as a test, I set both lines to blanks, and it still did not see the difference.
Any help would be great. Stumped for the day.
UPDATE w/ MORE INFO
As this is part of a larger loop through mulitple arrays, the diff check before this one above is below:
$arry1= Array
(
[lineCode] => B
[serviceRequest] =>
[skillCode] => 15
[opCode] => 15
[jobType] => CUSTOMER
[techNo] => A05
[lineStatus] => C
)
$arry2= Array
(
[id] => 755362
[rid] => 252184
[lineCode] => B
[serviceRequest] =>
[skillCode] => 15
[opCode] => 15
[jobType] => CUSTOMER
[techNo] => A05
[lineStatus] => W
[timeA] => 1575504138
[timeC] => 0
)
$diff= Array
(
[lineStatus] => C
)
the code for the diff is $diff=array_diff($arry1,$arry2);
If it works correctly for this one, why would it not for the next.
Why does it not find it the way you originally did it...?
array_diff() does not care about key-value combinations, it only compares the values in the different arrays that are compared.
To better understand what's happening: if in your updated data you introduce an array element [dummy] => "C" into $arry2 you will no longer get [lineStatus] => "C" returned into $diff. As the value C is now found in both $arry1 and $arry2.
Have a look at this demo

PHP locale with money_format not working with fr_CA

I have this simple code:
<?php
setlocale('LC_MONETARY', 'fr_CA.UTF-8');
echo money_format('%+#10n', '-4562.75834');
print_r(localeconv());
?>
Who normally should give -4 562,76 $. But the result is always this:
(4 562,76 $)
The output of localeconv():
Array
(
[decimal_point] => .
[thousands_sep] =>
[int_curr_symbol] => CAD
[currency_symbol] => $
[mon_decimal_point] => ,
[mon_thousands_sep] =>
[positive_sign] =>
[negative_sign] => -
[int_frac_digits] => 2
[frac_digits] => 2
[p_cs_precedes] => 0
[p_sep_by_space] => 1
[n_cs_precedes] => 0
[n_sep_by_space] => 1
[p_sign_posn] => 1
[n_sign_posn] => 0
[grouping] => Array
(
)
[mon_grouping] => Array
(
[0] => 3
[1] => 3
)
)
We can see that negative sign should be - but not ()
The locale on the server (which is Debian 7), is installed:
# locale-gen
Generating locales (this might take a while)...
en_CA.UTF-8... done
fr_CA.ISO-8859-1... done
fr_CA.UTF-8... done
Generation complete.
I have tried with PHP 5.4.45 and 5.6.17
You have put the LC_MONETARY between single quotes.
It needs to live as a const variable which is set as not in quotes.
setlocale(LC_MONETARY, 'fr_CA.UTF-8');

How to convert this date format to PHP

From the JSON snippet that i got from a .net API query, I can't seem to convert the date /Date(1393477200000)/ properly in PHP.
I tried to do echo date('m/n/Y','1393477200000'); but it is still outputting the wrong date which is 07/7/46127 instead of the correct date of 2/27/2014.
Array
(
[status] => ok
[results] => Array
(
[0] => Array
(
[PROJECT_ID] => 1
[COMPANY_ID] => 1
[PROJECT_NAME] => The "Getting Started" Project
[PROJECT_NUMBER] => 000001
[CAN_OPEN_PROJECT] => 1
[DATE_START_DATE] => /Date(1393477200000)/
[DATE_END_DATE] => /Date(1440648000000)/
[PROJECT_DESC] =>
[TASK_NUMBER] => 6
[DATE_CREATED] => /Date(1409142925980)/
[TOTAL_TASKS] => 1
[TOTAL_INCOMPLETE_TASKS] => 1
[TOTAL_COMPLETED_TASKS] => 0
Any ideas how to format [DATE_START_DATE] correctly in PHP? Thanks!
Divide your unix-timestamp by 1000, then use date(..).
$date = '1393477200000';
echo date("m/d/y", $date/1000);
Its that simple.
Result:
02/27/14
echo date('m/d/Y',(1393477200000/1000)); U have to truncate last 3 digit.
The time received is in milliseconds... You have to divide by a thousand to retrieve UNIX epoch time:
echo date('m/d/Y',(1393477200000/1000));
And here is the fiddle

Extract item from an array

I want to be able to extract the output of [HostName] from this array in PHP. Thank you!
Array
(
[Protocol] => 17
[HostName] => [HG] JAILBREAK #1 - HeLLsGamers.com | 30+ LR's | FastDL
[Map] => ba_jail_hellsgamers_fx6
[ModDir] => cstrike
[ModDesc] => Counter-Strike: Source
[AppID] => 240
[Players] => 12
[MaxPlayers] => 64
[Bots] => 0
[Dedicated] => d
[Os] => l
[Password] =>
[Secure] => 1
[Version] => 1.0.0.75
[GamePort] => 27015
[ServerID] => -682722125
[GameTags] => HLstatsX:CE,alltalk,bunnyhopping,cool,drugs,free,gameme,gang,hellsgamers,hg,increased_maxplayers,jail,jailbr,nostats,startmoney
)
Like this:
echo $Array[HostName]; // output: [HG] JAILBREAK #1 - HeLLsGamers.com | 30+ LR's | FastDL
where $Array is the array you printed and copied here.
I recommend you start reading stuff from php.net - as this is the most basic thing you can do.
Thats the most simplest question .........
Just use this
echo $Your_array[HostName];

Using setlocale() doesn't affect PHPs number conversions

I have the following script:
<?php
$test = "2.5";
echo (float)$test;
echo "\n";
$r = setlocale(LC_ALL, "da_DK.UTF8");
setlocale(LC_ALL, NULL);
print_r(localeconv());
echo "\n";
echo (float)$test;
echo "\n";
echo (float)"2,5";
echo "\n";
?>
Which generates the following output:
2.5
Array
(
[decimal_point] => ,
[thousands_sep] => .
[int_curr_symbol] => DKK
[currency_symbol] => kr
[mon_decimal_point] => ,
[mon_thousands_sep] => .
[positive_sign] =>
[negative_sign] => -
[int_frac_digits] => 2
[frac_digits] => 2
[p_cs_precedes] => 1
[p_sep_by_space] => 2
[n_cs_precedes] => 1
[n_sep_by_space] => 2
[p_sign_posn] => 4
[n_sign_posn] => 4
[grouping] => Array
(
[0] => 3
[1] => 3
)
[mon_grouping] => Array
(
[0] => 3
[1] => 3
)
)
2,5
2
The very last line which reads 2 - I would have expected that to read 2,5 - and as far as I can see on the PHP documentation, it should.
If the second call to setlocale is omitted then the output of localeconv() is inconsistent with the danish locale - for reasons that are unclear to me.
(float)"2,5" equals 2 (note the comma) whereas (float)"2.5" equals 2.5. The reason can be read in the manual:
If the string does not contain any of the characters '.', 'e', or 'E' and the numeric value fits into integer type limits (as defined by PHP_INT_MAX), the string will be evaluated as an integer. In all other cases it will be evaluated as a float.
Type casting is not affected by setlocale().

Categories