Magentoを日本向けに使おうと思うと、フリガナより問題になるのが端数処理です。
Magentoの標準処理では端数処理をPHP標準関数のroundで行っているため、日本円以外の小数点以下桁数を持たない通貨(ベトナム・ドンやインドネシア・ルピア、韓国・ウォン、ハンガリー・フォリントなど)では価格の表示で違和感が生じます。

今回Magento2.3向けに改良された日本向けエクステンションでは、端数処理が改められています。
今回はこの新しくなった端数処理についてご説明しましょう。

Magento2.2までの端数処理

Magento2.2までは、PHP標準の以下の関数を設定で切り替えて使用していました。

  • round(四捨五入)
  • ceil(切り上げ)
  • floor(切り捨て)

この仕組はMagento1系から引き継いできたもので、比較的単純な実装方法を用いていました。
ただ、単純な反面、様々な言語と通貨の組み合わせに対して検証が十分に及んでいない面もあったことは事実です。

Magento2.3での端数処理

Magento2.3で改良された端数処理ではInternational Components for Unicode(ICU)を採用し、通貨の表示や端数処理を行っています。

MagentoCommunity_CurrencyPrecisionで利用できる端数処理

端数処理を担当しているのは、MagentoCommunity_CurrencyPrecisionです。
このエクステンションでは、ICUライブラリを利用するPHPの国際化拡張モジュー(intl)の機能を使用して、端数処理を行います。
intlモジュール自体はMagento2のインストール要件に含まれているものなので、このエクステンションをインストールするために、新たに何かが求められるということはありません。

利用できる端数処理方法

ICUでは以下の7種類の端数処理方法が用意されています。
実際にどういう計算結果になるのか違いがわかりにくいので、ICUの公式サイトの表を見てみることにしましょう。ここから先はICU公式サイトの表と見比べながらお読みください。

例では2.0から-2.0までの間で端数処理がどうなるかを示しています。

Ceilingが切り上げ。Floorが切り捨て。Halfupが四捨五入を表しています。
DownからHalfdownまでが今回新たに追加された処理方法です。

Down

Downの場合は、端数を切り捨てます。CeilingとFloorとの違いは、0以上と0以下の場合での処理方法です。
Downの場合、0以下の場合は隣接する最も大きい負の整数値に丸めます。0以上の場合は、隣接する最も小さい正の整数値に丸めます。

Up

Upの場合は、Downと逆に端数を切り上げます。Downと概ね真逆の動きをします。0以下の場合は隣接する最も小さい負の整数値に丸めます。
0以上の場合は隣接する最も大きい正の整数値に丸めます。

HalfevenとHalfdown

あまり目にしない丸め方法であるこの2つの方法ですが、以下の点で挙動が異なります。

Halfevenは、真ん中の値(つまり5)の場合、整数桁が偶数になるように丸めます。-1.5は-2となり、0.5は0となります。
Halfdownは、Halfevenとは逆で、5の場合は整数桁が奇数になるように丸めます。-1.5は-1となり、0.5は1となります。

設定方法

Magento2.3の端数処理に関する設定は、これまでと異なり、以下の場所にあります。

店舗>設定>通貨セットアップ

端数処理設定

端数丸め処理のオプションは先程ご説明したとおり、7種類から選べます。

端数処理方法

また、2.2までの実装と同じく、日本円の場合は表示フォーマットを以下の2通りから指定できます。

  • 円記号(¥)を左に表示する
  • 漢字の「円」を右に表示する

まとめ

今回はMagento2.3での端数処理について解説しました。
CurrencyPrecisionエクステンションでは、7通りの端数丸め方法から設定ができるようになっています。
実際の処理はPHPのintlモジュールが行ってくれるので、PHPネイティブの関数は使われなくなっています。

Github上では引き続き改良を続けていきますので、不具合等を見つけられた方はお知らせいただければ幸いです。