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.
For example, if I type 23 Jan 2023, I would like to select the text and run the macro which would:
23 Jan 2023
Monday
Mon 23 Jan 2023
Thanks in advance for your time and help.
Hey @ronald,
Yes...
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
1/10/2023
There might be issues caused by system date settings if they are not U.S.
If you have any problems report back.
-Chris
Convert Selected Date String to a Given Format v1.00.kmmacros (9.8 KB)
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)
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)
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!Â
Would you mind providing a more formally written sample (i.e. not a one-liner)?
TIA.
-Chris
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.
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}
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.
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:
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.
Thank you
Laid out in a more script-like form, and not relying on command-line switches, it would be this:
#!/usr/bin/perl
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”:
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.
Etcetera.
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:
I've also used a few different utilities on Windows, but it was 2009 (I think) when I last used a PC.
So kind of you to take that time Christopher. I will bookmark it. It is time I stretched a bit on my snippets.