PHPackages                             caffeine/money - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. caffeine/money

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

caffeine/money
==============

Convert monetary values to and from integer nanos to minimise floating-point rounding errors, with locale-aware formatting via ext-intl.

v0.0.4(2mo ago)06↓90.9%0BSDPHPPHP ^8.1CI passing

Since Apr 1Pushed 2mo agoCompare

[ Source](https://github.com/Phil-Venter/caffeine-money-nano)[ Packagist](https://packagist.org/packages/caffeine/money)[ RSS](/packages/caffeine-money/feed)WikiDiscussions main Synced 4w ago

READMEChangelog (4)Dependencies (5)Versions (5)Used By (0)

Nano
====

[](#nano)

[![PHP](https://camo.githubusercontent.com/3998c54117914f1626fe8e2157287a95d05177f6896b0587164a90a9864d79a0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e312d373737424234)](https://packagist.org/packages/caffeine/money)[![License](https://camo.githubusercontent.com/9e0ea96d025fa36672fafe8d0822633279836cc995a39787bb73fc09f54fe44a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d304253442d626c7565)](https://opensource.org/licenses/0BSD)[![Lint](https://github.com/Phil-Venter/caffeine-money-nano/actions/workflows/lint.yml/badge.svg)](https://github.com/Phil-Venter/caffeine-money-nano/actions/workflows/lint.yml)[![PHP 8.1](https://github.com/Phil-Venter/caffeine-money-nano/actions/workflows/php-8.1.yml/badge.svg)](https://github.com/Phil-Venter/caffeine-money-nano/actions/workflows/php-8.1.yml)[![PHP 8.2](https://github.com/Phil-Venter/caffeine-money-nano/actions/workflows/php-8.2.yml/badge.svg)](https://github.com/Phil-Venter/caffeine-money-nano/actions/workflows/php-8.2.yml)[![PHP 8.3](https://github.com/Phil-Venter/caffeine-money-nano/actions/workflows/php-8.3.yml/badge.svg)](https://github.com/Phil-Venter/caffeine-money-nano/actions/workflows/php-8.3.yml)[![PHP 8.4](https://github.com/Phil-Venter/caffeine-money-nano/actions/workflows/php-8.4.yml/badge.svg)](https://github.com/Phil-Venter/caffeine-money-nano/actions/workflows/php-8.4.yml)[![PHP 8.5](https://github.com/Phil-Venter/caffeine-money-nano/actions/workflows/php-8.5.yml/badge.svg)](https://github.com/Phil-Venter/caffeine-money-nano/actions/workflows/php-8.5.yml)

Nano-precision currency conversion and locale-aware formatting for PHP.

Converts monetary values to and from integer nanos (10⁹ nanos per major unit), minimising floating-point rounding errors during arithmetic. Wraps PHP's `ext-intl` `NumberFormatter` for locale-aware output. You hold the nano integers - `Nano` just converts and formats them.

> **If your project can support it, use a full money library instead - [`brick/money`](https://github.com/brick/money) or [`moneyphp/money`](https://github.com/moneyphp/money).** This library exists for situations where adopting one of those is not practical right away.

Requirements
------------

[](#requirements)

- PHP 8.1+
- `ext-intl`

Installation
------------

[](#installation)

```
composer require caffeine/money
```

Usage
-----

[](#usage)

### Creating an instance

[](#creating-an-instance)

```
use Caffeine\Money\Nano;

// From a locale string
$nano = Nano::forLocale('en_US');

// From an ISO 4217 currency code
$nano = Nano::forCurrency('JPY');

// From an ISO 3166-1 alpha-2 country code
$nano = Nano::forCountry('DE');

// Auto-detect from the HTTP Accept-Language header
$nano = Nano::detect(defaultLocale: 'en_US');
```

### Converting to nanos

[](#converting-to-nanos)

```
$nano = Nano::forLocale('en_US');

$nano->fromMajor(19.99);    // 19_990_000_000  (dollars → nanos)
$nano->fromMajor('$19.99'); // 19_990_000_000  (locale-formatted string)
$nano->fromMinor(1999);     // 19_990_000_000  (cents → nanos)
$nano->toNano(1.5);         // 1_500_000_000   (raw, no currency snapping)
```

### Converting from nanos

[](#converting-from-nanos)

```
$nano->toMajor(19_990_000_000); // 19.99  (float)
$nano->toMinor(19_990_000_000); // 1999   (int)
```

### Formatting

[](#formatting)

```
Nano::forLocale('en_US')->formatCurrency(19_990_000_000); // "$19.99"
Nano::forLocale('en_US')->formatDecimal(19_990_000_000);  // "19.99"
Nano::forLocale('ja_JP')->formatCurrency(2_000_000_000_000); // "￥2,000"
```

### Rounding

[](#rounding)

The default rounding mode is `PHP_ROUND_HALF_UP`. Override per-instance or per-call:

```
$nano = Nano::forLocale('en_US', PHP_ROUND_HALF_EVEN);

$nano->fromMajor(19.995, PHP_ROUND_HALF_UP);
$nano->snapToMinor(19_995_000_000, PHP_ROUND_HALF_DOWN);
```

### Snapping

[](#snapping)

`snapToMinor` aligns a nano value to the nearest minor-unit boundary (e.g. cent for USD, fil for KWD):

```
$nano = Nano::forLocale('en_US');
$nano->snapToMinor(19_995_000_000); // 20_000_000_000  ($19.995 → $20.00)

$nano = Nano::forCurrency('KWD'); // 3 decimal places
$nano->snapToMinor(1_500_500_000); // 1_501_000_000   (1.5005 → 1.501 KWD)
```

`snapToNano` rounds a float nano value to the nearest integer nano - useful after arithmetic that may produce fractional nanos:

```
$nano->snapToNano(1_000_000_000.6); // 1_000_000_001
```

### Getters

[](#getters)

```
$nano->getLocale();         // "en_US"
$nano->getCurrency();       // "USD"
$nano->getCountry();        // "US"
$nano->getFractionDigits(); // 2
$nano->getRoundingMode();   // PHP_ROUND_HALF_UP
```

Safe operating range
--------------------

[](#safe-operating-range)

Nanos are stored as PHP `int`. On 64-bit systems the safe range is ±9,223,372,036 major units (~±9.2 billion). Integer overflow beyond this range will occur silently. A 64-bit runtime is assumed.

License
-------

[](#license)

[0BSD](https://opensource.org/licenses/0BSD) - do whatever you want, no attribution required.

###  Health Score

34

—

LowBetter than 75% of packages

Maintenance83

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity36

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

4

Last Release

85d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/13363810?v=4)[Caffeinated Coder](/maintainers/phil-venter)[@Phil-Venter](https://github.com/Phil-Venter)

---

Top Contributors

[![Phil-Venter](https://avatars.githubusercontent.com/u/13363810?v=4)](https://github.com/Phil-Venter "Phil-Venter (16 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/caffeine-money/health.svg)

```
[![Health](https://phpackages.com/badges/caffeine-money/health.svg)](https://phpackages.com/packages/caffeine-money)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
