Adrian Nier Code

Back to overview

Create week number calendar

Last modification: Monday, August 25, 2008 12:47 am

Creates a calendar in iCal that has an all day event every monday representing the week number of the year.

Implementation

-- Ask the user for the range of years
set _startYear to askForIntegerWithPrompt(localizedString("start_year_dialog_message"), (year of (current date)))
set _endYear to askForIntegerWithPrompt(localizedString("end_year_dialog_message"), _startYear + 2)

-- Create a new calendar
set _calendar to newCalendarWithName(localizedString("week_numbers_calendar_name"))

-- Create the date object holding the first day
set _dateObj to firstDayOfYear(_startYear)

-- Generate the events
repeat
   set _title to (localizedString("week_number_prefix") & (weekNumber(_dateObj) as string))
   
   tell application "iCal" to make new event at the end of events of _calendar with properties {summary:_title, start date:_dateObj, end date:_dateObj, allday event:true}
   
   set _dateObj to _dateObj + (7 * 24 * 60 * 60)
   if year of _dateObj is (_endYear + 1) then exit repeat
end repeat


on askForIntegerWithPrompt(_prompt, _default)
   activate
   repeat
      try
         return text returned of (display dialog _prompt default answer _default) as integer
      on error _eMsg number _eNum
         if _eNum = -128 then error _eMsg number _eNum
         beep
      end try
   end repeat
end askForIntegerWithPrompt

on newCalendarWithName(_calendarName)
   set _calendarNumber to 1
   
   repeat
      if _calendarNumber is 1 then
         set _uniqueCalendarName to _calendarName
      else
         set _uniqueCalendarName to _calendarName & " " & (_calendarNumber as string)
      end if
      
      tell application "iCal" to if (exists of calendar _uniqueCalendarName) is false then exit repeat
      set _calendarNumber to _calendarNumber + 1
   end repeat
   
   tell application "iCal"
      create calendar with name _uniqueCalendarName
      return calendar _uniqueCalendarName
   end tell
end newCalendarWithName

on firstDayOfYear(_year)
   set _date to current date
   
   set year of _date to _year
   set month of _date to 1
   set day of _date to 1
   set time of _date to 0
   
   return _date
end firstDayOfYear

on weekNumber(_dateObject)
   
   
   script Week_Number_Extras
      
      -- Define an extra function to calculate how many days of a week belong to the next year
      on daysBelongingToNextYear(_dateObject)
         -- Find out how many of the next 6 days belong to the next year
         set _currentYear to year of _dateObject
         
         set _daysInNextYear to 0
         repeat with _dayOffset from 0 to 6
            if (year of (_dateObject + (_dayOffset * (24 * 60 * 60)))) ≠ _currentYear then
               set _daysInNextYear to _daysInNextYear + 1
            end if
         end repeat
         
         return _daysInNextYear
         
      end daysBelongingToNextYear
      
   end script
   
   -- Make a copy of the passed date object to avoid changes to the original
   copy _dateObject to _dateObjCopy
   
   -- Save the year for later
   set _yearOfGivenDate to year of _dateObjCopy
   
   -- Set the date back to a Monday
   repeat
      if weekday of _dateObjCopy is Monday then exit repeat
      set _dateObjCopy to _dateObjCopy - (24 * 60 * 60)
   end repeat
   
   -- Find out how many days of this week belong to the next year
   -- If at least 4 days do belong to next year then
   -- it’s safe to assume that it’s the first week of the year
   tell Week_Number_Extras to set _daysBelongingToNextYear to daysBelongingToNextYear(_dateObjCopy)
   if _daysBelongingToNextYear ≥ 4 then return 1
   
   -- Set the date back a week at a time until the previous year is reached
   -- Count how many weeks had to pass to reach the previous year
   set _weeksPassed to 0
   repeat
      if year of _dateObjCopy ≠ _yearOfGivenDate then exit repeat
      set _dateObjCopy to _dateObjCopy - (7 * 24 * 60 * 60)
      set _weeksPassed to _weeksPassed + 1
   end repeat
   
   -- Return the week number depending on wether the last monday of the previous year
   -- did belong to the first week of this year or not
   tell Week_Number_Extras to set _daysBelongingToNextYear to daysBelongingToNextYear(_dateObjCopy)
   if _daysBelongingToNextYear ≥ 4 then
      return _weeksPassed + 1
   else
      return _weeksPassed
   end if
   
end weekNumber

on localizedString(_string)
   
   set _stringKey to _string & "/" & systemLanguage()
   
   if _stringKey is "week_numbers_calendar_name/en" then return "Week numbers"
   if _stringKey is "week_numbers_calendar_name/de" then return "Kalenderwochen"
   
   if _stringKey is "start_year_dialog_message/en" then return "Please specify the year to start with:"
   if _stringKey is "start_year_dialog_message/de" then return "Bitte geben Sie an mit welchem Jahr angefangen werden soll:"
   
   if _stringKey is "end_year_dialog_message/en" then return "Please specify the year to end with:"
   if _stringKey is "end_year_dialog_message/de" then return "Bitte geben Sie an bis zu welchem Jahr es gehen soll:"
   
   if _stringKey is "week_number_prefix/en" then return "Week "
   if _stringKey is "week_number_prefix/de" then return "KW "
   
   
end localizedString

on systemLanguage()
   try
      return first word of (do shell script "defaults read NSGlobalDomain AppleLanguages")
   on error
      return "en"
   end try
end systemLanguage