Drop-in `holidays`-compatible lookup of special-event dates (Super Bowl, Oscars, ...). Data sourced from Wikidata; offline-only at runtime.
Project description
special-days
Lookup dates for special events — Super Bowl Sunday, Oscars night,
World Series Game 7, NCAA championship. Drop-in compatible with the
holidays package, so the same
date in calendar logic you already use for public holidays answers
"is today Super Bowl Sunday?" too.
Zero runtime dependencies. Lookups are local by default; data is
refreshed in CI from Wikidata and pip install --upgrade pulls the
new dates. A long-running process can opt into a Wikidata refresh
mid-run — see the dev guide.
Status: Alpha. Currently ships Super Bowl + Academy Awards (Oscars). The API is still moving — expect breaking changes on any release until the maintenance process has run for a while and I've learned what wants to change.
Install
pip install special-days
Quickstart — "what's special about today?"
The most common use: ask "is this date significant?" in the
holidays-compatible way.
from datetime import date
from special_days import SpecialDays
sd = SpecialDays() # all events the package ships
sd.get_list(date(2025, 2, 9)) # ['Super Bowl']
sd.get_list(date(2025, 3, 2)) # ['Academy Awards']
sd.get_list(date(2025, 5, 1)) # []
Compose with the holidays package via union(...), preserving
laziness on both sides:
import holidays
from special_days import SpecialDays, union
combined = union(holidays.US(), SpecialDays())
combined.get_list(date(2025, 2, 9)) # ['Super Bowl']
combined.get_list(date(2025, 7, 4)) # ['Independence Day']
Drop a flat name → emoji dict on top and you have a "what's special
about today?" UI in a dozen lines:
EMOJI = {
"Independence Day": "🎆",
"Super Bowl": "🏈",
"Academy Awards": "🎬",
}
def specials(d):
return [(n, EMOJI[n]) for n in combined.get_list(d) if n in EMOJI]
specials(date(2025, 2, 9)) # [('Super Bowl', '🏈')]
specials(date(2025, 7, 4)) # [('Independence Day', '🎆')]
specials(date(2025, 5, 1)) # []
The full version is in examples/by_date.py.
Two ways to use it
Date-keyed (drop-in for holidays)
A dict[date, str] subclass populated from the shipped snapshot at
construction time.
from datetime import date
from special_days import SuperBowl
sb = SuperBowl() # every known Super Bowl date
date(2025, 2, 9) in sb # True
sb[date(2025, 2, 9)] # 'Super Bowl'
sb.get_list(date(2025, 2, 9)) # ['Super Bowl']
len(sb) # one entry per game, grows each year
# Filter to a subset of years.
SuperBowl(years=[1967, 2024, 2025])
SuperBowl(years=range(2020, 2030))
datetime.datetime values are normalized to date automatically, so
mixing the two in a lookup just works.
Year-keyed (planner-style)
from datetime import date
from special_days import super_bowl
super_bowl.date(2025) # datetime.date(2025, 2, 9)
super_bowl.is_super_bowl_sunday(date(2025, 2, 9)) # True
super_bowl.all_known() # {1967: date(1967, 1, 15), ..., 2027: date(2027, 2, 14)}
Pick whichever shape fits the question.
Display strings
By default the dict value is the constant event name ("Super Bowl",
"Academy Awards"). Pass label_with_edition=True for
edition-numbered display strings:
SuperBowl(label_with_edition=True)[date(2025, 2, 9)] # 'Super Bowl LIX'
Oscars(label_with_edition=True)[date(2025, 3, 2)] # '97th Academy Awards'
Super Bowl 50 (2016) uses the Arabic numeral, matching official NFL branding; every other edition uses Roman. The Academy Awards labeller handles 1930's two ceremonies (the 2nd in April, the 3rd in November) and the subsequent resync at the 6th ceremony in 1934.
Two ceremonies in one year
Most series have at most one installment per year, but not all. 1930 hosted two Academy Awards (the 2nd and 3rd):
from special_days import oscars
oscars.date(1930) # datetime.date(1930, 4, 3) -- first only
oscars.dates(1930) # [date(1930, 4, 3), date(1930, 11, 5)]
SpecialDays/Oscars dicts contain both dates and label them
distinctly when label_with_edition=True.
Recipes
Next upcoming event from today
is_super_bowl_sunday over a date range, or just iterate dates() /
all_known():
from datetime import date, timedelta
from special_days import super_bowl
today = date.today()
upcoming = next(
d for d in (today + timedelta(days=i) for i in range(365 * 2))
if super_bowl.is_super_bowl_sunday(d)
)
All special days in a date range
from datetime import date, timedelta
from special_days import SpecialDays
sd = SpecialDays()
start, end = date(2025, 1, 1), date(2025, 12, 31)
days = [d for d in (start + timedelta(days=i)
for i in range((end - start).days + 1))
if d in sd]
# [date(2025, 2, 9), date(2025, 3, 2)]
Just one event, not all of them
SpecialDays(events=[...]) accepts string names, classes, or
already-built instances:
from special_days import SpecialDays, SuperBowl
SpecialDays(events=["super_bowl"]) # by registered name
SpecialDays(events=[SuperBowl]) # by class
SpecialDays(events=[SuperBowl(years=[2024, 2025])]) # pre-filtered instance
Data freshness
The shipped snapshot covers every event known to the maintainers at
release time — every past game and every officially-announced future
game. A daily CI job rebuilds the snapshot from Wikidata; if anything
changed, it opens a PR. Once merged, a new patch release ships to
PyPI. Run pip install --upgrade special-days to pull the latest.
For maintainers and curious users, the full pipeline is documented in
docs/how_it_works.md.
Errors
super_bowl.date(year)raisesKeyErrorif the year is not in the shipped snapshot. Upgrade the package to pick up newly-announced dates.- Non-
intyeararguments raiseTypeErrorimmediately. SpecialDays(events=[...])raisesValueErrorfor unknown event strings, listing the valid ones.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file special_days-0.3.0.tar.gz.
File metadata
- Download URL: special_days-0.3.0.tar.gz
- Upload date:
- Size: 26.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cd4ba0d63df2272859152f22576b46503196b0f6da5cd24d4e07a07df863f5d1
|
|
| MD5 |
2a954a762c14bc66750470a6a51c85f9
|
|
| BLAKE2b-256 |
3374b4dca190bb6381de222dac989e3defb302c6ab232dc7593e5f71c387b77e
|
Provenance
The following attestation bundles were made for special_days-0.3.0.tar.gz:
Publisher:
release.yml on stringertheory/special-days
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
special_days-0.3.0.tar.gz -
Subject digest:
cd4ba0d63df2272859152f22576b46503196b0f6da5cd24d4e07a07df863f5d1 - Sigstore transparency entry: 1525024495
- Sigstore integration time:
-
Permalink:
stringertheory/special-days@2212d3c0d4a7a1e92b800187803f27d1788b21c0 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/stringertheory
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2212d3c0d4a7a1e92b800187803f27d1788b21c0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file special_days-0.3.0-py3-none-any.whl.
File metadata
- Download URL: special_days-0.3.0-py3-none-any.whl
- Upload date:
- Size: 19.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b718cae2f34ca39bebc29ed11b928f3f9702526bf9e3bf3bb5b78bb03f6f0c2d
|
|
| MD5 |
fb328f2cd8148dac79a010b975f6084c
|
|
| BLAKE2b-256 |
ed60fdc108e9723515a331fca8d54c05734b7b0c76e11af9a57edcdf71f2680d
|
Provenance
The following attestation bundles were made for special_days-0.3.0-py3-none-any.whl:
Publisher:
release.yml on stringertheory/special-days
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
special_days-0.3.0-py3-none-any.whl -
Subject digest:
b718cae2f34ca39bebc29ed11b928f3f9702526bf9e3bf3bb5b78bb03f6f0c2d - Sigstore transparency entry: 1525024507
- Sigstore integration time:
-
Permalink:
stringertheory/special-days@2212d3c0d4a7a1e92b800187803f27d1788b21c0 -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/stringertheory
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2212d3c0d4a7a1e92b800187803f27d1788b21c0 -
Trigger Event:
push
-
Statement type: