Extract a date out of a string

I have a 'most recent update' string which I want to extract the date out of so I can compare it to today's date but the string contains a date and time in a format that isn't supported. e.g. "2025-03-23 18:35:51 +1000". I thought I could separate the string out by blank space delimiter and then put that into a date variable but it won't extract the date for some reason. For the delimiter I tried a simple blank space (as in screenshot) and also tried \s but neither work. Here is what I have:

The fourth line in the actions:

Any idea what I am doing wrong? Is this is even possible? Thanks

Don’t you need token zero?

2 Likes

I don't think it works with spaces. I was looking at one of my old RM rules and I used the Replace function to replace spaces with semi-colon ";" and then used the token function to break out what I needed.

I think I was having the same issue trying to use spaces.

1 Like

Quick testing here looks like spaces work ok

1 Like

would it be possible that an app could give your the string to compare against instead of the actual value? I still use my date/time parser to give me easy variables for comparitors. However you may need to build a custom app to handle a fed date/time (feel free to snap my driver and customize the patterns!)

1 Like

Thanks but I tried and that doesn't fix it

Sorry I'm no programmer. Are you saying I can edit your driver to add my pattern (YYYY-MM-DD HH:MM:SS +1000) and convert my 'APC UPS lastUpdate' string to a date using the 'device attribute' string operation? I had a look through the code but couldn't figure out how/where

Good morning Owen - sure. I do it all the time. Install my driver via HPM. Then copy the driver from the 'Drivers code' under 'For Developers' on your hubitat to an ide or text editor.

Edit the metadata :slight_smile:

and be sure to change the name, namespace, author and importurl to your own stuff. I also suggest you mod the comments and add a date and note about your work. Oh, and maybe change the version

Then make your changes using the models I have in the code. save your work as a groovy file (just the extension) copy paste that into the 'add driver' button on the drivers code window and save. if it goes well it will show up on the drivers list and you can knock yourself out. While this is unorthodox, I find it necessary often instead of asking the originator to make mods just for me. I always reference any devs' original work in the driver that I'm extending so as to give proper attribution but this is a DIY environment and I'm not concerned - I'm not in it for the money.
Here is an example of a customization I did on my 3rd Reality driver:


I leave the original in my drivers. In this way I have a simpler way to keep my eye on what drivers I've modded - HE doesn't do versions of drivers.

1 Like

@Owen have you tried doing what @John_Land suggested? Works a charm for me

1 Like

Yes thanks it works for me too! Problem is now with the next line where I am trying to convert the tokenised string to a date with "Format DateTime". It's shown in my original post (fourth line). Despite the correct date in the string the resulting value in the DateTime variable is always "no time" whatever I try :face_with_spiral_eyes:

I'm not really sure why, but It only does that when the source variable is missing a time component. Can you reset LastUpdateDate so it contains both a date and time?

This test code works for me:

This compares the exact current date AND time to the date+time format that is apparently returned by the APC UPS. That format is not quite what Rule Machine wants:

  • The date needs to be separated from the time by a "T"; accordingly, the first space is replaced by "T", which also replaces the second space.
  • Fortunately, the 2nd replacement uniquely results in "T+". RM doesn't want the "T" or the "+" either, it wants a decimal point, 3 digits of fractional seconds, and a hyphen separating the time from the time zone offset. So replace "T+" with ".000-".
  • After the replacements, the "LastUpdate_string_edit" string is converted to the DateTime variable "LastUpdateDate".

Note that I used a 2nd variable, "LastUpdate_string_edit" just to be able to track the changes from "LastUpdate_string". You could dispense with the 2nd variable and substitute "LastUpdate_string" for "LastUpdate_string_edit".

NOTE: the action "Set LastUpdateDate to %LastUpdate_string_edit%" is VERY, VERY TOUCHY -- if you get the format of the datetime string wrong in the slightest, the Rule will CRASH irrecoverably. Ask my how I know.

PS: The value for "LastUpdateDate" in the Local Variables table differs by 3 hours from the computed value actually used in the IF statement -- I have no idea why, but the IF statement uses the correct value.

2 Likes

That worked! Thanks so much. I spent hours playing around with this but with my limited knowledge I would have never figured out the need for the special date format. And didn't think of using the 'Time String' time operation either. The variable differs by 3 hours for me too but it doesn't cause an issue.
Thanks again!