Chilling hours calculator
Of eight hourly readings, five fell below 7.2 °C, so the orchard logged 5 chilling hours. Paste your hourly temperatures, pick the threshold, and see whether the season meets the chill your apples, peaches or cherries need. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Threshold
- 7.2
- Temperatures count
- 8 C
- Chilling hours
- 5
- Hours above or equal
- 3
- Fraction below
- 0.625
Winter chill accumulation decides whether temperate fruit trees—apples, peaches, cherries, plums, almonds, and many others—break dormancy cleanly in spring. Growers and extension agents still ask a simple first question: how many hours of the season sat below the chill threshold? This chilling hours calculator accepts an ordered series of hourly temperature readings, compares each reading to a threshold (classically 7.2 °C or 45 °F), and returns the count of hours strictly below that base. You can attach a crop requirement in hours to see whether the series meets dormancy needs, and how large the shortfall or surplus is. No network calls, no random seeds, and no calendar clocks—only the temperatures you supply.
What chilling hours measure and why the simple model still matters
Chilling hours are a practical proxy for the cold exposure required to complete endodormancy in many deciduous fruit and nut species. Nurseries and cultivar catalogs often publish a chill requirement as a number of hours, commonly referenced to a base near 7.2 degrees Celsius (about 45 degrees Fahrenheit). The simple model used here follows that tradition: each hourly observation that falls strictly below the chosen threshold contributes one chilling hour; observations at or above the threshold contribute zero.
That rule is intentionally transparent. More elaborate schemes such as the Utah model weight temperature bands and can cancel chill after warm spells, and the Dynamic model tracks intermediate chill portions—both are valuable research tools—but growers often need a first-pass tally that matches the language of a catalog line “needs 800 chill hours.” By counting only hours below threshold you obtain a number you can explain in one sentence to a field crew or a student.
The calculator does not invent missing hours or interpolate between stations; it treats your series as already hourly and complete for the period you care about. If you feed daily means you will under- or over-count relative to true hourly exposure, so prefer logger or reanalysis series at one-hour resolution when decisions matter.
What you can do with it
Orchard winter chill tracking
Ingest hourly logger or weather-station temperatures each week, count hours below 7.2 °C, and compare against the cultivar chill requirement before spring spray and pruning plans lock in.
Horticulture teaching labs
Give students short synthetic hourly series and let them verify by hand that only readings strictly below the threshold add to chilling hours, including the edge case of equality.
FAQ
How are chilling hours counted?
Each hourly temperature strictly below the threshold adds one chilling hour. Readings at or above the threshold add zero. Defaults are 7.2 °C or 45 °F depending on unit.
Does the calculator use the Utah or Dynamic chill model?
No. This capability implements the simple below-threshold hour count used in many catalog requirements. Weighted Utah units and Dynamic chill portions are out of scope here.
What if my temperature equals the threshold exactly?
Equality does not count. Only t < threshold contributes. For example 7.2 with threshold 7.2 adds zero chilling hours.
Can I check a crop chill requirement?
Yes. Send requirement as non-negative hours needed. Omit requirement to skip those fields.
Can I use daily average temperatures instead of hourly readings?
It is better not to. Each reading counts as one hour, so daily means will under- or over-count the real cold exposure. Use hourly logger or weather-station data when the decision matters.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/bio/chilling-hours \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"temperatures":[8,6.5,5,4.2,7.2,9,3.5,6]}'const res = await fetch("https://api.kit.forhosting.com/bio/chilling-hours", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"temperatures": [
8,
6.5,
5,
4.2,
7.2,
9,
3.5,
6
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/bio/chilling-hours",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"temperatures": [
8,
6.5,
5,
4.2,
7.2,
9,
3.5,
6
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/bio/chilling-hours", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"temperatures":[8,6.5,5,4.2,7.2,9,3.5,6]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"temperatures":[8,6.5,5,4.2,7.2,9,3.5,6]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/bio/chilling-hours", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"temperatures": [
8,
6.5,
5,
4.2,
7.2,
9,
3.5,
6
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "bio.chilling_hours",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
What chilling hours measure and why the simple model still matters
Unit is a label shared by temperatures and threshold: choose Celsius or Fahrenheit and keep every number on that scale. The endpoint does not convert between scales, which avoids silent double conversion when you already work in Fahrenheit station data.
Input contract, response fields, and validation behaviour
Optional threshold defaults to 7.2 when unit is C and to 45 when unit is F; override it when your cultivar sheet uses a different base. Optional unit is the closed set C or F and defaults to C. Optional requirement is a non-negative number of hours the crop is said to need; when you omit it, requirement-related fields are omitted from the response rather than returned as null. Example: eight hourly Celsius readings 8.0, 6.5, 5.0, 4.2, 7.2, 9.0, 3.5, 6.0 with the default 7.2 threshold yield five chilling hours because 7.2 itself is not strictly below the base. On success the body echoes temperatures_count, threshold, and unit; reports chilling_hours and hours_above_or_equal; gives fraction_below as chilling hours divided by the series length; and includes a short formula string plus a human message summarizing the tally. When requirement is present you also receive requirement_met, shortfall, and surplus so dashboards can color a pass or fail without recomputing. Empty series, non-finite readings, more than twenty thousand hours, negative requirement, or an unknown unit fail with invalid_input naming the problem; failed validation is not billed. Pair the response with your own charts if you need a time series plot; this endpoint returns aggregate counts only.
Where a chilling hours API earns its keep in production
Classroom labs in horticulture and phenology use small synthetic series so students see how a single warm hour drops out of the tally when it sits on the threshold. Replace the simple model later with Utah or Dynamic scores only when your agronomy team standardizes on those units; until then a clear below-threshold count remains the most searchable and most auditable first answer for winter dormancy planning. Orchard management software can push each winter week of station data through this endpoint and store chilling_hours beside soil moisture and frost risk without embedding chill logic in every client. Breeding programs comparing sites can batch many series with a fixed threshold and requirement, then filter on requirement_met for cultivar placement.
Integration use cases
Site and cultivar suitability screens
Batch historical winters for candidate planting sites with a fixed threshold and requirement; keep sites where requirement_met is true across enough seasons.
Technical questions
What does the chilling hours calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.