How to set date format as plain text inside Set Variable?

When the Set Variable to Text action is set to process text, it sets the variable currentDate to the data that the '%ICUDateTime%` token represents at run-time:

"2022-05-13, 02.09.22 am"

When it is set to "Process Nothing", it sets currentDate to the literal string:

"%ICUDateTime%yyyy-MM-d, hh.mm.ss a%"

The Create New Folder action specifies a path at which to create a folder. Whatever currentDate is set as will make up part of that path, and that will either be the time captured when the variable was set or the literal string.

Good point. Another speedy way to enter the token would be to make a macro that inserts the text

%ICUDateTime%yyyy-MM-d hh.mm.ss a%

with a short typed string trigger. That would give you direct entry of the token when making new macros and avoid variables entirely.

1 Like

That's a good idea too! So something like this...

Date & Time.kmmacros (21 KB)

Macro screenshot

Exactly. The Value will change everywhere.

But you are asking for a Variable that is created by a maths, formula, token and want that “formula” to automatically change everywhere and to recalculate a new Value rather than use the original value that the formula arrived at, when the variable was created.

There is no mechanism for that (other than trying to break the formula down into every single mathematical element and number and making variables for each).

That could work for 1 + 2 where 1 and 2 are replaced by variables. But even in that case you would not be able to make “+” into a Variable directly. You would need to have a separate routine that looks to see if a Variable was say “+” or “-“ and applies the appropriate maths.

This would be completely impractical for your Date example and would anyway be too much work to make and too complex to use.

So, the answer to your question is, no you can’t do what you are asking.

2 Likes

But isn't this the exact same process when creating a variable? A variable sets a text and then when you call that variable, it uses that text.
I understand that we can have 2 formats:
1 - The variable gets assigned the date of when it was ran (Process Text Normally)
2 - The variable gets assigned a string/text (Process Nothing)

So in my mind, using the second option would be the right way to do it.
The issue here is that the New Folder action is not processing
%ICUDateTime%yyyy-MM-d hh.mm.ss a% properly (in my opinion).

It should use the text based on the variable and then the action itself would interpret that as a variable and replace %ICUDateTime%yyyy-MM-d hh.mm.ss a% with the actual date. Pretty much the same when we manually type/paste %ICUDateTime%yyyy-MM-d hh.mm.ss a% into the field.

I think we could have an option to set this as a string, for example, if instead of
Text Here - %Variable%VarName% (which would result, for example, in Text Here - The Sun is Shinning)
we used
Text Here - "%Variable%VarName%" (look at the quotes)
then we would have the folder/file name as
Text Here - %Variable%VarName%

Does it make sense?

@drdrang and @noisneil, what you guys are missing here, is that the goal is to use a variable that can easily be changed and used. The issue is not (only) that I need to remember this long string. yes, it helps, but I don't want to paste something that if needs to be changed in the future, then I have to go and open each macro, then each action, and change it. Let's say that one day I decide that instead of
2022-05-12, 11.17.24 PM
I want this
2022---05---12 - 11-17-24 PM
?

With a variable I just need to change it in one place.

The only way I found that this works (but I wanted to avoid that extra action) is to include an Execute Macro action before the New Folder action. This will execute the Variable macro (if it's set to Process Text) and update it to the current date. Will this be super accurate when it comes to the date, by the second or millisecond? Probably not, but in this particular case, not relevant. It gives me a pretty accurate date, different enough to create a new folder right away and end up with a new current date.

But yeah, my goal was to have variables work as they should (or what I think is the right way this should work) :slight_smile:

Not sure I totally understand what you mean...
From what I'm reading, you are probably misunderstanding what I mean, maybe because I'm using the wrong wording?

When you use the Create Folder action and you type for example:
New Folder Name - %ICUDateTime%yyyy-MM-d, hh.mm.ss a%
the Create Folder action itself will interpret this as
New Folder Name - 2022-05-12, 11.17.24 PM
right? And that's the name of the folder

Now when I'm using a variable currentDate that has this value assigned
%ICUDateTime%yyyy-MM-d, hh.mm.ss a%
(maybe this is what is causing the issue, that I use the word "value"?)
the end result should be exactly the same as when I manually type
New Folder Name - %ICUDateTime%yyyy-MM-d, hh.mm.ss a%

So typing
New Folder Name - %Variable%currentDate%
should be, at least in theory, the same as manually typing
New Folder Name - %ICUDateTime%yyyy-MM-d, hh.mm.ss a%
because that's what a variable is for.

I understand that we could set the variable "type" when using the Process Text vs Process Nothing, but to me Process Nothing should just use plain text and then the New Folder action would create the conversion between currentDate and the %ICUDateTime%yyyy-MM-d, hh.mm.ss a% "code" (or whatever that's proper name that thing has...)

Is it making sense what I'm trying to explain?
Are we talking about the same end result and same workflow? Let me know :slight_smile:

But when you set the variable to Process Nothing, it stops being a math, formula, token, and it becomes plain text, right? At least that's what I'm getting from that. That being said, when the variable becomes plain text, the New Folder action should interpret that as plain text so when using %Variable%currentDate%, the action should interpret this:
New Folder Name - %Variable%currentDate%
as this
New Folder Name - %ICUDateTime%yyyy-MM-d, hh.mm.ss a%

so when it processes that information, the end result should be:
New Folder Name - 2022-05-12, 11.17.24 PM

Right now, when set to Process Nothing it ends up creating a folder with this name:
New Folder Name - %ICUDateTime%yyyy-MM-d, hh.mm.ss a%
literally! :confused:

Yes, absolutely. But this cannot be done in the current implementation of Keyboard Maestro. What you are asking for is a new feature.

Yes, I think we could have for example the option to add quotes around a token and that would "print" the token itself as text and not what the token represents, you know?
Like this
New Folder - "%Variable%VarName%"
would actually create a new folder with that name:
New Folder - %Variable%VarName%

I'm using quotes as an example, not sure if this would be the right symbol, but you get the point :slight_smile: That way we would have 3 options available.

This is exactly my point :slight_smile:
If it's a literal string then the New Folder action should interpret that the same way as when we manually type %ICUDateTime%yyyy-MM-d, hh.mm.ss a% into the field (when we type, we are typing a literal string as well, right? It's plain text).

So the action itself should get that information from the variable and replace the string with the current date when creating the folder.

With the current way Keyboard Maestro works I would suggest you do this:

  1. Make a Subroutine Macro that creates the date in the form you would like.
  2. In each Macro that you want to use that date call the Subroutine.
  3. If you ever want to change the date format, you only have to do that in the Subroutine. All the calling Macros would be given the new date format without having to make any changes to them.

I'm not familiar with Subroutines yet, but I will research.
What I'm getting from it is that it's just a macro with a different name... am I missing something special about it...?

I was able to make it work last night and it's here:

I just need to run the macro with the variable. I believe it's the same as the subroutine?
Reading the documentation, didn't really clarify how different it is from running a macro
https://wiki.keyboardmaestro.com:8443/Subroutines

Hi @iamdannywyatt - after a good night's sleep and a bit of catching up with this thread I now have a better perspective on what you're after.

If I understand correctly now, what you want is the ability to save a "formula" in a variable and then evaluate that formula later by using a reference to the variable. Something like:

set TimeStamp to "%ICUDateTime%yyyy-MM-d, hh.mm.ss a%"
...
...
...
create a folder with name "BetterTouchTool Backup, EVALUATE(TimeStamp)"
...
...

In this example the name of the folder would be evaluated to something like this:

BetterTouchTool Backup, 2022-05-13, 10.21.56 am

In other words, you're using the contents of the variable TimeStamp as a kind of template.

While there is no direct equivalent in-line function in KM to the EVALUATE() function I've written above, you can achieve a similar effect by using KM's Filter action like so in this demonstration macro (which you'll need to tweak to suit your needs):

Test Indirect Evaluation.kmmacros (4.3 KB)

Click to see macro

The Filter with Process Tokens action takes what is in the variable and evaluates it thus allowing you to set up a global variable as a "template" for your timestamp. I've grouped this with the New Folder action to emphasise that they are both needed together for it to work as (I hope) you want it to.

After all the discussion I wonder if I'm on the right track? What do you think?

2 Likes

@iamdannywyatt, as @Zabobon so eloquently explained, we do understand what you're after, but it's not how KM works. In simplistic terms, the folder action processes what you write in the box once.

variable > data

What you're asking it to do is selectively process part of it twice.

variable > token > data

@tiffle has provided a nifty solution for changing the behaviour of the variable globally, but the trouble is that you need to trigger that process, so I still think the quickest option, practically speaking, is to recall a favourite that sets the variable to a preferred date format. That's one move. Inserting a subroutine and select its target is two moves.

Thanks for taking the time to go back to this thread and coming up with another solution :slight_smile:

My goal, though, is to make everything less confusing and faster to set up. Also, with the advantage of using global variables. In your example, it seems that each macro would have to have those 2 complex actions, which is something I would like to avoid.

I found a workaround that I detailed here:

Basically, before the New Folder action, I just run the variable's macro. That removes a lot of the extra actions and complexity. Even if the date is not accurate to the millisecond or second, in this particular scenario that's not relevant, as long as it finds the approximate current date so that I can run the same macro twice and it creates 2 distinct folders.

Basically, since running the variable's macro updates it to the current date, running the New Folder action right after it, will use the current date (add a few ms or sec, but not a big deal).

As I mentioned before, this would cause more problems, should I decide to change the format later on, because now all formats are "hard-coded" into each action. Let's say you used that in 100 actions... you will have to go back to each one of them and update the format manually. Having a variable, makes everything easier.

I shared my method of just running the variable right before the New Folder action, but it seems that everyone here is skipping that as a "valid" approach hahaha. Am I missing something here? Because that seems to be the most simple and fast approach, and also the easier to update should I decide to make changes to the format.

If I'm missing something about that approach, please let me know, as I'm still learning KM :slight_smile:

Nope.

I'm sorry but I assumed you had more experience with KM than perhaps you have. My demo macro is exactly that and just illustrates the principle involved and, for testing, I always use local variables so I don't get cluttered up with variables I'll never use again.

So - the first action coloured orange would be in a separate macro and would, in your case, assign the literal string to a global variable that you want to be your template for a timestamp. Like this:

The (teal-coloured) group of actions would be in your other macro(s) where you want to actually generate the timestamp from the template. You would set the green Filter action to refer to your global variable template. To illustrate, I've ungrouped the actions to make it more obvious what's going on:

KM 1 2022-05-13_12-40-51

In terms of complication, you've made it more complicated by having 2 macros since you can assign that ICUDate string directly to a variable using KM's variable inspector in the KM preferences

So instead of using the simple Filter action you choose to execute a separate macro.

Well, you're just replacing one action (Filter) with another (Execute Macro) and that macro contains a Set Variable action. So it looks like you're swapping my one action for your 2 actions!

The beauty of KM is that it provides enough options to satisfy everyone - so good luck and have fun!

2 Likes

No problem. Yes, I'm still learning :slight_smile:

Ok. Yes, in this case, I want it to be global, because I have a lot of apps that I need to create backups from on a regular basis.

Not really. I have 3 actions, just like you do:
1 - Set a Variable inside a macro, something I will not have to change at all.
2 - The action to run the variable
3 - The action to create the folder

You have 3 actions as well: orange, green, gray.

Now the difference I see on my approach, is that I don't have to worry much about filling out 2 fields ("Filter" and "To") or remember what those are supposed to be. All I need to do is go to the Execute Macro dropdown menu > "Select Macro by Name" > type "Current Date" and that's it. I'm good to go.

Your approach is also useful at least for me to learn another new thing that could be useful in another scenario. In this case, it seems that my approach (unless there's something I'm missing in terms of running into issues) is faster and easy to remember.

So true and it's through seeing other people's approach that we end up learning new ways of achieving the same results, but sometimes in a better way. Been learning a lot from reading other people's threads

Brilliant @tiffle, you have done what I was sure could not be done! That filter Action is very powerful.

1 Like