{"slug":"stock-market-hours","qid":"sessions_year","label":"Trading sessions over the trailing year, counted from the SPY tape","post_title":"Stock Market Hours: Open 9:30, Close 4:00 ET","post_url":"/blog/stock-market-hours#q-sessions_year","columns":["trading_days","full_length_sessions","shortened_sessions","irregular_sessions","weekend_sessions","first_session","last_session"],"rows":[{"trading_days":253,"full_length_sessions":251,"shortened_sessions":2,"irregular_sessions":0,"weekend_sessions":0,"first_session":"2025-08-18","last_session":"2026-08-19"}],"shape":"scalar","sql":"SELECT\n    count()                              AS trading_days,\n    countIf(rth_bars >= 380)             AS full_length_sessions,\n    countIf(rth_bars <= 240)             AS shortened_sessions,\n    countIf(rth_bars > 240 AND rth_bars < 380) AS irregular_sessions,\n    countIf(is_weekend)                  AS weekend_sessions,\n    toString(min(d))                     AS first_session,\n    toString(max(d))                     AS last_session\nFROM\n(\n    SELECT\n        toDate(toTimeZone(window_start, 'America/New_York')) AS d,\n        toDayOfWeek(toDate(toTimeZone(window_start, 'America/New_York'))) >= 6 AS is_weekend,\n        countIf((toHour(toTimeZone(window_start, 'America/New_York')) * 60\n                 + toMinute(toTimeZone(window_start, 'America/New_York'))) >= 570\n            AND (toHour(toTimeZone(window_start, 'America/New_York')) * 60\n                 + toMinute(toTimeZone(window_start, 'America/New_York'))) < 960) AS rth_bars\n    FROM global_markets.delayed_stocks_minute_aggs\n    WHERE ticker = 'SPY'\n      AND window_start >= today() - 370\n      AND window_start < today() - 2\n    GROUP BY d, is_weekend\n    HAVING rth_bars > 0\n)","computed_at":"2026-08-22T04:22:19.642062+00:00","elapsed":0.317827839}