Convert clipboard date to yyyy-mm-dd

Yes, but...   :sunglasses:

AppleScriptObjC provides access to data-detectors, and they're pretty good at deciphering date strings.

(Failures are most likely to occur in date-strings where the day precedes the month and is less-than or equal to 12.)

I don't have time to make this pretty, but it will take a wide variety of date-string input and produce an ISO 8601 formatted date-string output.

-Chris

* Note for the uninitiated – this is an AppleScript that uses AppleScriptObjC. It can be run directly in the Script Editor.app or in a Keyboard Maestro Execute an AppleScript action.

------------------------------------------------------------
# Auth: Christopher Stone <scriptmeister@thestoneforge.com>
# Auth: Shane Stanley graciously provided the ASObjC handlers.
# 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.
#     : Output an ISO 8601 formatted date-string.
# Libs: None
# Osax: None
# Tags: @Applescript, @Script, @ASObjC, @Date, @String
------------------------------------------------------------
use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
------------------------------------------------------------

# Example Date String Input
set theDate to my getDatesIn:"Some text containing Nov 5, for example"
set theDate to my getDatesIn:"2015/1/5"
set theDate to my getDatesIn:"1/5/2016"
set theDate to my getDatesIn:"4 May 1961"
set theDate to my getDatesIn:"jan 1 2012"

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 outputDate to my formatDate:(theDate) usingFormat:"y-MM-dd"
return outputDate

------------------------------------------------------------
--» 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:
------------------------------------------------------------
6 Likes