Formatter.Date (Date Formatter)
At some point, your scripts may need to display or request date information to or from a user. Using the properties and functions of the Formatter.Date class you can control the formatting of dates, and can even parse “natural language” date/time descriptors to return new JavaScript date objects.
Class Properties
iso8601 (Formatter.Date) • Return a date formatter that produces ISO–8601 formatted dates, using the Gregorian calendar and the UTC time zone.
Current Date in ISO8601 Format
fmtr = Formatter.Date.iso8601
fmtr.stringFromDate(new Date())
The resulting ISO8601 Format date string for today is:
Class Functions
withStyle(dateStyle: Formatter.Date.Style, timeStyle: Formatter.Date.Style or null) → (Formatter.Date) • A formatter that will display dates according to the specified date and time formats selected in system settings.
withFormat(format: String) → (Formatter.Date) • Returns a formatter with a specific ICU date format and the user’s current locale, calendar, and timeZone. See http://userguide.icu-project.org/formatparse/datetime/ for details on date format strings.
Instance Properties
calendar (Calendar) • The calendar used by the formatter instance.
dateFormat (String r/o) • The date format string used by the formatter instance.
locale (Locale) • The locale used by the formatter instance.
timeZone (TimeZone) • The time zone used by the formater instance.
Instance Functions
stringFromDate(date: Date) → (String) • A function that returns a text string formatted using the formatter’s settings.
dateFromString(string: String) → (Date or null) • A function that returns a date object determined by parsing the provided text string.
Time Format
fmtr = Formatter.Date.withFormat('h:mm a')
fmtr.stringFromDate(new Date())
//--> 5:19 AM
This example uses the Speech classes to vocalize the current time and date:
Vocalizing the Current Time and Date
dteStr = Formatter.Date.withFormat('h:mma, EEEE, LLLL d').stringFromDate(
new Date()) //--> "12:07AM, Wednesday, March 2"
utterance = new Speech.Utterance(`It is ${dteStr}`)
voice = Speech.Voice.withLanguage(Speech.Voice.currentLanguageCode)
utterance.voice = voice
new Speech.Synthesizer().speakUtterance(utterance)
Other examples of format strings:
'K:mm a, z' --> "7:48 AM, PDT"
"h 'o''clock' a, zzzz" --> "7 o'clock AM, Pacific Daylight Time"
"yyyy.MM.dd G 'at' HH:mm:ss zzz" --> "2020.08.07 AD at 07:56:23 PDT"
"yyyy/MM/dd '@' HH:mm a" --> "2020/08/07 @ 07:58 AM"
Setting Time Zone for Formatter
fmtr = Formatter.Date.withFormat("K:mm a, zzzz")
fmtr.timeZone = new TimeZone("EST")
fmtr.stringFromDate(new Date())
//--> "3:15 PM, Eastern Daylight Time"
There are also options for using standard date formatting styles:
Formatter Date Style
var fmtrShortStyle = Formatter.Date.Style.Short
var fmtrLongStyle = Formatter.Date.Style.Long
var fmtr = Formatter.Date.withStyle(fmtrLongStyle,fmtrShortStyle)
fmtr.stringFromDate(new Date())
//--> "August 7, 2021 at 1:42 PM"
Formatter.Date.Style
Full (Formatter.Date.Style r/o) • Use the user’s “full” format as selected in system settings.
Long (Formatter.Date.Style r/o) • Use the user’s “long” format as selected in system settings.
Medium (Formatter.Date.Style r/o) • Use the user’s “medium” format as selected in system settings.
Short (Formatter.Date.Style r/o) • Use the user’s “short” format as selected in system settings.
all (Array of Formatter.Date.Style r/o) • An array of all items of this enumeration. This property is often used when creating action forms.
Here are some of the possible combinations of date/time formatting.
NOTE: including time is optional, and time and date formats are not required to be the same.
Date Formatter Style Options
Formatter.Date.withStyle(Formatter.Date.Style.Full)
//--> Sunday, October 1, 2017
Formatter.Date.withStyle(Formatter.Date.Style.Full, Formatter.Date.Style.Full)
//--> Sunday, October 1, 2017 at 5:21:07 PM Pacific Daylight Time
Formatter.Date.withStyle(Formatter.Date.Style.Long)
//--> October 1, 2017
Formatter.Date.withStyle(Formatter.Date.Style.Long, Formatter.Date.Style.Long)
//--> October 1, 2017 at 5:26:51 PM PDT
Formatter.Date.withStyle(Formatter.Date.Style.Medium)
//--> Oct 1, 2017
Formatter.Date.withStyle(Formatter.Date.Style.Medium, Formatter.Date.Style.Medium)
//--> Oct 1, 2017, 5:29:41 PM
Formatter.Date.withStyle(Formatter.Date.Style.Short)
//--> 10/1/17
Formatter.Date.withStyle(Formatter.Date.Style.Short, Formatter.Date.Style.Short)
//--> 10/1/17, 5:24 PM
Here’s an example plug-in that will place a date/time stamp in the chosen format on the pasteboard.
Put Date/Time Stamp on Clipboard
/*{
"type": "action",
"targets": ["omnifocus","omnigraffle",
"omniplan", "omnioutliner"], "author": "Otto Automator",
"identifier": "com.omni-automation.all.date-time-stamp-on-clipboard",
"version": "1.1",
"description": "Puts the chosen formatted date/time stamp on the pasteboard.",
"label": "Date-Time Stamp",
"shortLabel": "Date-Time Stamp",
"paletteLabel": "Date-Time Stamp",
"image": "cursorarrow.click.badge.clock"
}*/
(() => {
var preferences = new Preferences() // NO ID = PLUG-IN ID
function generateMenuItems(){
now = new Date()
fullStyle = Formatter.Date.Style.Full
longStyle = Formatter.Date.Style.Long
mediumStyle = Formatter.Date.Style.Medium
shortStyle = Formatter.Date.Style.Short
// DATE ONLY
opt0 = Formatter.Date.withStyle(fullStyle).stringFromDate(now)
// "Thursday, June 17, 2021"
opt1 = Formatter.Date.withStyle(longStyle).stringFromDate(now)
// "June 17, 2021"
opt2 = Formatter.Date.withStyle(mediumStyle).stringFromDate(now)
// "Jun 17, 2021"
opt3 = Formatter.Date.withStyle(shortStyle).stringFromDate(now)
// "6/17/21"
// FULL DATE AND VARIOUS TIME
opt4 = Formatter.Date.withStyle(fullStyle, fullStyle).stringFromDate(now)
// "Thursday, June 17, 2021 at 2:10:50 PM Pacific Daylight Time"
opt5 = Formatter.Date.withStyle(fullStyle, longStyle).stringFromDate(now)
// "Thursday, June 17, 2021 at 2:10:50 PM PDT"
opt6 = Formatter.Date.withStyle(fullStyle, mediumStyle).stringFromDate(now)
// "Thursday, June 17, 2021 at 2:10:50 PM"
opt7 = Formatter.Date.withStyle(fullStyle, shortStyle).stringFromDate(now)
// "Thursday, June 17, 2021 at 2:10 PM"
// LONG DATE AND VARIOUS TIME
opt8 = Formatter.Date.withStyle(longStyle, fullStyle).stringFromDate(now)
// "June 17, 2021 at 2:24:16 PM Pacific Daylight Time"
opt9 = Formatter.Date.withStyle(longStyle, longStyle).stringFromDate(now)
// "June 17, 2021 at 2:25:07 PM PDT"
opt10 = Formatter.Date.withStyle(longStyle, mediumStyle).stringFromDate(now)
// "June 17, 2021 at 2:25:44 PM"
opt11 = Formatter.Date.withStyle(longStyle, shortStyle).stringFromDate(now)
// "June 17, 2021 at 2:26 PM"
// MEDIUM DATE AND VARIOUS TIME
opt12 = Formatter.Date.withStyle(mediumStyle, fullStyle).stringFromDate(now)
// "Jun 17, 2021 at 2:10:50 PM Pacific Daylight Time"
opt13 = Formatter.Date.withStyle(mediumStyle, longStyle).stringFromDate(now)
// "Jun 17, 2021 at 2:10:50 PM PDT"
opt14 = Formatter.Date.withStyle(mediumStyle, mediumStyle).stringFromDate(now)
// "Jun 17, 2021 at 2:10:50 PM"
opt15 = Formatter.Date.withStyle(mediumStyle, shortStyle).stringFromDate(now)
// "Jun 17, 2021 at 2:10 PM"
// SHORT DATE AND VARIOUS TIME
opt16 = Formatter.Date.withStyle(shortStyle, fullStyle).stringFromDate(now)
// "6/17/21, 2:10:50 PM Pacific Daylight Time"
opt17 = Formatter.Date.withStyle(shortStyle, longStyle).stringFromDate(now)
// "6/17/21, 2:10:50 PM PDT"
opt18 = Formatter.Date.withStyle(shortStyle, mediumStyle).stringFromDate(now)
// "6/17/21, 2:10:50 PM"
opt19 = Formatter.Date.withStyle(shortStyle, shortStyle).stringFromDate(now)
// "6/17/21, 2:10 PM"
return [opt0,
opt1, opt2, opt3, opt4, opt5, opt6, opt7, opt8, opt9, opt10, opt11, opt12, opt13, opt14, opt15, opt16, opt17, opt18, opt19] }
const action = new PlugIn.Action(async function(selection, sender){
defaultMenuIndex = 0
menuIndex = preferences.readNumber("optionsMenuIndex")
if(!menuIndex){
menuIndex = defaultMenuIndex
preferences.write("optionsMenuIndex", defaultMenuIndex)
}
menuItems = generateMenuItems()
menuIndexes = menuItems.map((item, index) => index)
formattedDateOptions = new Form.Field.Option(
"chosenStyle",
"Format",
menuIndexes,
generateMenuItems(),
menuIndex
)
inputForm = new Form()
inputForm.addField(formattedDateOptions)
formPrompt = "Choose a style:"
buttonTitle = "Continue"
formObject = await inputForm.show(formPrompt, buttonTitle)
index = formObject.values["chosenStyle"]
chosenStyle = menuItems[index]
preferences.write("optionsMenuIndex", index)
console.log(chosenStyle)
Pasteboard.general.string = chosenStyle
});
action.validate = function(selection, sender){
return true
};
]
return action;
})();
TIP: For speed, in the Automation Configuration dialog assign the plug-in a keyboard shortcut. Then it can be called and completed via two quick keyboard commands!
Shorthand Language
In Omni applications, date entry fields support the entering of shortcut date terminology, such as the words: “today” or “tomorrow” or shorthand values like: “+3d” or “3 days”
The value for a date input field can written using any syntax supported by an OmniOutliner date field. For example:
- 2d, –3w, 1h, 1y1m, and so on • Relative dates and times put the date at a certain amount of time from right now. Negative numbers represent times in the past.
- 2 days, –3 weeks, 1 hour, 1 year 1 month, and so on • You can use the full names of units too.
- yesterday, tomorrow, tonight, next thursday, last month, this friday, and so on • You can refer to relative dates using common words. “This”, “next”, and “last” have specific meanings: this friday always means the Friday in this week, next friday always means the Friday in the next week, and last friday always means the Friday in last week, regardless of what day today is. Other units work in the same way.
- september, fri, 2019, and so on • If you enter the name of a specific time period, the date will be at its beginning. So september means September first.
- 5/23/08 10a, 9.30.09 2:00 PM, and so on • You can use the short date format as defined in your Language & Region system preferences.
- 2w sat, 4d @ 5p, mon 6a, aug 6 tue 5p, and so on • Mix the available formats however you like.
- now, 9, 14:00, tom, and so on • Omni’s date parser makes its best guess at things like bare numbers, times, and word fragments.
Using an instance of the shared Formatter.Date class, you can convert those supported shorthand terms into date objects for use in scripts!
For example, the following script shows how to create a date object for three days from today at 9:30AM
Generate Date Object from Shorthand
// in three days at 9:30AM
fmtr = Formatter.Date.withStyle(Formatter.Date.Style.Short)
dateObj = fmtr.dateFromString('3d @ 9:30a')
Here's an OmniFocus example where the script locates all tasks whose deferment date/time occurs sometime tomorrow:
All Tasks Whose Deferment Occurs Tomorrow
fmtr = Formatter.Date.withStyle(Formatter.Date.Style.Short)
tomorrow = fmtr.dateFromString('tomorrow')
dayAfterTomorrow = fmtr.dateFromString('2 days')
deferredTasks = flattenedTasks.filter(task => {
return task.deferDate > tomorrow && task.deferDate < dayAfterTomorrow
})
For more commonly used date comparison functions, see the Date class documentation.
JavaScript Date Format Functions
The JavaScript language has numerous built-in date formatting functions that are demonstrated in the following plug-in that displays the indicated date in a variety of standard formats:
JavaScript Date Format Functions
/*{
"type": "action",
"targets": ["omnifocus","omnigraffle","omniplan","omnioutliner"],
"author": "Otto Automator",
"identifier": "com.omni-automation.all.date-formats-for-date",
"version": "1.1",
"description": "This action will display a dialog containing various formatted date string for the provided date.",
"label": "Date Formats for Date",
"shortLabel": "Date Formats",
"paletteLabel": "Date Formats",
"image": "calendar"
}*/
(() => {
const action = new PlugIn.Action(async function(selection, sender){
dateInputField = new Form.Field.Date(
"dateInput",
null,
new Date()
)
inputForm = new Form()
inputForm.addField(dateInputField)
inputForm.validate = function(formObject){
dateInput = formObject.values["dateInput"]
return (!dateInput) ? false : true
}
formPrompt = "Enter a date:"
buttonTitle = "Continue"
formObject = await inputForm.show(formPrompt, buttonTitle)
dateObj = formObject.values["dateInput"]
dateObjStr = dateObj.toString()
dateStr = dateObj.toDateString()
timeStr = dateObj.toTimeString()
ISOStr = dateObj.toISOString()
GMTStr = dateObj.toGMTString()
JSONDate = dateObj.toJSON()
locString = dateObj.toLocaleString()
locDateStr = dateObj.toLocaleDateString()
locTimeStr = dateObj.toLocaleTimeString()
results = [
"Date:", dateObjStr,
"ISO8601:" , ISOStr,
"GMT:", GMTStr,
"JSON:", JSONDate,
"LOCALIZED:", locString
].join("\n")
console.log(results)
message = [
dateObjStr,
"\nISO8601:" , ISOStr,
"\nGMT:", GMTStr,
"\nJSON:", JSONDate,
"\nLOCALIZED:", locString
].join("\n")
new Alert("Date Formats", message).show()
});
action.validate = function(selection, sender){
return true
};
return action;
})();