{"id":17689255,"url":"https://github.com/othyn/go-calendar","last_synced_at":"2026-06-16T03:01:21.279Z","repository":{"id":65067488,"uuid":"580172601","full_name":"othyn/go-calendar","owner":"othyn","description":"A community driven auto-updating Pokémon GO events calendar that you can subscribe to in any calendar app on your phone/PC. Powered by Leek Duck.","archived":false,"fork":false,"pushed_at":"2026-06-08T01:12:04.000Z","size":2871,"stargazers_count":63,"open_issues_count":7,"forks_count":14,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-06-08T03:23:09.262Z","etag":null,"topics":["calendar","ical","leek-duck","pokemon","pokemon-go"],"latest_commit_sha":null,"homepage":"https://gocalendar.info/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/othyn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["othyn"]}},"created_at":"2022-12-19T22:32:17.000Z","updated_at":"2026-06-08T01:11:26.000Z","dependencies_parsed_at":"2025-12-26T03:01:20.107Z","dependency_job_id":null,"html_url":"https://github.com/othyn/go-calendar","commit_stats":null,"previous_names":[],"tags_count":1277,"template":false,"template_full_name":null,"purl":"pkg:github/othyn/go-calendar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/othyn%2Fgo-calendar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/othyn%2Fgo-calendar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/othyn%2Fgo-calendar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/othyn%2Fgo-calendar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/othyn","download_url":"https://codeload.github.com/othyn/go-calendar/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/othyn%2Fgo-calendar/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34388669,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-16T02:00:06.860Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["calendar","ical","leek-duck","pokemon","pokemon-go"],"created_at":"2024-10-24T11:47:07.103Z","updated_at":"2026-06-16T03:01:21.242Z","avatar_url":"https://github.com/othyn.png","language":"PHP","funding_links":["https://github.com/sponsors/othyn"],"categories":[],"sub_categories":[],"readme":"# GO Calendar\n\n[![Lint](https://github.com/othyn/go-calendar/actions/workflows/00-lint.yml/badge.svg)](https://github.com/othyn/go-calendar/actions/workflows/00-lint.yml)\n[![Generate Calendars](https://github.com/othyn/go-calendar/actions/workflows/10-calendars.yml/badge.svg)](https://github.com/othyn/go-calendar/actions/workflows/10-calendars.yml)\n[![Deploy Site](https://github.com/othyn/go-calendar/actions/workflows/20-site.yml/badge.svg)](https://github.com/othyn/go-calendar/actions/workflows/20-site.yml)\n[![Automated Release](https://github.com/othyn/go-calendar/actions/workflows/30-release.yml/badge.svg)](https://github.com/othyn/go-calendar/actions/workflows/30-release.yml)\n![GitHub all releases](https://img.shields.io/github/downloads/othyn/go-calendar/total?color=success\u0026label=Downloads)\n\nAn automated unofficial iCal calendar generator for Pokémon GO events powered by Leek Duck, so you can easily have a\nPokémon GO calendar on your phone (iOS \u0026 Android) or computer (Linux, macOS \u0026 Windows) that is always up-to-date.\n\nTake a look at [the website](https://gocalendar.info/) to get setup with the calendar.\n\n# Sources \u0026 Credit\n\nAll events are sourced from [Leek Duck](https://leekduck.com/events/)\nvia [bigfoott/ScrapedDuck](https://github.com/bigfoott/ScrapedDuck), using\nthe [events JSON resource](https://github.com/bigfoott/ScrapedDuck/wiki/Events).\n\nThis project just aims to take all that brilliant hard work and dedication from the Leek Duck team, that is presented\noh-so nicely on the Leek Duck website, and create a highly convenient and easily consumable auto-updating iCal calendar\nfor use in any modern calendar client.\n\n# Development\n\nProject is just a simple PHP CLI script using a few Symfony libraries for the sake of convenience, not the best and far\nfrom optimal, but fast and easy to maintain. The idea is to just have it get executed every 24 hours by a GitHub Action\nworkflow, in which it updates the output fragment of `./dist/gocal.ics` and commits it back to the `main` repo branch.\nThis keeps the URL consistent so in theory calendar clients should be able to subscribe to it.\n\nThere is a makefile in the root of the project that does most of the heavy lifting. A brief overview of the current\nmakefile:\n\n```shell\n# Build the relevant Docker containers for the project\nmake build\n\n# Bring up/define in waiting the Docker containers for the project in detached mode\nmake up\n\n# Tear down the running containers\nmake down\n\n# Tear down and bring back up the containers for the project, shortcut for:\n# $ make down \u0026\u0026 make up\nmake restart\n\n# Install the project dependencies via the project container\nmake install\n\n# Lint the projects code via the project container\nmake lint\n\n# Generate the calendar file into dist/gocal.ics via the project container\nmake gen\n\n# Build the pages site into a static HTML file in pages/dist\nmake site\n\n# Generate the calendar then build the pages site\nmake all\n```\n\nAs for the code itself, `bin/gocal` is the entrypoint of this CLI tool. It will bootstrap the Symfony console library\nand pull in the instructed commands from `src/Commands`.\n\nHopefully the code should be clear enough to be self documenting, although I'm not usually one to rely on such things\nalone, given the relative size of the project and associated debug output lines enclosing code blocks, it should be fine\nin this circumstance. If the project grows any larger, then I'll produce the appropriate documentation to support it.\n\n## A note on time zones and local time\n\nThis was a pain in the arse to solve, and I went through a lot of iterations coming up with a working solution. I had to\nget my hands dirty and go digging, looking at the generated date output formats in the iCal file and delve into the\nSpatie iCal library source to figure out what it was doing that it shouldn't be.\n\nThe first clue was in the generated dates in the output iCal file, any start and end dates that also had times were\nsuffixed with a `Z`. According to this [SO post](https://stackoverflow.com/a/7626131/4494375), any start and end dates\nwith times that end with `Z` will be interpreted in a UTC timezone, regardless of the timezone - or lack thereof - in\nthe calendar or event.\n\nNext step, we need to remove the `Z` by finding out where and how its being added.\n\nTurns out in `\\Spatie\\IcalendarGenerator\\Properties\\DateTimeProperty::getValue` if the DateTime entity passed is in\nUTC (which is the default in PHP if no time zone is specified when creating a DateTime entity), regardless of the state\nof `withoutTimezone()`, `getValue` will append `Z` to the generated `DateTimeValue` as its **only** checks are if the\nDateTime is in UTC and has a time associated with it. The calendar clients will then interpret this as a set UTC time\nzone when in fact we didn't want that as we provided no initial time zone and removed time zones\nwith `withoutTimezone()`.\nThe [Spatie documentation for `spatie/icalendar-generator`](https://github.com/spatie/icalendar-generator#timezones)\ndoesn't specify this behaviour, and I believe this to be a bug in the library... kinda. More on that below as I worked\non a potential PR only to hit a _gotcha_ scenario.\n\nTo illustrate the issue, this is the current code:\n\n```php\npublic function getValue(): string\n{\n    return $this-\u003eisUTC() \u0026\u0026 $this-\u003edateTimeValue-\u003ehasTime()\n        ? \"{$this-\u003edateTimeValue-\u003eformat()}Z\"\n        : $this-\u003edateTimeValue-\u003eformat();\n}\n```\n\n... and this is what I think it should be:\n\n```php\n// Expose the existing $withoutTimeZone parameter captured in the __construct as a class property\nprivate bool $withoutTimeZone;\n\npublic function getValue(): string\n{\n    return $this-\u003eisUTC() \u0026\u0026 $this-\u003edateTimeValue-\u003ehasTime() \u0026\u0026 ! $this-\u003ewithoutTimeZone\n        ? \"{$this-\u003edateTimeValue-\u003eformat()}Z\"\n        : $this-\u003edateTimeValue-\u003eformat();\n}\n```\n\nThis as we should only be adding the `Z` suffix if the time zone has been **explicitly** set, otherwise we are getting\nthe UTC time zone set and thus interpreted by default, which is not intended if you've specified `withoutTimeZone()` on\nDateTime's initialised with no time zone, thus defaulting to UTC.\n\nThe workaround being to simply set a random time zone on the DateTime being created and then use `withoutTimeZone()`, as\nit will correctly strip out/not generate _any_ time zone related properties making all dates interpret as intended -\nlocal time.\n\nNow, back to that kinda, that lovely _gotcha_. I've had a go at patching this bug and submitting a PR for it,\nand now I see their problem, and it doesn't really have a clean solution. UTC DateTime's are used for internal time zone\ncalculations, mainly for setting boundaries to expected time zone shifts, such as during summer. Patching it with\nthe above fix solves the issues with implicit/default UTC usage and `withoutTimeZone()` used in combination, but breaks\nall `DTSTAMP` generation which needs to be UTC based. This is as internally they are using `withoutTimeZone()` to ensure\nthat all user defined time zones are stripped from these internal DateTime's, to normalise them onto a UTC base,\nas is required for fixed points in time such as time zone boundaries. Its not an easy solve without some major\nreworking of how dates are safely handled for time zone boundaries in the library.\n\nFor now, I'm going to leave my hack in this repo. Setting the time zone to GMT on the event dates in combination with\nusing `withoutTimeZone()` allows the library to skip the UTC logic, giving the desired effect of local times on the\nevents due to the UTC `Z` suffix **and** all time zone stuff being dropped from the generated iCal file. I'll maybe\nsubmit a PR just with a documentation change to alert other future users of the library to this _gotcha_ scenario,\nalthough I need to find a good way of phrasing it before I do so, as the above is a bit of a brain-teaser.\n\n# Legal\n\nAll rights reserved by their respective owners.\n\nThis project is not officially affiliated with Pokémon GO and is intended to fall under Fair Use doctrine, similar to\nany other informational site such as a wiki.\n\nPokémon and its trademarks are ©1995-2022 Nintendo, Creatures, and GAMEFREAK.\n\nAll images and names owned and trademarked by Nintendo, Niantic, The Pokémon Company, and GAMEFREAK are property of\ntheir respective owners.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fothyn%2Fgo-calendar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fothyn%2Fgo-calendar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fothyn%2Fgo-calendar/lists"}