Pseudocode ---------- All position offsets are from the beginning of the 0x8216 MAPI ID. The existence of this MAPI ID with nonzero length should signify a recurrence. Constants: week_table { 0x02 = Monday 0x04 = Tuesday 0x08 = Wednesday 0x10 = Thursday 0x20 = Friday 0x40 = Saturday 0x01 = Sunday } Bitwise OR of above makes multiple selection of days month_table { 0x0000 = January 0x60AE = February 0xE04B = March 0x40FA = April 0x00A3 = May 0x6051 = June 0x20FA = July 0x80A8 = August 0xE056 = September 0xA0FF = October 0x00AE = November 0xC056 = December } switch on value of position 0x04 case 0x0A daily_recurrence() case 0x0B weekly_recurrence() case 0x0C monthly_recurrence() case 0x0D yearly_recurrence() sub daily_occurrence { # There are 2 types of daily recurrences # 1 - Every X days # 2 - Every weekday (Mon-Fri) # Each can have either an indefinite period, or end after Y # recurrences if position 0x16 == (0x23 or 0x22 or 0x21) # This is type 1 above X = value for MAPI Code: [UD:x0011] if position 0x16 == 0x23 no ending period (indefinite) elsif position 0x16 == (0x22 or 0x21) Y = positions 0x1B 0x1A # (i.e. if 0x1B = 0x03, and 0x1A = 0xE7, num = 0x03E7 = 999 occurrences) elsif position 0x16 == 0x3E # This is type 2 above if position 0x1A == 0x23 no ending period (indefinite) elsif position 0x1A == (0x22 or 0x21) Y = positions 0x1F 0x1E # (i.e. if 0x1F = 0x03, and 0x1E = 0xE7, num = 0x03E7 = 999 occurrences) } sub weekly_recurrence { # Every X week(s) on Y day # (Y is day of week, e.g. Monday) # There can be an indefinite period, or end after Z recurrences X = position 0x0E Y = position 0x16 (according to week_table above) if position 0x1A == 0x23 no ending period (indefinite) elsif position 0x1A == (0x22 or 0x21) Z = positions 0x1F 0x1E # (i.e. if 0x1F = 0x03, and 0x1E = 0xE7, num = 0x03E7 = 999 occurrences) } sub monthly_recurrence { # There are 2 types of monthly recurrences # 1 - Day X of every Y month(s) # 2 - The Xth Y of every Z month(s) # (where X is First,Second,Third,Fourth,Last and # Y is Dayname,Weekday,Weekend Day,Day (any)) # # Each can have either an indefinite period, or end after N # recurrences if position 0x06 == 0x02 # This is type 1 above X = position 0x16 Y = position 0x0E if position 0x1A == 0x23 no ending period (indefinite) elsif position 0x1A == (0x22 or 0x21) N = positions 0x1F 0x1E # (i.e. if 0x1F = 0x03, and 0x1E = 0xE7, num = 0x03E7 = 999 occurrences) elsif position 0x06 == 0x03 # This is type 2 above X = position 0x1A (0x01 = First ... 0x05 = Last) Y = position 0x16 (according to week_table above) # Y can also take the following special values not in week_table: # 0x7F = any day (i.e. 2nd day of month) # 0x3E = weekday (Mon-Fri) # 0x41 = weekend day (Sat, Sun) Z = position 0x0E if position 0x1E == 0x23 no ending period (indefinite) elsif position 0x1E == (0x22 or 0x21) N = positions 0x23 0x22 # (i.e. if 0x23 = 0x03, and 0x22 = 0xE7, num = 0x03E7 = 999 occurrences) } sub yearly_recurrence { # There are 2 types of yearly recurrences # 1 - Every X Y # (where X is month name, Y is day number) # 2 - The Xth Y of Z # (where X is First,Second,Third,Fourth,Last and Y # Y is Dayname,Weekday,Weekend Day,Day (any) and Z is month name) # # Each can have either an indefinite period, or end after N # recurrences if position 0x06 == 0x02 # This is type 1 above X = positions 0x0A 0x0B (according to month_table above) Y = position 0x16 if position 0x1A == 0x23 no ending period (indefinite) elsif position 0x1A == (0x22 or 0x21) N = positions 0x1F 0x1E # (i.e. if 0x1F = 0x03, and 0x1E = 0xE7, num = 0x03E7 = 999 occurrences) elsif position 0x06 == 0x03 # This is type 2 above X = position 0x1A (0x01 = First ... 0x05 = Last) Y = position 0x16 (according to week_table above) # Y can also take the following special values not in week_table: # 0x7F = any day (i.e. 2nd day of month) # 0x3E = weekday (Mon-Fri) # 0x41 = weekend day (Sat, Sun) Z = positions 0x0A 0x0B (according to month_table above) if position 0x1E == 0x23 no ending period (indefinite) elsif position 0x1E = (0x22 or 0x21) N = positions 0x23 0x22 # (i.e. if 0x23 = 0x03, and 0x22 = 0xE7, num = 0x03E7 = 999 occurrences) } Details ------- Daily Occurrences ----------------- Position 0x04 = 0x0A always Position 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 -------------------------------------------------------------------- Every 1 day 0x00 0x00 0x00 0x00 0xA0 0x05 0x00 Every 2 days 0x00 0x00 0x00 0x00 0x40 0x0B 0x00 Every 3 days 0xA0 0x05 0x00 0x00 0xE0 0x10 0x00 Every 4 days 0x00 0x00 0x00 0x00 0x80 0x16 0x00 Every 16 days 0x80 0x16 0x00 0x00 0x00 0x5A 0x00 Every 999 days 0x60 0x1E 0x09 0x00 0x60 0xF3 0x15 0x16 = (0x23 or 0x22) every X days 0x3E every weekday X = value for MAPI Code: [UD:x0011] Ending time logic: If position 0x16 == 0x23 No end (indefinite) elsif position 0x16 == 0x22 num of occurrences = 0x1B 0x1A (i.e. if 0x1B = 0x03, and 0x1A = 0xE7, num = 0x03E7 = 999 occurrences) elsif position 0x16 == 0x3E if position 0x1A == 0x23 No end (indefinite) elsif position 0x1A == 0x22 num of occurrences = 0x1F 0x1E (i.e. if 0x1F = 0x03, and 0x1E = 0xE7, num = 0x03E7 = 999 occurrences) Weekly Occurrences ------------------ Position 0x04 = 0x0B always These byte positions seem to designate how often recurrence occurs 99 = max week interval Position 0x0A 0x0B 0x0C 0x0E -------------------------------------------- Every 1 week 0xC0 0x21 0x00 0x01 Every 2 weeks 0x20 0x49 0x00 0x02 Every 3 weeks 0x20 0x49 0x00 0x03 Every 9 weeks 0x40 0xBF 0x00 0x09 Every 10 weeks 0x60 0x35 0x01 0x0A Every 99 weeks 0x20 0xAB 0x07 0x63 Every 1 week, these byte positions seem to indicate weekday Position 0x16 0x2E 0x2F ------------------------------------ Monday 0x02 0x40 0xD3 Tuesday 0x04 0xE0 0xD8 Wednesday 0x08 0x80 0xDE Thursday 0x10 0x20 0xE4 Friday 0x20 0xC0 0xE9 Saturday 0x40 0x60 0xEF Sunday 0x01 0x00 0xF5 Logic: Weekly Occurrence = Position 0x04 = 0x0B Every X weeks on weekday Y X = Position 0x0E Y = Position 0x16 0x02 = Monday 0x04 = Tuesday 0x08 = Wednesday 0x10 = Thursday 0x20 = Friday 0x40 = Saturday 0x01 = Sunday Ending time Position 0x1A 0x1E 0x1F 0x32 0x33 0x34 0x35 -------------------------------------------------------------------- no end 0x23 0x0A 0x00 0xDF 0x80 0xE9 0x5A 1 occurrence 0x22 0x01 0x00 0xE0 0xD8 0xA3 0x0C 2 occurrences 0x22 0x02 0x00 0x40 0x00 0xA4 0x0C 9 occurrences 0x22 0x09 0x00 0xE0 0x13 0xA5 0x0C 10 occurrences 0x22 0x0A 0x00 0x40 0x3B 0xA5 0x0C 11 occurrences 0x22 0x0B 0x00 0xA0 0x62 0xA5 0x0C 231 occurrences 0x22 0xE7 0x00 0x20 0x39 0xC7 0x0C 232 occurrences 0x22 0xE8 0x00 0x80 0x60 0xC7 0x0C 998 occurrences 0x22 0xE6 0x03 0xC0 0x31 0x3D 0x0D 999 occurrences 0x22 0xE7 0x03 0x20 0x59 0x3D 0x0D Ending time logic: If position 0x1A == 0x23 No end (indefinite) elsif position 0x1A == 0x22 num of occurrences = 0x1F 0x1E (i.e. if 0x1F = 0x03, and 0x1E = 0xE7, num = 0x03E7 = 999 occurrences) Ending date goes by same logic as above. Number of occurrences is calculated by Outlook, and there is no end date value stored. Monthly Recurrences ------------------- Position 0x04 = 0x0C always Position 0x04 0x0E 0x16 0x2E 0x2F ------------------------------------------------------------ 6th, every 1 month 0x0C 0x01 0x06 0x00 0x4F 16th, every 1 month 0x0C 0x01 0x10 0xE0 0xD8 16th, every 2 month 0x0C 0x02 0x10 0xE0 0xD8 17th, every 1 month 0x0C 0x01 0x11 0x80 0xDE 28th, every 1 month 0x0C 0x01 0x1C 0x60 0x1C 31st, every 1 month 0x0C 0x01 0x1F 0x40 0x2D 0x06 = 0x02 0x16 = day of month 0x0E = every X month Ending time logic: If position 0x1A == 0x23 No end (indefinite) elsif position 0x1A == 0x22 num of occurrences = 0x1F 0x1E (i.e. if 0x1F = 0x03, and 0x1E = 0xE7, num = 0x03E7 = 999 occurrences) Position 0x04 0x06 0x0E 0x16 0x1A -------------------------------------------------------------------- Every 1 month, 3rd Tuesday 0x0C 0x03 0x01 0x04 0x03 Every 1 month, 4th Tuesday 0x0C 0x03 0x01 0x04 0x04 Every 1 month, last Tuesday 0x0C 0x03 0x01 0x04 0x05 Every 99 months, last Tuesday 0x0C 0x03 0x63 0x04 0x05 Every 2 months, 2nd Wednesday 0x0C 0x03 0x02 0x08 0x02 Every 2 months, 2nd day 0x0C 0x03 0x02 0x7F 0x02 Every 2 months, 2nd weekday 0x0C 0x03 0x02 0x3E 0x02 Every 2 months, 2nd weekendday 0x0C 0x03 0x02 0x41 0x02 0x06 = 0x03 when using Every X month, Yth Z day of week 0x16 = Z day of week (as above) or 0x7F = any day (i.e. 2nd day of month) 0x3E = weekday (Mon-Fri) 0x41 = weekend day (Sat, Sun) 0x1A = Yth day (0x01 = First ... 0x05 = Last) 0x0E = every X month Ending time logic: If position 0x1E == 0x23 No end (indefinite) elsif position 0x1E == 0x22 num of occurrences = 0x23 0x22 (i.e. if 0x23 = 0x03, and 0x22 = 0xE7, num = 0x03E7 = 999 occurrences) Yearly Occurrences ------------------ Position 0x04 = 0x0D always Position 0x04 0x0C 0x16 0x30 ---------------------------------------------------- Every 1 year, 03-16 0x0D 0x01 0x10 0xA3 Every 1 year, 04-16 0x0D 0x01 0x10 0xA4 Every 1 year, 05-16 0x0D 0x01 0x10 0xA5 0x06 = 0x02 0x0A 0x0B = month 0x16 = day number Ending time logic: If position 0x1A == 0x23 No end (indefinite) elsif position 0x1A == 0x22 num of occurrences = 0x1F 0x1E (i.e. if 0x1F = 0x03, and 0x1E = 0xE7, num = 0x03E7 = 999 occurrences) Position 0x04 0x1A 0x16 0x0A 0x0B 0x32 0x33 0x34 ------------------------------------------------------------------------------------ 1st Tuesday of January 0x0D 0x01 0x04 0x00 0x00 0x20 0x4F 0xA2 1st Tuesday of February 0x0D 0x01 0x04 0x60 0xAE 0x20 0xEC 0xAA 2nd Tuesday of March 0x0D 0x02 0x04 0xE0 0x4B 0x80 0xB1 0xA3 3rd Tuesday of March 0x0D 0x03 0x04 0xE0 0x4B 0x60 0xD8 0xAB 3rd Tuesday of April 0x0D 0x03 0x04 0x40 0xFA 0xC0 0x9D 0xA4 3rd Tuesday of May 0x0D 0x03 0x04 0x00 0xA3 0x40 0x3B 0xA5 2nd Tuesday of May 0x0D 0x02 0x04 0x00 0xA3 0x60 0x13 0xAD 1st Tuesday of June 0x0D 0x01 0x04 0x60 0x51 0x00 0x8A 0xA5 1st Tuesday of July 0x0D 0x01 0x04 0x20 0xFA 0xE0 0x4E 0xA6 1st Tuesday of August 0x0D 0x01 0x04 0x80 0xA8 0x60 0xEC 0xA6 1st Tuesday of Septemb 0x0D 0x01 0x04 0xE0 0x56 0x40 0xB1 0xA7 1st Tuesday of October 0x0D 0x01 0x04 0xA0 0xFF 0xC0 0x4E 0xA8 1st Tuesday of Novemb 0x0D 0x01 0x04 0x00 0xAE 0x40 0xEC 0xA8 1st Tuesday of Decemb 0x0D 0x01 0x04 0xC0 0x56 0x20 0xB1 0xA9 0x06 = 0x03 when using Every Xth Y day of Z month 0x1A = X 0x16 = Y day of week (as above) or 0x7F = any day (i.e. 2nd day of month) 0x3E = weekday (Mon-Fri) 0x41 = weekend day (Sat, Sun) 0x0A 0x0B = Z month 0x0000 = January 0x60AE = February 0xE04B = March 0x40FA = April 0x00A3 = May 0x6051 = June 0x20FA = July 0x80A8 = August 0xE056 = September 0xA0FF = October 0x00AE = November 0xC056 = December Ending time logic: If position 0x1E == 0x23 No end (indefinite) elsif position 0x1E == 0x22 num of occurrences = 0x23 0x22 (i.e. if 0x23 = 0x03, and 0x22 = 0xE7, num = 0x03E7 = 999 occurrences) Notes ----- Outlook only sends cancellation when deleting recurrence, not specific entry