Температура

Общая модель работы с температурными единицами

Библиотека Globalize опирается на данные Unicode CLDR (Common Locale Data Repository), где единицы измерения, включая температурные шкалы, описываются как часть стандартизированной локализации. Температура в этом контексте рассматривается не как числовая величина, а как форматируемая сущность, зависящая от локали и системы измерения.

В разных регионах применяются разные шкалы:

  • Celsius (°C) — большинство стран мира
  • Fahrenheit (°F) — США и отдельные территории
  • Kelvin (K) — научные и инженерные расчёты

Globalize предоставляет унифицированный слой для форматирования этих значений без ручного управления символами и локальными правилами отображения.


Подготовка окружения Globalize для работы с единицами

Для корректной работы с температурой требуется загрузка соответствующих CLDR-данных:

import Globalize from "globalize";

// загрузка CLDR-данных (примерная структура)
import likelySubtags from "cldr-core/supplemental/likelySubtags.json";
import numbers from "cldr-numbers-full/main/en/numbers.json";
import units from "cldr-units-full/main/en/units.json";
import currencyData from "cldr-core/supplemental/numberingSystems.json";

Globalize.load(
  likelySubtags,
  numbers,
  units,
  currencyData
);

Globalize.locale("en");

Ключевым элементом для температурных единиц является пакет cldr-units-full, содержащий правила форматирования единиц измерения, включая температурные шкалы.


Форматирование температуры через unitFormatter

Основной механизм работы с температурой в Globalize реализуется через unitFormatter.

const formatTemperature = Globalize.unitFormatter("celsius");

formatTemperature(25);
// → "25°C"

Форматирование зависит от локали:

Globalize.locale("en");
Globalize.unitFormatter("fahrenheit")(72);
// → "72°F"

Globalize.locale("fr");
Globalize.unitFormatter("celsius")(25);
// → "25 °C"

Разница заключается не только в символах, но и в пробелах, порядке и типографике, которые определяются CLDR.


Поддерживаемые температурные единицы

Globalize поддерживает несколько типов температурных единиц через унифицированные ключи:

  • celsius
  • fahrenheit
  • kelvin

Каждая единица является частью системы unitFormatter, которая обрабатывает локализационные правила автоматически.

const c = Globalize.unitFormatter("celsius");
const f = Globalize.unitFormatter("fahrenheit");
const k = Globalize.unitFormatter("kelvin");

c(0);   // "0°C"
f(32);  // "32°F"
k(273); // "273 K"

Локализационные различия представления температуры

Разные локали влияют не только на символ, но и на оформление строки:

Английская локаль

Globalize.locale("en");
Globalize.unitFormatter("celsius")(20);
// "20°C"

Французская локаль

Globalize.locale("fr");
Globalize.unitFormatter("celsius")(20);
// "20 °C"

Немецкая локаль

Globalize.locale("de");
Globalize.unitFormatter("celsius")(20);
// "20 °C"

Различия проявляются в пробеле перед символом и форматировании знаков.


Форматирование с учётом контекста (narrow, short, long)

CLDR поддерживает несколько форм представления единиц измерения:

  • short — компактная форма (°C)
  • narrow — максимально сокращённая (C)
  • long — полная форма (20 degrees Celsius)

Globalize позволяет учитывать эти формы при форматировании.

const shortC = Globalize.unitFormatter("celsius", { form: "short" });
const longC = Globalize.unitFormatter("celsius", { form: "long" });

shortC(30);
// "30°C"

longC(30);
// "30 degrees Celsius"

Интеграция температуры с числовым форматированием

Температурные значения часто требуют комбинирования с numberFormatter, особенно при работе с округлением или диапазонами.

const numberFormatter = Globalize.numberFormatter({ minimumFractionDigits: 1 });
const tempFormatter = Globalize.unitFormatter("celsius");

const value = 21.456;

tempFormatter(numberFormatter(value));
// "21.5°C"

Числовой формат применяется до передачи значения в форматтер единиц.


Работа с диапазонами температур

CLDR описывает правила для отображения диапазонов единиц измерения, которые могут использоваться для погодных данных.

const formatC = Globalize.unitFormatter("celsius");

function formatRange(min, max) {
  return `${formatC(min)} – ${formatC(max)}`;
}

formatRange(18, 25);
// "18°C – 25°C"

В локализованных системах диапазон может использовать специальные символы или пробелы в зависимости от региона.


Автоматическое переключение шкалы

Globalize не выполняет автоматическую конвертацию между шкалами, однако архитектура позволяет построить слой адаптации поверх форматтеров.

function toFahrenheit(c) {
  return (c * 9) / 5 + 32;
}

const formatF = Globalize.unitFormatter("fahrenheit");

formatF(toFahrenheit(0));
// "32°F"

Такой подход разделяет ответственность: вычисления выполняются отдельно от локализации.


Использование с динамическими данными

При работе с погодными API форматирование температуры часто становится финальным этапом отображения данных:

const formatTemp = Globalize.unitFormatter("celsius");

function renderWeather(data) {
  const temp = data.current.temperature;
  return {
    temperature: formatTemp(temp),
    condition: data.current.condition
  };
}

Форматирование остаётся стабильным независимо от источника данных.


Кеширование форматтеров

Создание форматтера в Globalize является относительно дорогой операцией, поэтому используется кеширование:

const cache = new Map();

function getFormatter(unit) {
  if (!cache.has(unit)) {
    cache.set(unit, Globalize.unitFormatter(unit));
  }
  return cache.get(unit);
}

getFormatter("celsius")(15);
// "15°C"

Это особенно важно при массовой обработке температурных рядов.


Температура в составе сложных единиц

CLDR позволяет комбинировать единицы измерения, например скорость ветра и температуру в погодных интерфейсах. В таких случаях Globalize применяется для каждого поля отдельно:

const formatC = Globalize.unitFormatter("celsius");
const formatKm = Globalize.unitFormatter("kilometer-per-hour");

const weather = {
  temp: formatC(22),
  wind: formatKm(15)
};

Каждая единица обрабатывается независимо, сохраняя семантическую чистоту данных.


Обработка отрицательных температур

Globalize корректно обрабатывает отрицательные значения без дополнительных настроек:

const formatC = Globalize.unitFormatter("celsius");

formatC(-5);
// "-5°C"

Локаль влияет только на оформление, а знак минус стандартизирован Unicode.


Особенности представления в научных локалях

В научных и технических локалях часто используется Kelvin без символа градуса:

Globalize.locale("en");

Globalize.unitFormatter("kelvin")(300);
// "300 K"

Отсутствие символа градуса является частью CLDR-правил, а не особенностью реализации.


Использование в UI-слое приложений

Температурное форматирование в Globalize обычно располагается на границе UI-слоя:

const formatC = Globalize.unitFormatter("celsius");

function TemperatureView({ value }) {
  return {
    text: formatC(value)
  };
}

Такое разделение предотвращает проникновение локализационной логики в бизнес-слой.


Согласованность температурных представлений

Единообразие отображения достигается за счёт следующих принципов:

  • единый источник CLDR-данных
  • отсутствие ручной конкатенации символов
  • использование единых formatter-объектов
  • разделение вычислений и представления

Эти принципы обеспечивают предсказуемое поведение температурных значений в любых локалях и сценариях.