When scheduling meetings across timezones, I often find myself converting PT to ET: for example, if I want 10am PT I will need to write “10am PT (1pm ET)”.
I would like to have a macro triggered by some string, which takes the time I enter in PT, and returns 2 times: PT and converted to ET.
For example, assuming that the trigger is “ptet”, if I type “10:15amptet” the macro will return “10:15am PT (1:15pm ET)”.
This will include string parsing and some basic operations. Would you recommend trying that in KM, or in TextExpander?
TextExpander will probably be a little faster, since it’s dedicated to text-substitution.
I would use something like the following AppleScript which allows for some English-language syntax in the date discovery.
I’ve used the character “x” to indicate “process after this”, because it’s unlikely to come up in the input string.
Experiment with the Example Date String Inputs in the Script Editor.app before trying to use the script in either Keyboard Maestro or TextExpander.
-Chris
------------------------------------------------------------------------------
# Auth: Christopher Stone { Heavy Lifting by Shane Stanley }
# dCre: 2016/03/17 03:45
# dMod: 2016/03/17 04:09
# Appl: AppleScriptObjC
# Task: Use Data-Detectors to extract a date from unstructured string input with optional conversion.
# : Output an ICU Formatted Date-String.
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @ASObjC, @Date, @String, @Data-Detectors
------------------------------------------------------------------------------
use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
------------------------------------------------------------------------------
set conversionStr to missing value
# Example Date String Inputs:
set inputStr to "10:30am"
set inputStr to "10:30"
set inputStr to "tomorrow 10:30xe"
set inputStr to "tomorrow 10:30xp"
set inputStr to "tues 10:30xp"
if inputStr contains "x" then
set AppleScript's text item delimiters to "x"
set conversionStr to text item 2 of inputStr
set inputStr to text item 1 of inputStr
end if
set theDate to my getDatesIn:inputStr
set theDate to first item of (theDate as list)
if conversionStr = "e" then
set convertedDate to theDate + (1 * hours)
else if conversionStr = "p" then
set convertedDate to theDate - (2 * hours)
else
set convertedDate to ""
end if
------------------------------------------------------------------------------
# Output formatted date-string.
------------------------------------------------------------------------------
considering numeric strings
if AppleScript's version < "2.5" then
set theDate to my makeASDateFrom:theDate
else
set theDate to theDate as date
end if
end considering
# Date String Output
set outputDate1 to my formatDate:(theDate) usingFormat:"y-MM-dd hh:mm"
if convertedDate ≠ "" then
set outputDate2 to my formatDate:(convertedDate) usingFormat:"y-MM-dd hh:mm"
else
set outputDate2 to ""
end if
set AppleScript's text item delimiters to linefeed
return {outputDate1, outputDate2} as text
------------------------------------------------------------------------------
------------------------------------------------------------------------------
--» HANDLERS
------------------------------------------------------------------------------
on formatDate:theDate usingFormat:formatString
if class of theDate is date then set theDate to my makeNSDateFrom:theDate
set theFormatter to current application's NSDateFormatter's new()
theFormatter's setLocale:(current application's NSLocale's localeWithLocaleIdentifier:"en_US_POSIX")
theFormatter's setDateFormat:formatString
set theString to theFormatter's stringFromDate:theDate
return theString as text
end formatDate:usingFormat:
------------------------------------------------------------------------------
on getDatesIn:aString
# Convert string to Cocoa string
set anNSString to current application's NSString's stringWithString:aString
# Create data detector
set theDetector to current application's NSDataDetector's dataDetectorWithTypes:(current application's NSTextCheckingTypeDate) |error|:(missing value)
# Find first match in string; returns an NSTextCheckingResult object
set theMatch to theDetector's firstMatchInString:anNSString options:0 range:{0, anNSString's |length|()}
if theMatch = missing value then error "No date found"
# Get the date property of the NSTextCheckingResult
set theDate to theMatch's |date|()
return theDate
end getDatesIn:
------------------------------------------------------------------------------
# Required before 10.11
on makeASDateFrom:theNSDate
set theCalendar to current application's NSCalendar's currentCalendar()
set comps to theCalendar's componentsInTimeZone:(missing value) fromDate:theNSDate # 'missing value' means current time zone
tell (current date) to set {theASDate, year, day, its month, day, time} to ¬
{it, comps's |year|(), 1, comps's |month|(), comps's |day|(), (comps's hour()) * hours + (comps's minute()) * minutes + (comps's |second|())}
return theASDate
end makeASDateFrom:
------------------------------------------------------------------------------
on makeNSDateFrom:theASDate
set {theYear, theMonth, theDay, theSeconds} to theASDate's {year, month, day, time}
if theYear < 0 then
set theYear to -theYear
set theEra to 0
else
set theEra to 1
end if
set theCalendar to current application's NSCalendar's currentCalendar()
set newDate to theCalendar's dateWithEra:theEra |year|:theYear |month|:(theMonth as integer) ¬
|day|:theDay hour:0 minute:0 |second|:theSeconds nanosecond:0
return newDate
end makeNSDateFrom:
------------------------------------------------------------------------------