{"id":1441,"date":"2026-10-22T18:00:00","date_gmt":"2026-10-22T17:00:00","guid":{"rendered":"https:\/\/wade.one\/blog\/?p=1441"},"modified":"2026-10-22T18:00:00","modified_gmt":"2026-10-22T17:00:00","slug":"a-scheduled-job-needs-a-time-zone-not-just-an-hour","status":"publish","type":"post","link":"https:\/\/wade.one\/blog\/2026\/10\/22\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\/","title":{"rendered":"A Scheduled Job Needs a Time Zone, Not Just an Hour"},"content":{"rendered":"<p>&#8220;Run it at six&#8221; is incomplete information for a scheduled job. Six where, and should it stay at six when the clocks change? If the requirement is a local wall-clock time, storing a fixed UTC offset can quietly move the job by an hour for part of the year.<\/p>\n<p>I would record the intended time zone alongside the schedule, then calculate the corresponding UTC instant for each occurrence. PHP&#8217;s <a href=\"https:\/\/www.php.net\/manual\/en\/class.datetimeimmutable.php\">DateTimeImmutable<\/a> supports working with time-zone-aware date objects without changing the original object in place. The important part is preserving the meaning of the schedule, rather than just getting a plausible timestamp into a field.<\/p>\n<p>The awkward cases deserve an explicit decision: a local time that occurs twice when the clocks go back, or does not occur when they go forward. For a recurring task, adding a fixed number of seconds to yesterday&#8217;s execution is not always equivalent to the next local calendar occurrence. Test the dates around a clock change, not only a random Tuesday in the middle of summer.<\/p>\n<p>Time-zone bugs are annoying because the code can be internally consistent and still violate what somebody asked for. A schedule should be readable as a human promise, with a precise instant behind each run. If that promise is &#8220;18:00 in London&#8221;, keep London in the data.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;Run it at six&#8221; is incomplete information for a scheduled job.<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_hide_featured_image":false,"_jetpack_featured_image_duplicate_dismissed":0,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[13],"tags":[35,275,274],"class_list":["post-1441","post","type-post","status-publish","format-standard","hentry","category-programming","tag-php","tag-scheduling","tag-time-zones"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>A Scheduled Job Needs a Time Zone, Not Just an Hour - wade.one<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/wade.one\/blog\/2026\/10\/22\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\/\" \/>\n<meta property=\"og:locale\" content=\"en_GB\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"A Scheduled Job Needs a Time Zone, Not Just an Hour - wade.one\" \/>\n<meta property=\"og:description\" content=\"&quot;Run it at six&quot; is incomplete information for a scheduled job.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/wade.one\/blog\/2026\/10\/22\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\/\" \/>\n<meta property=\"og:site_name\" content=\"wade.one\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-22T17:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/Wade-Logo-cropped.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1518\" \/>\n\t<meta property=\"og:image:height\" content=\"1506\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@wadewomersley\" \/>\n<meta name=\"twitter:site\" content=\"@wadewomersley\" \/>\n<meta name=\"twitter:label1\" content=\"Estimated reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/10\\\/22\\\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/10\\\/22\\\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\\\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"A Scheduled Job Needs a Time Zone, Not Just an Hour\",\"datePublished\":\"2026-10-22T17:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/10\\\/22\\\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\\\/\"},\"wordCount\":227,\"publisher\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#\\\/schema\\\/person\\\/8b4739f8f8bb2cff5d792d4b8779fcc3\"},\"keywords\":[\"php\",\"scheduling\",\"time-zones\"],\"articleSection\":[\"Programming\"],\"inLanguage\":\"en-GB\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/10\\\/22\\\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\\\/\",\"url\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/10\\\/22\\\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\\\/\",\"name\":\"A Scheduled Job Needs a Time Zone, Not Just an Hour - wade.one\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#website\"},\"datePublished\":\"2026-10-22T17:00:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/10\\\/22\\\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\\\/#breadcrumb\"},\"inLanguage\":\"en-GB\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/10\\\/22\\\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/2026\\\/10\\\/22\\\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/wade.one\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"A Scheduled Job Needs a Time Zone, Not Just an Hour\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/wade.one\\\/blog\\\/\",\"name\":\"wade.one\",\"description\":\"wade womersley - york based software engineer\",\"publisher\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#\\\/schema\\\/person\\\/8b4739f8f8bb2cff5d792d4b8779fcc3\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/wade.one\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-GB\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/#\\\/schema\\\/person\\\/8b4739f8f8bb2cff5d792d4b8779fcc3\",\"name\":\"Wade Womersley\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-GB\",\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\",\"url\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\",\"contentUrl\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\",\"width\":202,\"height\":200,\"caption\":\"Wade Womersley\"},\"logo\":{\"@id\":\"https:\\\/\\\/wade.one\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/02\\\/200px.png\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"A Scheduled Job Needs a Time Zone, Not Just an Hour - wade.one","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/wade.one\/blog\/2026\/10\/22\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\/","og_locale":"en_GB","og_type":"article","og_title":"A Scheduled Job Needs a Time Zone, Not Just an Hour - wade.one","og_description":"\"Run it at six\" is incomplete information for a scheduled job.","og_url":"https:\/\/wade.one\/blog\/2026\/10\/22\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\/","og_site_name":"wade.one","article_published_time":"2026-10-22T17:00:00+00:00","og_image":[{"width":1518,"height":1506,"url":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/Wade-Logo-cropped.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_creator":"@wadewomersley","twitter_site":"@wadewomersley","twitter_misc":{"Estimated reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/wade.one\/blog\/2026\/10\/22\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\/#article","isPartOf":{"@id":"https:\/\/wade.one\/blog\/2026\/10\/22\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\/"},"author":{"name":"","@id":""},"headline":"A Scheduled Job Needs a Time Zone, Not Just an Hour","datePublished":"2026-10-22T17:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/wade.one\/blog\/2026\/10\/22\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\/"},"wordCount":227,"publisher":{"@id":"https:\/\/wade.one\/blog\/#\/schema\/person\/8b4739f8f8bb2cff5d792d4b8779fcc3"},"keywords":["php","scheduling","time-zones"],"articleSection":["Programming"],"inLanguage":"en-GB"},{"@type":"WebPage","@id":"https:\/\/wade.one\/blog\/2026\/10\/22\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\/","url":"https:\/\/wade.one\/blog\/2026\/10\/22\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\/","name":"A Scheduled Job Needs a Time Zone, Not Just an Hour - wade.one","isPartOf":{"@id":"https:\/\/wade.one\/blog\/#website"},"datePublished":"2026-10-22T17:00:00+00:00","breadcrumb":{"@id":"https:\/\/wade.one\/blog\/2026\/10\/22\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\/#breadcrumb"},"inLanguage":"en-GB","potentialAction":[{"@type":"ReadAction","target":["https:\/\/wade.one\/blog\/2026\/10\/22\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/wade.one\/blog\/2026\/10\/22\/a-scheduled-job-needs-a-time-zone-not-just-an-hour\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/wade.one\/blog\/"},{"@type":"ListItem","position":2,"name":"A Scheduled Job Needs a Time Zone, Not Just an Hour"}]},{"@type":"WebSite","@id":"https:\/\/wade.one\/blog\/#website","url":"https:\/\/wade.one\/blog\/","name":"wade.one","description":"wade womersley - york based software engineer","publisher":{"@id":"https:\/\/wade.one\/blog\/#\/schema\/person\/8b4739f8f8bb2cff5d792d4b8779fcc3"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/wade.one\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-GB"},{"@type":["Person","Organization"],"@id":"https:\/\/wade.one\/blog\/#\/schema\/person\/8b4739f8f8bb2cff5d792d4b8779fcc3","name":"Wade Womersley","image":{"@type":"ImageObject","inLanguage":"en-GB","@id":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png","url":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png","contentUrl":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png","width":202,"height":200,"caption":"Wade Womersley"},"logo":{"@id":"https:\/\/wade.one\/blog\/wp-content\/uploads\/2015\/02\/200px.png"}}]}},"jetpack_publicize_connections":[],"jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":410,"url":"https:\/\/wade.one\/blog\/2010\/01\/07\/snowy-britain-nasa-terra-image\/","url_meta":{"origin":1441,"position":0},"title":"Snowy Britain &#8211; NASA Terra image","author":"Wade","date":"January 7, 2010","format":false,"excerpt":"NASA uploaded an image today of Great Britain from space as of 11:50 UTC today, it's a truly remarkable picture showing just how much it has snowed here. For anyone not from the UK, snow like this has not hit Britain for over 30 years, hence all the hoo-haa about.\u2026","rel":"","context":"In &quot;News&quot;","block_context":{"text":"News","link":"https:\/\/wade.one\/blog\/category\/news\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/wade.one\/blog\/wp-content\/uploads\/2016\/04\/GreatBritain.A2010007.1150.1km.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/wade.one\/blog\/wp-content\/uploads\/2016\/04\/GreatBritain.A2010007.1150.1km.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/wade.one\/blog\/wp-content\/uploads\/2016\/04\/GreatBritain.A2010007.1150.1km.jpg?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/wade.one\/blog\/wp-content\/uploads\/2016\/04\/GreatBritain.A2010007.1150.1km.jpg?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":1335,"url":"https:\/\/wade.one\/blog\/2026\/06\/03\/claude-code-routines-make-agents-feel-more-like-ci-jobs\/","url_meta":{"origin":1441,"position":1},"title":"Claude Code Routines Make Agents Feel More Like CI Jobs","author":"Wade","date":"June 3, 2026","format":false,"excerpt":"Claude Code routines are interesting because they move coding agents toward scheduled, event-driven, reviewable work.","rel":"","context":"In &quot;AI&quot;","block_context":{"text":"AI","link":"https:\/\/wade.one\/blog\/category\/ai\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1100,"url":"https:\/\/wade.one\/blog\/2023\/03\/26\/years-later-starting-to-blog\/","url_meta":{"origin":1441,"position":2},"title":"Years later, starting to blog","author":"Wade","date":"March 26, 2023","format":false,"excerpt":"So time to start blogging again, years of not doing it, I'll slowly work up again so it will probably be a slow ramp up. I've had a rather comfortable life the last few years so let myself slip, as most of us are experiencing now, that is no longer\u2026","rel":"","context":"In &quot;Software Engineer&quot;","block_context":{"text":"Software Engineer","link":"https:\/\/wade.one\/blog\/category\/software-engineer\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1408,"url":"https:\/\/wade.one\/blog\/2026\/08\/19\/furry-meets-work-best-when-nothing-much-is-planned\/","url_meta":{"origin":1441,"position":3},"title":"Furry Meets Work Best When Nothing Much Is Planned","author":"Wade","date":"August 19, 2026","format":false,"excerpt":"The best furry meets leave enough empty space for conversations, wandering around, and whatever happens next.","rel":"","context":"In &quot;Random Stuff&quot;","block_context":{"text":"Random Stuff","link":"https:\/\/wade.one\/blog\/category\/random-stuff\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1168,"url":"https:\/\/wade.one\/blog\/2026\/04\/01\/why-i-still-like-serverless-for-small-teams\/","url_meta":{"origin":1441,"position":4},"title":"Why I Still Like Serverless for Small Teams","author":"","date":"April 1, 2026","format":false,"excerpt":"Serverless has real tradeoffs, but for small teams I still think it usually wins. The operational overhead stays low, the first version ships faster, and the mistakes are easier to afford early on.","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/wade.one\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1435,"url":"https:\/\/wade.one\/blog\/2026\/10\/16\/docker-compose-start-order-is-not-database-readiness\/","url_meta":{"origin":1441,"position":5},"title":"Docker Compose Start Order Is Not Database Readiness","author":"","date":"October 16, 2026","format":false,"excerpt":"Starting the database container before the application container sounds like it should solve startup failures.","rel":"","context":"In &quot;Programming&quot;","block_context":{"text":"Programming","link":"https:\/\/wade.one\/blog\/category\/programming\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts\/1441","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/comments?post=1441"}],"version-history":[{"count":1,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts\/1441\/revisions"}],"predecessor-version":[{"id":1464,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/posts\/1441\/revisions\/1464"}],"wp:attachment":[{"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/media?parent=1441"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/categories?post=1441"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wade.one\/blog\/wp-json\/wp\/v2\/tags?post=1441"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}