Is There a Way to Add the Day of the Week to a Date?

For example, if I type 23 Jan 2023, I would like to select the text and run the macro which would:

  • Copy the date string: 23 Jan 2023
  • Determine that it's a Monday
  • Convert to: Mon 23 Jan 2023

Thanks in advance for your time and help.

Hey @ronald,


While this is possible using Keyboard Maestro native actions, you have to live with a fixed date format (or detect between a variety of fixed formats).

AppleScript Data Detectors allow the user to be a little more lazy about the format of their original date string. These all work on my system:

jan 10 2023
10 jan 2023
10 jan 23

There might be issues caused by system date settings if they are not U.S.

If you have any problems report back.


Convert Selected Date String to a Given Format v1.00.kmmacros (9.8 KB)

Macro Image

Keyboard Maestro Export


If you're sure you will always use the "23 Jan 2023" format, there's a simpler (or at least shorter) way using the shell's date command.

Date with DOW.kmmacros (2.4 KB)

Show screenshot of macro

The shell script is

date -j -f '%d %b %Y' '+%a %-d %b %Y' "$KMVAR_localDate"

I'm assuming you prefer output of "Thu 5 Jan 2023" over "Thu 05 Jan 2023." If you want the leading zero in the output, delete the hyphen in %-d. Either way, you don't need the leading zero in the input.

To get the kind of input flexibility @ccstone's solution provides, you could write a Perl one-liner that uses the Date::Parse library:

Date with DOW.kmmacros (2.2 KB)

Show screenshot of macro

Here, the shell script is

perl -MTime::Piece -MDate::Parse -nle '$ts=str2time($_); print localtime($ts)->strftime("%a %-d %b %Y")'

This is no better than @ccstone's AppleScript, just a different approach.

I think the key to both of our answers is that while Keyboard Maestro has excellent facilities for formatting dates, it has no built-in way to parse dates. You have to use some outside scripting utility to parse the date, and while you're there, you might as well format the date, too.


Hey Drang,

I don't like using date for this purpose simply because of the dependency upon a strict format, but it can be very useful as you say when dealing with said fixed format.

Love the Perl!  :sunglasses:

Would you mind providing a more formally written sample (i.e. not a one-liner)?



1 Like

@ccstone @drdrang
thanks very much !

1 Like

Are you actually doing the typing? If so you have total control over the format and this looks like a fine use case for a typed string trigger. So you could expand ;18012023; to "Wed 18 Jan 2023" with:

ddMMYYYY to Date stamp.kmmacros (2.5 KB)


It's less versatile the either @ccstone's or @drdrang's solutions, but it does make it very easy to customise to what's natural to you for date entry. Perhaps you only ever enter dates in the 2000s and like / delimiters instead of padding the day and month -- strip the ;s and treat the remainder as an array. So you'd type ;18/1/23; and:

d-slash-M-slash-YY to Date stamp.kmmacros (3.0 KB)


With a consistent data format and a little bit of text processing -- the world's your oyster!


Very interesting...

You are opening the pandora's box of macros triggered by strings which i ignored until now.

Thanks very much. I will play around with the concept.

1 Like

Be careful – typed-trigger macros are mostly for text-expansion and generally shouldn't be used outside of text fields/editors.

But they're useful as all get-out – I have almost 49,000 text expansions in Typinator – and quite a few in Keyboard Maestro where KM's features are needed.

I use them many times per day.

I have a few hundred in Typinator (49 K !!!), and was precisely working on a Typinator solution to avoid having 2 sources of expansion. thank you for the comment.

You do know that Typinator has its own date-expansion format, so you can do all kinds of expansions for the current date and/or time.

One of mine for instance: dt expands to 2023/01/17 14:13

In Typinator-speak it looks like this:

{YYYY}/{MM}/{DD} {h024}:{m}
1 Like

Yes, I use the exact same expansion.

The problem is what you write 6 Feb 2023 and want to add the day in which case I can search and replace with your macro that of @drdrang or use @Nige_S ' string method.

1 Like

Right. I use this technique all the time to convert various date formats to my preferred formats.

I made this easy to modify in the macro:


ICU Date/Time Format Syntax

1 Like

Thank you for the reference on ICU formatting!

It's in the Keyboard Maestro Editor Help menu if you lose the URL – as is the ICU regular expression syntax guide.

1 Like

Thank you

Laid out in a more script-like form, and not relying on command-line switches, it would be this:


use Time::Piece;
use Date::Parse;

my $dateString = <STDIN>;
chomp $dateString;
my $timeStamp = str2time($dateString);
print localtime($timeStamp)->strftime("%a %-d %b %Y");

Ignoring the question, I have several short text macros that give the following formats

27/01/2023 21:50:15 << email date stamp
20230127 2150 <<quick filename append for version control

%ICUDateTime%ddMMMyyyy HH:mm EEE% <<Used for diary/log entries

Quick Checkpoint for file name
CKP %ICUDateTime%yyyyMMdd HHmmss%

This one also has a time offset (no allowance for summertime etc)
%ICUDateTime%EEEddMMMyyyy HH:mm%UK [and %ICUDateTimeMinus%6%Hours%EEE HH:mm% in Belize]
used for many emails to Belize.

Hope this helps..... 27Jan2023 21:57 Fri

How do you find them?

I am still staggered by that number. I have maybe 35.

Really how does it work for you? Are they systematic in some way and complete pieces of code?

That is my guess.


Typinator has a very sophisticated Quick-Search mechanism.

Categories can be globally available to search, or you can designate a label that's required to search that category.

Here are my AppleScript handlers (subroutines) with a category label of “h” and text search of “BBEdit”:

  • I export these handler-calls from my AppleScript Libraries with a script that auto-numbers them.
  • The prefix (abbreviation) for the handler-calls I only use as a filter.
    • FLb.## means “Find Library” handler number ##.
    • GLb.## means “General Library” handler number ##.
    • NLb.## means “Net Library” handler number ##.

If I can't remember the handler name – but I know what library it's in I can use the library name in the filter to restrict to just that library and then start drilling down to what I'm looking for.

I have a good memory for abbreviations that I use regularly, and I use mnemonics to make them more memorable and also easy to figure out.

cs<space>	== Christopher Stone 		(must be lower case)
dt<space>	== 2023/01/27 19:11			(date/time)
ffd<space>	== 2023-01-27 › 19.12.46	(Finder Formated Date)
etc<space>	== etcetera 				(must be lower case)
etcc<space>	== Etcetera 				(extra c means capitalized)
km<space>	== Keyboard Maestro 		(must be lower case)
kmv<space>	== Keyboard Maestro 10.2	(script that computes the KM version)
mos<space>	== macOS	 				(must be lower case)
osv<space>	== macOS 10.14.6 			(script that computes the macOS version)

I punctuate anything that might need to be isolated from other strings:

c;<space>	== Chris 			(must be lower case)
pnt;<space>	== @Pending @Now 	(must be lower case)

A whole lot of my expansions are for use with Quick-Search only, so I don't have to remember much.

I have the TidBITS Auto-Correct library which is a pretty large collection.

I have all sorts of code snippets.

I use text-tags liberally when things are hard to find.


How do I remember everything? The real answer is that I don't remember everything – I remember a great deal (especially those things I use regularly), and I've made things relatively easy to find if I forget.

The enormous utility of Quick-Search is the single biggest reason I switched to Typinator a decade or so ago.

Before that I used in order:

  • My own system driven by QuicKeys and AppleScript.
  • TypeIt4Me
  • TextExpander

I've also used a few different utilities on Windows, but it was 2009 (I think) when I last used a PC.

  • PhraseExpress was my favorite at the time (I think it's gotten ridiculously expensive since then.)

So kind of you to take that time Christopher. I will bookmark it. It is time I stretched a bit on my snippets.

1 Like