Skip to main content
SunnyDays
Methodology

How we score the weather

Every destination on this site carries a number from 0 to 10. That number decides what you see and in what order, so you are entitled to know exactly how it is produced. Here is the whole model, including the parts that make us look bad.

What qualifies a destination

Before a destination appears on this site at all, its 7-day forecast must contain a run of at least 3 consecutive days that each pass all three checks:

These are the live values read from the settings table at render time. They are not duplicated anywhere in the codebase. Preview different values before changing them.

The short version

We score each forecast day on its own, then combine the days into a score for the whole window. We do not average the week and call it a day — averaging is how a travel site turns four grey days and one good one into "sunny".

Step 1 — scoring a single day

Each day gets a 0–10 score built from three things:

Day score = 10 × (0.40 · Temp + 0.30 · Sky + 0.30 · Dryness) Temp, Sky and Dryness are each scaled 0–1 before weighting.

The caps

Some conditions are bad enough that no amount of pleasant temperature should rescue the day, so we cap the result outright rather than let the weighting average it away:

Step 2 — scoring the window

Window score = 0.55 · trimmed mean + 0.25 · worst day + 0.20 · run coverage Run coverage is the longest unbroken stretch of good days (7.0+), as a share of the window, scaled to 0–10.

Why one great day cannot carry a week

That middle term is the whole point. A quarter of the window score is set by the worst day in it. If you fly somewhere for five days and one of those days is a washout, the washout drags the score down and stays visible in it — there is no arrangement of good days that can hide it.

The best day in a window gets no special treatment at all. It contributes only through the trimmed mean, alongside every other day. A single spectacular Tuesday does not make the week worth flying for, and the arithmetic here refuses to pretend otherwise.

Why "clear" excludes "partly cloudy"

When we say a window has three clear days, we mean three days the forecast calls clear or mainly clear. Partly cloudy days are not counted as clear. They are perfectly pleasant days and they score well — but calling them clear is the exact sleight of hand that makes weather marketing untrustworthy, so we do not do it.

We also report the count of clear days separately from the score, and never fold it in. The score answers "how good is this week overall?". The clear-day count answers "how much actual sun am I getting?". Those are different questions, and a destination can do well on the first while doing badly on the second. When that happens we show you both numbers side by side rather than the flattering one alone.

The card badge — one vocabulary

Every destination card carries a badge that describes the current window in a single phrase. That phrase is built from the same three numbers that appear elsewhere on the card: the weather score, the genuinely-clear-day count, and the peak temperature. No separate calculation is run for the badge.

Clear days: days with WMO code 0 or 1 (clear sky or mainly clear). This is the number the badge, headline, and card label all count. Partly-cloudy days are not clear days.

Two vocabularies ran in parallel until August 2026. The label used “bright days” (clear + partly-cloudy) while the badge used “clear days” (WMO 0–1 only). That split let Destin show “no clear days” on the badge while its own label said “2 bright days” — both reading from the same underlying data. The fix: one term throughout. The badge, label, and headline now all count from the same field, so they cannot contradict each other.

Badge tier follows score order. A destination scoring 8.0 or above earns the highlighted (teal pulsing) chip. Below 8.0 it gets the muted chip. Within each tier the text tells you why: cloud fraction, wet-day count, clear-day count, and peak temperature when it clears 100°F — so Dallas at 106°F and Jackson Hole at 89°F carry visibly different badges even when their clear-day counts match.

A real worked example, from today's data

This is not an illustration. It is read live from the forecast cache that powers the rest of the site, at the moment this page loaded, and it is deliberately the most awkward case we could find in it.

Newport Beach, CA · SNA

8.8
window score out of 10 · Excellent
0
genuinely clear days out of 7
Zero clear days Dull days outnumber bright ones Worst day's rain chance: 3% Worst day scores 8.5 Best day scores 9.3

What the forecast actually says: 7 cloudy / 0 wet days, no clear days in 7.

Read this before you read the score. Newport Beach scores 8.8 out of 10 and has not one genuinely clear day in the next 7. That is not a bug in the model — it is the model working. The days are dry and the temperature is good, which is what the score is measuring. The sky is grey, which is what the clear-day count is measuring. If you are flying somewhere to sit in the sun, this window is not for you, and no headline number on this site will tell you otherwise.

The days, as forecast

Date High Low Rain Sky Day score
2026-08-08 81°F 67°F 0% Overcast 8.5
2026-08-09 78°F 66°F 3% Partly cloudy 9.3
2026-08-10 82°F 66°F 1% Overcast 8.5
2026-08-11 86°F 74°F 1% Overcast 8.5
2026-08-12 85°F 73°F 0% Overcast 8.5
2026-08-13 80°F 72°F 1% Overcast 8.5
2026-08-14 81°F 70°F 1% Overcast 8.5

How the sky broke down

Bright (1) = clear + partly cloudy. Dull (6) = overcast + wet + stormy. We never describe a window as good when dull days equal or outnumber bright ones.

The model's own working, term by term

If that example looks unflattering, that is because it is. It was chosen by preferring the highest-scoring destination in the cache with zero clear days, precisely so the uncomfortable case is the one on display. Publishing a scoring model and then illustrating it with your best-looking city is a brochure, not a methodology.

What this score is not

It is a forecast, and forecasts are wrong sometimes. A 9 is not a promise of sunshine and carries no entitlement to a refund if the week turns. What the score does promise is that the same published arithmetic was applied to every destination, that nothing was quietly boosted, and that when the sky is grey we say the sky is grey. The full terms are on our terms page.

Weather data from Open-Meteo. Scores recomputed on every refresh — see system status for when that last happened.

The almanac sunshine metric — a second instrument

Historical almanac pages carry a second metric alongside the WMO-code clear bar above. The two instruments answer different questions and are published side by side so you can compare before any headline change is made.

Warm and sunny day: a day where ERA5 shows temp ≥ 72°F and sunshine_duration > 6 hours. sunshine_duration = integrated direct solar irradiance > 120 W/m² (ERA5 via Open-Meteo).

Why a second metric?

The WMO daily weather code is a worst-moment-of-the-day summary. A Lowcountry July day that is brilliantly sunny from 7am to 3pm, gets a 25-minute convective storm at 4pm, then clears again, receives code 63 (moderate rain) for the whole day. The WMO clear bar discards that day entirely.

sunshine_duration is not fooled by the storm. It records roughly 12 hours of direct sun. The new metric counts this day correctly as warm and sunny — which is what a guest who visited in July experienced.

What this measures vs. the code bar

Supporting metrics published alongside it

Why error size varies by climate

The WMO bias is not a constant offset that can be patched with a fudge factor. It is climate-dependent: subtropical and tropical destinations with frequent short afternoon convective storms are heavily understated (measured gap up to +84 points for Key West in August). Desert and mediterranean climates where storms are rare are nearly unaffected (San Diego July: gap < 3 points). The metric must therefore be recomputed per destination from real sunshine hours.

Importantly, bad months stay bad under the new metric: Aspen in January is 0% warm and sunny, Hilton Head in January 3%, Scottsdale in January 13%. This is what makes the good numbers credible — the metric is not indiscriminate inflation.

Sunshine metric data: ERA5 via Open-Meteo archive API (archive-api.open-meteo.com), 8 years (2018–2025). Computed by scripts/backfill_sunshine_almanac.py; refreshed monthly. Machine-readable definition: DefinedTerm JSON-LD embedded in this page.

How destinations are added and removed

The roster is self-maintaining. A place is added because it demonstrably qualifies and removed when it stops. No human decides which places are destinations. The rule is stored in the database and published here verbatim — it is the same rule the nightly discovery loop applies.

Promotion test (all three must be true)

Hysteresis

A candidate must pass the test on 2 consecutive daily checks before it is added to the roster. An active destination must fail on 3 consecutive daily checks before it is removed. This prevents a single API error or transient supply gap from reshaping the roster.

Blast-radius caps

At most 5 destinations can be added and at most 5 can be removed in a single nightly run. A loop that can add 80 or delete 30 at once is a liability, not a feature.

Retired destinations

A retired destination’s URL returns HTTP 410 Gone rather than silently 404-ing. This signals to search engines that the page existed and was intentionally removed, rather than disappeared without notice. The page carries a noindex directive.

Rule derived from Phase B distribution analysis (141 US airports screened 2026-08-07). Rule effective: 2026-08-08. Screening cadence: every 90 days per candidate.