You're integrating a weather API for a side project. The docs say the response includes a temp field, no units specified. You render the value and your UI tells users it's currently 98 degrees outside. Fahrenheit — fine. Except the server is in Germany, and the API returns Celsius, and you just told someone in San Francisco it's basically body temperature outside on a pleasant spring day. Nobody files a bug report, but someone quietly closes your app and opens a different one.
This is the kind of mistake that's easy to make once, because three separate temperature scales are genuinely in active use around the world, and the names aren't always explicit in API responses, config files, or sensor data. It helps to understand where each scale came from, why it persists, and how to convert between them without the kind of arithmetic that makes mistakes likely.
Where Fahrenheit came from
Daniel Gabriel Fahrenheit was a Polish-German physicist and instrument maker who, in the early 1700s, built some of the first reliable mercury thermometers. He needed a scale. For his zero point, he chose the coldest temperature he could reliably reproduce in his lab — a brine mixture of water, ice, and ammonium chloride. For his upper reference point, he used human body temperature, aiming for 96 degrees (later revised to 98.6°F as calibration improved).
The result is a scale that, within the range humans actually live and work, is reasonably fine-grained. Zero is "extremely cold, almost dangerously so." 100 is "hotter than the human body." For everyday weather — somewhere between 0°F and 100°F — the scale gives you a number that intuitively communicates something about how to dress. That's part of why it stuck in the United States, where the metric system never fully displaced the older conventions.
Where Celsius came from
Anders Celsius, a Swedish astronomer, proposed his scale in 1742. He originally used 100 as the freezing point and 0 as boiling — reversed from what we use now. The version we're familiar with, where water freezes at 0°C and boils at 100°C, was popularized after his death, partly by Carl Linnaeus.
The elegance of Celsius is that it's anchored to something universal and reproducible: the behavior of water at standard atmospheric pressure. Everyone on Earth can independently verify what 0°C and 100°C mean, using nothing but a pot of water and a thermometer. That's a stronger foundation than "the coldest brine mixture I could make in Gdańsk in 1714."
Celsius is used everywhere the metric system is standard, which is essentially every country in the world except the United States, Liberia, and Myanmar.
Where Kelvin came from, and why it matters for science
William Thomson — later Lord Kelvin — took the logical next step in the mid-1800s: instead of anchoring a scale to water's behavior, anchor it to the actual theoretical minimum temperature. Absolute zero is the point at which particles have minimal thermal energy. It cannot, in principle, go lower. That point is 0 K, which corresponds to −273.15°C.
The Kelvin scale uses the same degree size as Celsius, just shifted. 0°C is 273.15 K. 100°C is 373.15 K.
This matters enormously in physics and engineering. When you're working with gas laws, thermodynamics, or any formula that involves temperature ratios, you need Kelvin. If you try to use Celsius in the ideal gas law — PV = nRT — and you plug in 0°C for absolute zero conditions, you get a temperature of zero and the formula collapses. All the thermodynamic relationships assume an absolute scale. Using Celsius or Fahrenheit in those formulas produces wrong answers, sometimes silently.
The formulas you actually need
Converting between these three scales is straightforward arithmetic once you have the right formula. The one that trips people up most is Fahrenheit to Celsius, because the offset (32°F = 0°C) and the degree size (1°C = 1.8°F) are both part of the conversion.
°F to °C: (°F − 32) × 5/9
°C to °F: (°C × 9/5) + 32
°C to K: °C + 273.15
K to °C: K − 273.15
°F to K: (°F − 32) × 5/9 + 273.15
K to °F: (K − 273.15) × 9/5 + 32
The direction of subtraction is where bugs hide. (F - 32) × 5/9 versus F × 5/9 - 32 — the second one is wrong, and if you're doing this in code without unit tests, it'll silently return a value that looks plausible enough to miss.
def celsius_to_fahrenheit(c: float) -> float:
return c * 9/5 + 32
def fahrenheit_to_celsius(f: float) -> float:
return (f - 32) * 5/9
def celsius_to_kelvin(c: float) -> float:
return c + 273.15
def kelvin_to_celsius(k: float) -> float:
if k < 0:
raise ValueError(f"Kelvin cannot be negative, got {k}")
return k - 273.15
Notice the guard on kelvin_to_celsius. Negative Kelvin is physically impossible. If your data pipeline is passing negative Kelvin values, something upstream is broken and you want to know immediately, not silently compute a Celsius temperature below absolute zero and store it in your database.
The places this bites developers
Weather APIs are the most common offender. OpenWeatherMap defaults to Kelvin (yes, really — the base API returns Kelvin unless you specify units=metric or units=imperial). The WeatherAPI.com API returns both Celsius and Fahrenheit. The NOAA APIs are Fahrenheit by default in most endpoints. Dark Sky (now Apple Weather) used Fahrenheit unless you set the locale. Almost none of them enforce the unit in the field name.
The pattern that prevents bugs: always store temperatures internally in one canonical unit (Celsius is a sensible default for non-physics applications), convert at the ingestion layer with an explicit documented function, and never accept raw API values without knowing the unit.
IoT and hardware sensors often output Kelvin or raw ADC readings that need to be converted to Kelvin first, then to Celsius. DS18B20 temperature sensors talk to microcontrollers in a raw 12-bit reading that maps to Celsius via a formula in the datasheet. Thermocouples output millivolts; converting those to temperature requires knowing the thermocouple type and referencing a lookup table. If you're working with sensor data and the temperatures seem slightly but consistently off, check whether your conversion formula is handling the baseline offset correctly.
Medical and scientific APIs frequently use Celsius, and the US-centric assumption that all temperatures in an English-language API are Fahrenheit has caused enough confusion that it's worth treating this as a known risk. Body temperature is 37°C / 98.6°F. If a system reports "patient temperature: 38.5" with no unit, that's a slight fever in Celsius, or hypothermia-with-impossible-precision in Fahrenheit.
Scientific computing in Python with NumPy or similar: temperature is frequently in Kelvin in physics and chemistry datasets. Datasets from NIST, PubChem, and similar sources default to SI units. If you're doing any kind of thermodynamic calculation and your results are off by a factor of roughly 1.37 (which is approximately 373/273), you almost certainly have a Kelvin/Celsius mismatch somewhere.
A note on "degrees" vs no degrees
Kelvin doesn't use the degree symbol. It's "300 K," not "300°K." This isn't just pedantry — the absence of "degrees" reflects that Kelvin is measuring an absolute physical quantity, not a position on an arbitrary scale. The SI standard is explicit about this, and certain scientific documentation systems will flag "°K" as an error. If you're generating output strings for scientific audiences, format Kelvin without the degree symbol.
Need to convert between Celsius, Fahrenheit, and Kelvin right now? The Unit Converter handles temperature and a dozen other unit types — no install, runs in the browser.