Time zone conversion?


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?


1 Like

In TextExpander I don’t know, but in Typinator you can do this:

Abbreviation (regex):



{{refTime=$1}}{h12}:{m}{a} PT ({{hourDelta=+3}}{h12}:{m}{a} ET)

The input must be in 24h format (1-24). Example:

9:15ptet → 9:15am PT (12:15pm ET)
17:20ptet → 5:20pm PT (8:20pm ET)

Hey Giovanni,

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.


# 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)
   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
      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"
   set outputDate2 to ""
end if

set AppleScript's text item delimiters to linefeed
return {outputDate1, outputDate2} as text

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
      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:
1 Like

You can do this in Keyboard Maestro using the regular expression text expansion:


The resulting expansion comes in as the %TriggerValue% - put that in a variable and then use the Search Variable action with:


to extract the three components.

You then just need to figure out the other time based on the hour and the a/p, and then insert it as appropriate.

Both Time Zones.kmmacros (6.6 KB)


Wow. This works perfectly!

Thank you so much! :grinning:

Glad you found a solution.

If one of the above posts solves your problem/question as originally stated, please check the "Solved" checkbox (click this link for details) at the bottom of that post.

Otherwise, please post your remaining questions/issues about this problem.
If you have other questions, please start a new topic.

done. thanks!