How to check whether a timestamp is within the last X hours

I’m working with a device that feeds its output to a web server which always displays the last data it received, so standard HTTP GET-style is-it-alive monitoring doesn’t work. What does work is using Scrape to grab the timestamp from the device, e.g. “07/04/25 22:05:00”. However I now need to check whether this is within (say) 12 hours of {{ now() | as_local }}, but after reading way too many threads on messing with dates I’m not having much luck. Can anyone provide any insight?

Doing a straight equivalence comparison as per this thread seems fairly straightforward but I need to do a within-bounds check which means a range comparison, or at least an is-it-more-than-X-hours-in-the-past check. My plan was to strptime() the string into a datetime, subtract it from {{ now() | as_local }}, and then somehow check whether that’s more than X hours. I know Python has a timedelta but I’m not sure how far I can get with that in HA’s YAML.

timedelta() is supported in HA’s Jinja templates.

{% set dt = strptime('07/04/25 22:05:00', '%m/%d/%y %H:%M:%S')|as_local %}
{{ dt > now() - timedelta(hours=12) }}
2 Likes

Some additional info to @Didgeridrew’s answer in case anyone finds it useful, this is a complete template binary sensor that uses the above, the only minor change I’ve made is moving the as_local around since the web page datestamp is already in local time. As the names indicate, in this particular case it’s to check whether a WeeWX weather feed has gone offline:

# Template binary sensor to record whether there's been any updates in the
# last 12 hours.  To test, use the following, with the date set to < 12 and
# > 12 hours ago:
#
# {% set webPageTime = strptime('06/25/25 22:05:00', '%m/%d/%y %H:%M:%S')|as_local %}

template:
  - binary_sensor:
      - name: WeeWX Online
        unique_id: uniqueid__weewx_online
        state: >
          {% set webPageTime = strptime(states('sensor.weewx_last_update'), '%m/%d/%y %H:%M:%S')|as_local %}
          {% set currentTime = now() | as_local %}
          {{ webPageTime > currentTime - timedelta(hours=12) }}

FWIW, now() is localized, so the as_local isn’t doing anything.

Ah, OK. I was thinking of C’s UTC-referenced time().