use scripting additions
use framework "EventKit"
use framework "Foundation"
--Every other day
set recurrenceRule to my recurrenceRuleFromString("FREQ=DAILY;INTERVAL=2")
--> «class ocid» id «data optr00000000200393FFB97F0000»
my stringFromRecurrenceRule(recurrenceRule)
--> "FREQ=DAILY;INTERVAL=2"
on recurrenceRuleFromString(recur as text)
--require framework: EventKit, Foundation
--recurをパースしてdictionaryに変換
set RRULE to current application's NSMutableDictionary's dictionaryWithObject:1 forKey:"INTERVAL"
set scanner to current application's NSScanner's scannerWithString:(recur & ";")
repeat until scanner's atEnd as boolean
set {scanResult, |name|} to scanner's scanUpToString:"=" intoString:(reference)
set scanResult to scanner's scanString:"=" intoString:(missing value)
set {scanResult, value} to scanner's scanUpToString:";" intoString:(reference)
set scanResult to scanner's scanString:";" intoString:(missing value)
try
if |name|'s isEqualToString:"FREQ" then
set freqDictionary to (current application's NSDictionary's dictionaryWithObjects:{current application's EKRecurrenceFrequencyDaily, current application's EKRecurrenceFrequencyWeekly, current application's EKRecurrenceFrequencyMonthly, current application's EKRecurrenceFrequencyYearly} forKeys:{"DAILY", "WEEKLY", "MONTHLY", "YEARLY"})
set value to (freqDictionary's objectForKey:value)
else if |name|'s isEqualToString:"UNTIL" then
if (value's |length| as integer) = 8 then
set endDate to my dateFromStringUsingFormat(value, "yyyyMMdd")
else if (value's |length| as integer) = 15 then
set endDate to my dateFromStringUsingFormat(value, "yyyyMMdd'T'HHmmss")
else if (value's |length| as integer) = 16 then
set endDate to my dateFromStringUsingFormat(value, "yyyyMMdd'T'HHmmss'Z'")
set endDate to my shiftDateFromGMT(endDate)
end if
set value to (current application's EKRecurrenceEnd's recurrenceEndWithEndDate:endDate)
set |name| to "END"
else if |name|'s isEqualToString:"COUNT" then
set value to (current application's EKRecurrenceEnd's recurrenceEndWithOccurrenceCount:(value's integerValue))
set |name| to "END"
else if |name|'s isEqualToString:"INTERVAL" then
set value to value's integerValue
else if |name|'s isEqualToString:"BYDAY" then
set weekdayDictionary to (current application's NSDictionary's dictionaryWithObjects:{current application's EKSunday, current application's EKMonday, current application's EKTuesday, current application's EKWednesday, current application's EKThursday, current application's EKFriday, current application's EKSaturday} forKeys:{"SU", "MO", "TU", "WE", "TH", "FR", "SA"})
set recurrenceDayOfWeekArray to current application's NSMutableArray's array()
repeat with weekdaynum in (value's componentsSeparatedByString:",") as list
set |weekday| to (weekdayDictionary's objectForKey:(text -2 thru -1 of weekdaynum))
if (count weekdaynum) = 2 then
set recurrenceDayOfWeek to (current application's EKRecurrenceDayOfWeek's dayOfWeek:|weekday|)
else
set recurrenceDayOfWeek to (current application's EKRecurrenceDayOfWeek's dayOfWeek:|weekday| weekNumber:(text 1 thru -3 of weekdaynum as integer))
end if
(recurrenceDayOfWeekArray's addObject:recurrenceDayOfWeek)
end repeat
set value to recurrenceDayOfWeekArray
else if (current application's NSArray's arrayWithArray:{"BYMONTHDAY", "BYYEARDAY", "BYWEEKNO", "BYMONTH", "BYSETPOS"})'s containsObject:|name| then
set value to ((value's componentsSeparatedByString:",")'s valueForKeyPath:"self.integerValue")
else
set value to |name| & "=" & value
set |name| to "UNRECOGNIZED NAME"
end if
--RRULEに追加
(RRULE's setObject:value forKey:|name|)
--エラー
on error
error "Invalid " & |name| & " in Recurrence Rule: " & |name| & "=" & value
end try
end repeat
--EKRecurrenceRule作成
set nameSet to current application's NSSet's setWithArray:(RRULE's allKeys())
if nameSet's isSubsetOfSet:(current application's NSSet's setWithArray:{"FREQ", "INTERVAL", "END", "UNRECOGNIZED NAME"}) then
return current application's EKRecurrenceRule's alloc()'s initRecurrenceWithFrequency:(RRULE's objectForKey:"FREQ") interval:(RRULE's objectForKey:"INTERVAL") |end|:(RRULE's objectForKey:"END")
else
return current application's EKRecurrenceRule's alloc()'s initRecurrenceWithFrequency:(RRULE's objectForKey:"FREQ") interval:(RRULE's objectForKey:"INTERVAL") daysOfTheWeek:(RRULE's objectForKey:"BYDAY") daysOfTheMonth:(RRULE's objectForKey:"BYMONTHDAY") monthsOfTheYear:(RRULE's objectForKey:"BYMONTH") weeksOfTheYear:(RRULE's objectForKey:"BYWEEKNO") daysOfTheYear:(RRULE's objectForKey:"BYYEARDAY") setPositions:(RRULE's objectForKey:"BYSETPOS") |end|:(RRULE's objectForKey:"END")
end if
end recurrenceRuleFromString
on stringFromRecurrenceRule(recurrenceRule)
--require framework: Foundation
return (recurrenceRule's |description|'s componentsSeparatedByString:space)'s lastObject() as text
end stringFromRecurrenceRule
on dateFromStringUsingFormat(dateString as text, dateFormat as text)
--reference: UTS #35: Unicode Locale Data Markup Language - http://www.unicode.org/reports/tr35/tr35-25.html#Date_Format_Patterns
set dateFormatter to my currentDateFormatter(dateFormat)
return (dateFormatter's dateFromString:dateString) as date
end dateFromStringUsingFormat
on shiftDateFromGMT(aDate as date)
global timeToGMT
try
timeToGMT
on error number -2753
set timeToGMT to time to GMT
end try
return aDate + timeToGMT
end shiftDateFromGMT
on currentDateFormatter(dateFormat as text)
--require framework: Foundation
set dateFormatter to current application's NSDateFormatter's alloc()'s init()
set dateFormatter's locale to current application's NSLocale's currentLocale()
set dateFormatter's timeZone to current application's NSTimeZone's localTimeZone()
set dateFormatter's dateFormat to dateFormat
return dateFormatter
end currentDateFormatter