Währungsumrechnung mit Zend_Currency und Anzeige des korrekten WährungssymbolsCurrency conversion using Zend_Currency and displaying correct currency symbols

When developing i18n’ed (web) applications it is important to keep various required conversions in mind, such as currency conversions when dealing with payments. In the case of the Zend Framework (ZF) this conversion can be done using Zend_Currency and optionally a conversion service based on the Zend_Currency_CurrencyInterface.

One confusing thing when it comes to dealing with Zend_Currency is the fact that it is locale-based, meaning that when instantiating Zend_Currency objects like in the following example the currency (symbol) used to output the value set is determined by the locale (either automatically determined by Zend_Currency based on the client’s locale, or by specifying it explicitely in the $options array of Zend_Currency’s constructor).

Thus, you cannot expect that the following example will always display ‘USD’ just because you’ve set it in the $options array. Instead, Zend_Currency will display the currency corresponding to the locale determined, or specified explicitly:

$curr = new Zend_Currency(array(
  'value' => 100,
  'currency' => 'USD'
));

echo $curr->toString();
// will *probably* display "USD" -> if locale is set to "en_US", "en_XXX" in general
// will *not* display "USD" if locale is set to "de_AT" for instance -> will display 'EUR' in this case as USD in not a region-valid currency in this case, "EUR" is

This behavior can be quite confusing at first, as it is not expected to work this way. From my point of view, I would expect to see “100 USD” in the example above, independent of the locale used…

Either way, Zend_Currency depends on a valid locale to display the output string in a localized manner, e.g. “100,00 USD” vs. “100.00 USD”, which makes perfect sense. On the other hand the option “currency” specified in the constructor simply does not work as the currency to be displayed, but rather represents the currency of the value specified.

Thus, in order to display the value set in the example above in a specific currency, such as “USD” you are required to use toCurrency() together with “USD” as currency in the $options array, as shown in the following example:

// convert to localized string in a specific currency
$curr = new Zend_Currency(array('value' => $curr->getValue(), 'currency' => 'USD'));
return $curr->toCurrency($curr->getValue(), array('currency' => 'USD'));

Currency conversion

Now, that we have cleared out one of the most confusing things about Zend_Currency it is time to do some currency conversion.

There exist various online services to get current currency conversion rates, such as “http://finance.yahoo.com/d/”. It is easiest to encapsulate one of these services in a concrete implementations of Zend_Currency_CurrencyInterface, as shown in the following example:

class Service_CurrencyConversion implements Zend_Currency_CurrencyInterface {

  public static function convertCurrency($from, $to, $amount = 1) {
    return $this->getRate($from, $to) * $amount;
  }

  public function getRate($from, $to) {
    return 1; //current conversion rate, get from corresponding (external) service
  }
}

Finally, we can wrap up this functionality in a conversion function that is contained in a currency utility class extending Zend_Currency:

class Custom_Currency extends Zend_Currency {
  public static function convertToCurrency($val, $srcCc, $dstCc, $includeCurrencyCode = false) {
    $_srcCc = mb_strtoupper($srcCc);
    $_dstCc = mb_strtoupper($dstCc);

    // dst currency
    $dst = new Zend_Currency(array(
      'value' => 0,
      'currency' => $_dstCc
    ));
    $dst->setService(new Service_CurrencyConversion());

    // src currency
    $src = new Zend_Currency(array(
      'value' => $val,
      'currency' => $_srcCc));
 
    // convert
    $dst->add($src);

    if (!$includeCurrencyCode) {
      return round($dst->getValue(), 2);
    }

    // convert to localized string
    $final = new Zend_Currency(array('value' => $dst->getValue(), 'currency' => $_dstCc));
    return $final->toCurrency($final->getValue(), array('currency' => $_dstCc));
  }
}

Using this approach you get a conversion function that optionally displays localized strings in the currency you expect 🙂

Explicity specifying currency symbol

Another approach to display specific currency symbols is to use the “symbol” options when instantiating Zend_Currency objects. Although this will display exactly the currency symbol specified you will most likely be forced to determine the appropriate symbol yourself rather than rely on Zend_Currency’s innerworkings to translate ISO currency codes such as ‘USD’ to the corresponding symbol ($). This approach only makes sense if you have a (very) limited list of supported currencies and symbols.

You may also like...

1 Response

  1. its actually a nice article..i was looking for..

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.