Testing the display support recently added to Adafruit IO's no-code Arduino firmware, WipperSnapper, I've come unstuck with my automations a few times due to living over the other side of the pond (🫖) from Adafruit HQ...
"Why?", you ask? Time-zones!
In case you were unaware, Adafruit HQ runs on New York time, also known as EST (Eastern Standard Time), which is currently 4hours behind UTC (daylight savings can alter this 4hr offset).
Now to make life easier, the schedule block uses a timezone location set in the User account page, meaning my schedules run as expected, yay! The tricky bit comes when you want to start comparing time or timestamp values.
Most things live in server time, which is set to New York, but many other bits and bobs are presented in UTC.
For our purposes we want things in our local time, advancing time back to the future, with a no-code clock!
Setup WipperSnapper
- Head over to io.adafruit.com/devices/new and pick one of the boards to install, if yours is not listed then try a board with a similar chip, or file a feature request for us to add the board to WipperSnapper here.
- Once you're device is online (you've followed all the installer steps/pages and copied the secrets.json file to the device if USB drive and rebooted it) then use the New Component button to add your display components (OLED / Character LCD / 14 or 7 segment alphanumeric displays). Try sending them values to ensure they work
In this example I've got two 14-segment Quad alphanumeric i2c displays (Date), and a 7-segment numeric display (Time), making 12 characters in 3 groups of four (ignoring symbols like period / colon)
Setup clock updating action - runs once per minute
- Create a new Action on the /Actions page, with an appropriate name and description.
- Add a schedule block, set to run every month, day, hour, and minute.
-
OPTIONAL: Use the cog button on the root action block to adjust the delay settings for the action.
Alter the delay to be 59seconds, so it changes just as the minute does.
You can add 1second to the current time to get the display to show the next / correct minute.
- Create a variable for
timezone_offset_hoursand set the value to your local timezone offset
- Add a new variable for
local_time, and 3 more for the display segments (or as many as appropriate).
- Use the template block (text category) for the Set Variable value for local_time .
In the template's paragraph child block, where thing represents offset difference, set the body to:{%- assign now_s = "now" | date: "%Y-%m-%dT%H:%M:%S" | date: "%s" %}
{%- assign now_z_s = "now" | date: "%Y-%m-%dT%H:%M:%SZ%z" | date: "%s" -%}
{%- assign server_utc_diff = now_z_s | minus: now_s -%}
{%- assign thing = 3600 | times: vars["timezone_offset_hours"] | minus: server_utc_diff -%}
{{ now_s | plus: thing | date: "%Y-%m-%dT%H:%M:%S" }}
{%- comment %} this is a bit hacky, as the timezone doesn't get properly altered with plus: seen by printing %z {% endcomment -%} - Use the Set Variable block for the segment1 variable, combined with a template block for the value connection. Then set the template body to cut four characters (period is ignored for alphanum-segments):
{{vars.local_time | date: "%d.%b" | slice: 0,5 }}
- Do the same for segment 2, with the template:
{{vars.local_time | date: "%b.%y " | slice: 2,8 }}
- For segment 3's template body:
{{vars.local_time | date: "%H.%M" }}
- Finally use Set Feed blocks, pointed at the segment displays, to assign each segment variable to a display.
- Save and run the action, enabling it if asked.
Your action should look similar to this:
Setup DST Change-over Actions
- Create a new feed to store the timezone offset inside if you haven't already got one. Do it on the /feeds page, and then on the new feed page add data manually for the current time-zone offset.
- Create a new Action on the /Actions page, called "Start of DST", with a description of when it should run.
- Add a schedule trigger block to the diagram. Use the cogs to alter the schedule block for your DST changeover. In my case we don't support "last X in Month" yet so I'm using "Every Sunday in March", followed by a check of a liquid template function if it's the last sunday in the month.
- If needed for complex schedules then add a Set Variable block (variable named timezone_offset_hours) with the value set to the timezone offset feed (Get feed block). Otherwise jump to step 7.
- Add a set variable block for a new variable called is_last_sunday, then add a template block as the value.
For the template body, use the following (which adds 7days then compares the month to current)
Template:{%- assign now_s = "now" | date: "%Y-%m-%dT%H:%M:%S" | date: "%s" %}{%- assign now_z_s = "now" | date: "%Y-%m-%dT%H:%M:%SZ%z" | date: "%s" -%}{%- assign server_utc_diff = now_z_s | minus: now_s -%}{%- assign thing = 3600 | times: vars["timezone_offset_hours"] | minus: server_utc_diff -%}{%- assign bst_time_s = now_s | plus: thing -%}{%- assign current_month = bst_time_s | date: "%m" -%}{%- assign next_week_month = bst_time_s | plus: 604800 | date: "%m" -%}{%- if current_month != next_week_month -%}1{%- else -%}0{%- endif -%}
- Add a logic IF condition block, then place a number comparison block from the maths category (=)
Inside the number comparison block, add a Get Variable block for is_last_sunday, and compare to 1.
- Add a Set Feed block to the Actions: section of the diagram, and select the timezone offset feed in the dropdown. For the value enter the local UTC offset in hours during the next daylight savings time period.
- Save and run the action, enabling if asked.
- Create a second action for the end of Daylight savings time, with the appropriate local UTC offset in hours for that next period. Save it and run it, enabling if asked.
Your actions should look similar to this:
Now go back to the clock updating action, and replace the fixed timezone offset value with the Get Feed block.
Taking it further
Well, I don't know what you want personally, but I'm going to have the clock display other things every 10seconds, like the rain in next 15mins / 1hr, sunset, Air Quality, you get the idea.
But mostly I got these screens for an ulterior motive...
I'm eventually looking to recreate this crucial piece from a time machine...and then get myself to 88mph🌩️
This page (Displays and Clocks with Adafruit IO - Back to the Future with timezones) was last updated on July 21, 2025.