php 56 lines · 7 steps

Locale-aware formatting with PHP's intl extension

A small class wraps PHP's intl formatters so currency and dates render correctly for one locale and timezone.

Explained by highlit
1<?php
2 
3namespace App\Support;
4 
5use IntlDateFormatter;
6use NumberFormatter;
7 
8final class LocaleFormatter
9{
10 private NumberFormatter $currency;
11 private IntlDateFormatter $dateTime;
12 private IntlDateFormatter $shortDate;
13 
14 public function __construct(
15 private readonly string $locale,
16 private readonly string $currencyCode,
17 string $timezone = 'UTC',
18 ) {
19 $this->currency = new NumberFormatter($locale, NumberFormatter::CURRENCY);
20 
21 $this->dateTime = new IntlDateFormatter(
22 $locale,
23 IntlDateFormatter::LONG,
24 IntlDateFormatter::SHORT,
25 $timezone,
26 );
27 
28 $this->shortDate = new IntlDateFormatter(
29 $locale,
30 IntlDateFormatter::MEDIUM,
31 IntlDateFormatter::NONE,
32 $timezone,
33 );
34 }
35 
36 public function money(float $amount): string
37 {
38 $formatted = $this->currency->formatCurrency($amount, $this->currencyCode);
39 
40 if ($formatted === false) {
41 throw new \RuntimeException($this->currency->getErrorMessage());
42 }
43 
44 return $formatted;
45 }
46 
47 public function dateTime(\DateTimeInterface $when): string
48 {
49 return $this->dateTime->format($when);
50 }
51 
52 public function date(\DateTimeInterface $when): string
53 {
54 return $this->shortDate->format($when);
55 }
56}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Building intl formatters once in the constructor avoids re-creating expensive objects on every format call.
  2. 2Currency and date locales belong to configuration, so injecting them keeps formatting consistent across an app.
  3. 3intl methods signal failure by returning false, so check the result before trusting the output.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Locale-aware formatting with PHP's intl extension — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code