๐Ÿ“ sports-calendar-merger / sports-calendar.php โ— live PHP 8+ iCal / RFC 5545

๐ŸŸ๏ธ DC Sports Combined Calendar

// merges four sport calendar feeds โ†’ one clean subscription url

โšพ MLB Baseball ๐Ÿ€ NBA Basketball ๐Ÿ’ NHL Hockey ๐Ÿˆ NFL Football

What this is

A single PHP script that acts as a personal iCal aggregator for sports schedules. It fetches four public Google Calendar feeds (baseball, basketball, hockey, and football), merges them into one combined feed, slaps the right emoji on each event so you know which sport you're looking at at a glance, and drops any game that has already ended so your calendar stays clean.

Subscribe to sports-calendar.php once in Google Calendar and you're done โ€” no app, no account, no fuss.

Features

FeatureDetail
๐Ÿ”€ Merged feed All four sports in one .ics subscription URL
๐Ÿท๏ธ Emoji labels โšพ ๐Ÿ€ ๐Ÿ’ ๐Ÿˆ prepended to every event title automatically
๐Ÿงน Auto-cleanup Completed games are filtered out on every request โ€” no stale clutter
โšก No dependencies Pure PHP, no libraries, no Composer โ€” just upload and go
๐Ÿ” Always fresh Re-fetches source calendars on every poll; 1-hour cache header for Google

How to subscribe

  1. In Google Calendar, click the + next to Other calendars and choose From URL.

  2. Paste in the URL of this script:

    https://dcsports.stevenglassman.com/sports-calendar.php
  3. Click Add calendar. Google will import it and start showing games. Done! ๐ŸŽ‰

๐Ÿ“ก Note on refresh rate: Google Calendar polls subscribed URLs roughly every 12โ€“24 hours. This is Google's own schedule and can't be changed from our end. The script itself is always current โ€” it's just Google's polling that introduces the lag.

Source calendars

SportSource URL
โšพ Baseball (MLB) โ€ฆ4effb802โ€ฆ/basic.ics
๐Ÿ€ Basketball (NBA) โ€ฆ184f235cโ€ฆ/basic.ics
๐Ÿ’ Hockey (NHL) โ€ฆ8be63d02โ€ฆ/basic.ics
๐Ÿˆ Football (NFL) โ€ฆ3kooo1l2โ€ฆ/basic.ics

To add, remove, or swap a calendar, edit the $CALENDARS array at the top of sports-calendar.php and re-upload.

How it works

On every request

When Google Calendar polls the URL, the script fetches all four source .ics feeds in sequence, parses out the VEVENT blocks, checks each event's DTEND (or end-of-day on DTSTART for all-day events) against the current UTC time, drops anything in the past, prepends the sport emoji to the SUMMARY field, and streams the merged result as a valid iCal document.

Date handling

The script handles all three iCal date formats: UTC datetime (20240101T120000Z), floating datetime (20240101T120000), and all-day date values (20240101). Events with no end time fall back to end-of-calendar-day so they still get cleaned up promptly.

โš ๏ธ Troubleshooting: If the calendar appears empty, the most likely cause is that outbound file_get_contents() is disabled on the server. Contact your host or swap the fetch function for a cURL equivalent โ€” a commented fallback is easy to add.

Customising

$CALENDARS = [
    [
        'url'   => 'https://...your-ics-url...',
        'emoji' => 'โšฝ',  // โ† change to any emoji you like
    ],
    // add as many entries as you want
];

Any number of source calendars is supported โ€” just add more entries to the array. The output calendar name is set via the X-WR-CALNAME header near the bottom of the script.