Category Archives: Ical RFC5545 / 2445

Notes on working with the icalendar spec:
(RFC2445 spec is obsolete)
More readable format here using old spec:

GDPR Compliance for event plugins

This statement is for the wordpress plugins amr-events, amr-ical-events-list  and amr events attendees at

Briefly: the amr-events plugin creates events as wordpress custom posts. No additional user data is created or stored. The post author (display name and email) is assumed to be the event organiser for purposes of complying with the ics feed RFC5545 standard. The plugins do not send or store data on any other servers.

Collecting & storing of user data:

The amr-events plugin creates events as wordpress posts.  As per standard wp processing the author of the post is recorded.  That is the extent of any collecting any personal user data that is within the plugins control – only as per standard wordpress user functioning.   The plugin does not of itself collect and store user data.  Control of that user data rests with the website owner.

Processing or use of user data (email and display name):

In event feeds (ics feed) as per the RFC5545 standard the event organizer must be included in the RFC 5545 ics file.  Refer   – see Organizer

This property MUST be specified in an iCalendar object
      that specifies a group-scheduled calendar entity.  This property
      MUST be specified in an iCalendar object that specifies the
      publication of a calendar user's busy time.

To conform to this, the event post author’s data is then included in the ics file as per the example in the specification :


The plugin uses the wordpress post authors “display name” if it exists, if not then the wordpress users “userlogin”, and then the wordpress users ‘user_email’ to provide the required ORGANIZER details.  The plugin does not have any means to validate this data and simply uses what has been stored the user records by the website.

A web developer can choose to display (or not) the public ics url.  The web developer can also control whether a real user or a dummy user is recorded as the post author.

The plugins can also list events from external public ics files.  These ics files may contain attendee data.  The ics files are cached and refreshed daily or as requested.  The cache purpose is to continue to be able to list events should there be a disruption in access to source url.   If the web designer chooses to use the addon  then the web designer can choose to display that attendee data in the event list.  That list may be displayed in a  public or private page as setup by the web designer.  There is currently no provision to add attendee data to the custom events created inside wordpress.  If this becomes available, a link to the user data such as the user id or email address is what would be stored.

GDPR Summary

The plugins use a minimal amount of user data required to provide event functionality in adherence with the ‘purpose’ and ‘data minimisation’ principles.  With respect to the other GDPR principles, the plugins do not control the accuracy, storage, or security of this user data.   The plugin does not pass user data on to any other parties except as required by the RFC5545 ics specification and as configured by the website developer.


Modifications to events, especially to an instance of a recurring event, or an update to a modified instance can all seem quite complex.  It’s not that bad once you understand the various bits that you need to provide for the receiving application to make sense of it. See the RFC5545 spec for details.  This version or or the kanzaki version.

  • UID – must have and must be unique
  • SEQUENCE – numerically update to indicate which is the latest version
  • RECURRENCE-ID – if modifying a single instance with in a recurring stream.  Note that for a UID and SEQUENCE pair, the “RECURRENCE-ID” value for a recurrence instance is fixed. The event date may change but the “RECURRENCE-ID” does not. It must always be the original date as generated by the RRULE.
  • LAST-MODIFIED – Probably a good idea top update this too

Note also:

  • if a user subscribes to an ICS URL, then the receiving application will check for updates on a regular basis at a frequency determined by it.  It will be seen as a separate calendar.  It will use the SEQUENCE numbers to determine the latest event details. There may be a delay in an update being made on the originating system and it being reflected in the receiving system.   The only reliable way to be sure that users will have updates seen in their calendars is if you can get them to subscribe to the url (or ‘import’ the url, not the file)
  • if an ics file is imported (eg: when event details are sent as an ics file attachment, not as a url, or if the user downloads the ics file from a url and then imports it), then it will be added as events into the calendar chosen by the user.  Updates may overwrite IF the user re-imports the events AND the application is clever enough to match up the UID’s (and RECURRENCE-IDs if it’s part of a recurring set).  It should then also use the SEQUENCE to determine if the details are actually the latest.  There is no way on devices to force a user to load an updated ics file sent to them.


Modifications to recurring rules or rdates and modifications to instances of those recurring rules (themselves already a modification.)

Assume we have a recurring event.  It starts with a SEQUENCE: 0


This generates an infinite set of mondays, including the following

  • 19th May
  • 16th June
  • 21 July
  • 18 August
  • etc

Now, one of the instances gets modified.  (This could be just the description or the actual date.)  A RECURRENCE-ID VEVENT is created for each instance modification and the SEQUENCE NO is updated.   The recurrence-id matches the date in the recurring rule that it applies to. The combination of UID, RECURRENCE-ID and SEQUENCE helps us identify the instance that is being updated.

For a given pair of "UID" and "SEQUENCE" property values,
   the "RECURRENCE-ID" value for a recurrence instance is fixed.
DTSTART;VALUE=DATE:20140721  (ie no date change in this example)

Now assume the original RRULE is modified too, perhaps just the description or shock horror, the recurring date definition?  It’s sequence-no is updated too BUT now what should happen to the RECURRENCE-ID instance?  Should it be updated to indicate it is still valid?  IE we now have:

  • generated date 21 July 2014 with UID and SEQUENCE = 3 and
  • RECURRENCE-ID;VALUE=DATE:20140721 with matching UID and SEQUENCE = 3

It appears that perhaps SEQUENCE numbers can increment separately, so one could conceivably receive a file with a RRULE with an equal to or  greater sequence number than a RECURRENCE-ID.       From   this discussion, it is really not clear what the supplying calendar application will do:

Once UID 1/SEQUENCE 0 hits UID 1/SEQUENCE 1 (which would
mean something significant about the set of instances
has changed) all bets are off in regards to RECURRENCE-ID
values that previously existed.

If the UID/RECURRENCE-ID/SEQUENCE matches a generated date from the rrule with same SEQUENCE (ie both have been modified), then what?  One cannot just use eg: LAST-MODIFIED:20140620T200327Z.  Who is to say that a mod of the RRULE was intended to overwrite the RECURRENCE instance?   Quite possibly not.

Some lengthy related discussions here and in other parts of the thread:

Complications that urge one to keep events as simple as possible:

Searching the web seems to indicate some folks believe RECURRENCE-IDS should not change.  So should we assume that if the RECURRENCE-ID vevent is still in the file then it is still valid and should be included.  (What does this mean for syncing and deletions?  IE How does one ‘delete’ an existing event.  Or should one always delete events from an ics file and reload ONLY what’s in the ics file?)

Dates, Times, Formatting

There are a number of date and time options for you to choose when displaying your events.    The main ones you should be using are created by the plugin and will be formatted by the date and time settings you have specified in the plugin settings (and applying any localisation that may be available in your wordpress setup).  You can specify these by listtype, so say a widget could have a very compact date format and a full list may be more detailed.

screnshot Date Time Formats
Date Time Format settings by listtype

Event date fields formatted by your date settings:

  • EventDate: Mon, June 23, 2014
  • EndDate: Mon, June 30, 2014 (only if event greater than one day)

Event time fields formatted by your time settings:

  • StartTime: 9:00 am
  • EndTime: 10:00 am

Note there may be situations where there is no end time or no end date (eg: if there is no duration or the end date is the same as the start date.   If a field has not been populated, it will not be displayed and neither will any ‘before’ or ‘after’ text.

Field from the ics specification that may be useful.

Formatted using human language function

  • DURATION:1 week , 1 hour

Other date fields in the ‘edit events’ admin screen

screenshot of show screen options in edit events
show screen options in edit events

  • Last 20140630

The ‘last’ date shown in the edit events admin screen shows the last recurrence date of an event.  It is used to select events within a date range (ie exclude events whose recurrences are in the past, without having to rebuild the recurrence logic).  It is also used to sort events in the admin screen by this last recurrence.   It is therefore formatted yyyymmdd for the sorting.   It is not intended to be displayed elsewhere.

Technical fields

These are direct from the ics specification formatted by the DateTime settings  in the plugin settings.   Note the DTEND has a special definition in the ics specification for all day events (it will have the next day as the end date) and may be confusing to normal users.   Some ics generators get the DTEND logic wrong, so this plugin tries to work with duration just in case.

  • DTEND: Mon, June 30, 2014 10:00 am
  • DTSTART: Mon, June 23, 2014 9:00 am

Other fields

As these are very technical, precise fields, they are by default not formatted but left as found.

  • DTSTAMP: 20140616T021842Z
    • the date and time that the instance of the iCalendar object was created.
  • LAST-MODIFIED:20140616T025756Z
    • the date and time last modified – works with the sequence number to determine the latest modification to an event instance.

Html in descriptions in ics feed generation

What to do about html in event descriptions?

Some applications will cope with the html, but there are other applications which do not. EG: Google calendar – does not faciliate html nor  issue it in feed.

HTML in the description field is not explicitly forbidden, however it is probably not recommended.  There is some provision for html to be explicitly allowed for, either:

  •  in the description using an ALTREP parameter,
  • or in an ‘experiemental’  X field, X-ALT-DESC,

WordPress allows us to create events with html in them.  So what to do when the ics feed is generated?

Retaining the html – two possibilties:

Link to the html representation:

DESCRIPTION;ALTREP="":This is an example description.

Provide separate field with html representation:

Outlook will recognise:

X-ALT-DESC;FMTTYPE=text/html:<p>This is an example description.</p>


This update does both, as well of course ,as stripping the html from the description field in the ics file.  This means images will be stripped too (only for the feed – do not panic!)

More information for the technically minded



Problem with Dates/Time – Off by 1 Hour?

If you are using amr-events or amr-ical-events-list you will not have this problem!

Every time a zone somewhere in the world kicks on to daylight saving or off for that matter, I see a bunch of support questions popping up about their event times being off by an hour.    (I monitor wordpress support, stackexchange and wpquestions, and maybe a few more…..)

From a favourite cartoon source - thanks

Imagine the confusion this can cause where clients may have subscribed to calendar feeds and have the wrong times.

PHP datetime objects and functions

If people are very lucky, the plugin that they are using has some good coding and is using php DateTime objects with timezone support, and the only problem is that their wordpress timezone is set as a GMT offset, not as a timezone.

That is easily fixed! (goto wordpress general settings)

However all too often the plugin developer has failed to appreciate

  • the complexities of times around the world,
  • timezones,
  • daylight saving and
  • most importance of managing recurring events in one timezone for a display in another where one zone changes daylight saving.  Very easy to generate the wrong times for a recurring event without realising it!
  • even worse governments sometimes change the date/time of the switchover (ok not that often, but it does happen, and then you hope your php installation gets updated with the timezone definitions)


If it is not a simple wordpress timezone setting, then these things are NOT easy to fix and will involve changes to code:

  1. Change to use php DateTime Classes for all date logic .If they are using unix time and not  php datetime objects, it is almost impossible to get it right.  It’s a fairly major rewrite to change all date logic to use the DateTime objects and functions.
  2. If already using, it maybe that the intricacies of recurring event logic have won out.  See below for logic help.

Developers and event website managers should read:



Need to know the possible combinations for repeating dates? – an Ical cheatsheet

The ical specification allows one to define some very interesting and complicated date recurrences.  This table (adapted from was very useful when I decided to rewrite the recurrence engine part of my plugins.

Sorry about the table width – got to get that theme css fixed!

Yearly Monthly Weekly Daily Hourly Minutely Secondly
BY MONTH (1 to 31,  -1 to -31) Expand Limit Limit Limit Limit Limit Limit
BY WEEK NO (1 to 53, -1 to 53) Expand invalid invalid invalid invalid invalid invalid
BY YEAR DAY (1  to 366, -1 to -366) Expand invalid invalid invalid Limit Limit Limit
BY MONTH DAY (1 to 31, -1 to -31) Expand Expand invalid Limit Limit Limit Limit
BY DAY (MO, TU , WE, TH, FR, SA, SU) Note 2 Note 1 Expand Limit Limit Limit Limit
BY HOUR (-23 to 0 to +23) Expand Expand Expand Expand Limit Limit Limit
BY MINUTE (-59 to 0 to 59) Expand Expand Expand Expand Expand Limit Limit
BY SECOND (-60 to 0 to 60) Expand Expand Expand Expand Expand Expand Limit
BY SET POS (-366 to -1,1 to 366) Limit Limit Limit Limit Limit Limit Limit

The “By”‘s are applied in the order indicated. Limit means that the possible repeat dates are limited by the “BY” specification.  Expand means that the possible repeat dates are expanded by the BY values.  The start date will fill in any missing year, month, day, hour, minute or second values.  See the RFC 5545 Specification for examples.

Note 1:

  • Limit the dates if BYMONTHDAY is present;
  • else special expand for monthly


  • Limit if BYYEARDAY or BYMONTHDAY is present; otherwise,
  • special expand for WEEKLY if BYWEEKNO present; otherwise,
  • special expand for MONTHLY if BYMONTH present; otherwise,
  • special expand for YEARLY

What every developer ought to know about timezones wrt calendar files

A timezone definition consists of

  • a ID
  • a name
  • a standard time definition with a gmt offset
  • daylight saving time definitions with a series of daylight saving transitions (as rules have changed over time

Ideally every system around the world should be using the same definition of timezones.  However not all systems are kept up to date when a government decides to change a transition time.  In addition not all systems use the same naming conventions, so while to the human it may be obvious which timezone is being referred to, a program has to do some deductions.

Most calendar applications appear to use the olson database or similar.  Windows PC take a slightly different approach, with a requested time change on the first reboot after daylight saving change.  Windows based application issue different timezone ID’s.

A calendar application can decide on it’s own timezone id’s. They have to include the definition (The VTIMEZONE) with the daylight saving changes in the file, however this can be their own version of the timezone definition

What if the issuing application has an outdated version of the daylight saving changes?  Would you not rather control it on your server than taking their definition?

Global Timezone Database

Php, WordPress, Google, Linux (Ubuntu), Apple

These all appear to use the timezone database aka Olson Database.  It has timezone identifiers like:


A few months ago, Issued no TZID, no VTIMEZONE, all dates local / floating and just this : X-WR-TIMEZONE;VALUE=TEXT:Europe/Oslo

Mozilla sometimes has great fun confusing people:


Recently I dealt with an ics file that had no TZID, no VTIMEZONE, all dates local / floating

Microsoft Windows PC, Microsoft Exchange

Setting TimeZone in Windows Vista

Microsoft exchange, Windows PC’s and by extension any application that runs on the PC that uses the windows timezones does the gmt offset thing

(GMT+10:00) Canberra, Melbourne, Sydney.

Now Sydney has daylight saving, so we are only GMT+10 for half the year.  The rest of the time we are GMT+11.  If we happen to choose the GMT+11 option for our setup thinking it was more correct we would be wrong…..

What windows does is technically not wrong.  They acknowledge the daylight saving and you can choose to have it automatically update… WHEN you REBOOT the PC, the times will update.

It is however potentially misleading, unnecessarily so.  Particularly around the actual daylight saving change, errors may occur, due

  • an ‘old’ ics file perhaps – the one issued before the times were updated ?, or
  • to applications not always handling the timezone  correctly – It would be very tempting as a programmer to grab that GMT+10 and use that.  Just google things like my meeting is one hour out etc to get a feeling for the problem.

What does this mean for developers using calendar files?

Well it depends a bit on the application issuing the ics file.  You could have to deal with any of these timezone values:


  • TZID:America/New_York
  • DTSTART;TZID=”America/New_York”:20080807T090000
  • X-WR-TIMEZONE:Europe/London
  • TZID:Europe/London
  • DTSTART;TZID=Europe/London:20060707T130000
  • TZID:Canberra\, Melbourne\, Sydney
  • DTSTART;TZID=”Canberra, Melbourne, Sydney”:20100831T210000
  • DTSTART;TZID=”(GMT+01.00) Amsterdam / Berlin / Bern / Rome / Stockholm / Vienna”:20100831T16000
  • TZID:(GMT+02.00) Harare/Pretoria
  • DTSTART;TZID=US/Central:20080726T190000
  • DTSTART;TZID=”(GMT) Greenwich Mean Time – Dublin / Edinburgh / Lisbon /
  • TZID:/

Windows – assessed using Windows Calendar

Windows Calendar Ics file

Windows calendar defines the TZID with a VTIMEZONE definition

TZID:Canberra\, Melbourne\, Sydney
TZNAME:AUS Eastern Standard Time...

and then uses it in the ics file

DTSTART;TZID="Canberra, Melbourne, Sydney":20100831T210000

This is correct according to the spec and not too hard to deal with.    The developer can grab each city and check for a matching timezone on their host system.

A minor gripe is that if you import this into Google and then share the resulting google calendar file, Google will decide to go with Melbourne, even if the rest of your calendars are Sydney.  This may offend some. ;-)


I’m told that Zimbra issues ics files with :

DTSTART;TZID="(GMT+01.00) Amsterdam / Berlin / Bern / Rome / Stockholm / Vienna":20100831T160000

I don’t know whether a VTIMEZONE was included or not.  AS noted before grabbing that GMT+01 may cause incorrect times when daylight saving is involved.

At the very least the reading application  has to deal with that somehow. Possibly by tossing the GMT parts away and looking for the cities again.  My events plugin will do this in the next upgrade

Mozilla / Thunderbird

Mozilla plays nicely (with php anyway!)

PRODID:-// Mozilla Calendar V1.1//EN

Reading the VTIMEZONE definition?

Somehow working with the timezone definition passed in the ics file – Is this an option ? – well maybe – I shudder to think how though. Imagine the confusion if some dates in your website knew about one set of daylight saving and others were obeying the possibly different definition in the ics file. PHP encourages us to use it’s timezone definitions. It has functions to do a variety of timezone functions, but uploading daylight saving changes into a timezone object is not one of them. (Probably a good idea too).

Parsing Timezone Ids

If you are developing an ical parser, I believe that the best approach (wrt correctness and usability) is

  1. attempt to determine the desired timezone from the TZ id (toss those GMT’s if you have too)
  2. match to a timezone identifier that is already in your system, and then use those consistent daylight saving changes
  3. and of course use the DateTime object class – do not mess around with unix time that breaks on old dates.
    Dates, Times, Timezones, daylight saving etc are so fraught with danger (see the best of dates, the worst of dates), that one must use pre-tested logic as much as possible, and there are some very useful functions there.

My amr-ical-events-list plugin

For the record, my plugin will attempt to cope with all of these variations (and more if anyone tells me about them).   If we can extract some city names, it should be easy to match it at least one to the php timezones:

  • explode the names out, stripping off all the quotes, slashes etc
  • If a timezone has been specified in the shortcode, and it matches the city name, then it will deduce that is the timezone
  • If the wordpress timezone  matches the city name, then it will deduce that that is the timezone
  • Else if will attempt to find a match in the php timezone names list (which it should unless something really weird is going on)
  • Else if all that fails, it will just use the wordpress timezone as the base timezone for the events.

Extract From

This property parameter specifies a text value that uniquely identifies the “VTIMEZONE” calendar component to be used when evaluating the time portion of the property. The value of the “TZID” property parameter will be equal to the value of the “TZID” property for the matching time zone definition. An individual “VTIMEZONE” calendar component MUST be specified for each unique “TZID” parameter value specified in the iCalendar object.

Failure to include and follow VTIMEZONE definitions in iCalendar objects may lead to inconsistent understanding of the local time at any given location

The presence of the SOLIDUS character “/” as a prefix, indicates that this “TZID” represents a unique ID in a globally defined time zone registry (when such registry is defined).

Note: This document does not define a naming convention for time zone identifiers. Implementers may want to use the naming conventions defined in existing time zone specifications such as the public-domain TZ database [TZDB]. The specification of globally unique time zone identifiers is not addressed by this document and is left for future study.

Do you need BYYEARDAY for your events?

Is BYYEARDAY useful enough ?

ByYearDay allows the user to enter days of the year to repeat separated by commas (1,2,…366,-366,-365…-1). Almost every real example can be represented in a more user friendly fashion using other ‘BY’s such as BYMONTH and BYMONTHDAY


Only leap years affect whether the 72nd day of the year is 31+28+13 = March 13 or 31+29+12 = March 12. It’s just not useful enough to schedule a meeting on “March 13, except March 12 if it’s a leap year” and that kind of use case can be worked around. (One special case might be to state that a RRULE that occured yearly on Feb 29 might automatically recur on Feb 28 if not a leap year). Without BYYEARDAY we’d see rules like “RRULE:FREQ=YEARLY; INTERVAL=1” and the date would be March 12 every year.

For this reason, at launch, the amr events plugin does not offer a BYYEARDAY entry option on the edit event screen. It will however read BYYEARDAY’s entered in ics files and apply the necessary recurrence rule and included in any calendar listing.

Does your group need BYYEARDAY ?

If your website needs to be able to offer entry of recurring dates using BYYEARDAY for it’s members, it will be easy to add.  It is beingexcluded to avoid cluttering the screen unnecessarily.

The last week of the year is….

According to wikipedia,the last week of the ISO week-numbering year is the week before week 01; in accordance with the symmetry of the definition, equivalent definitions are:

* the week with the year’s last Thursday in it
* the week ending with the Sunday which is nearest in time to 31 December
* the week with December 28 in it
* the last week with the majority (four or more) of its days in the ending year
* the week starting with the Monday in the period 22 – 28 December
* the week with the Thursday in the period 25 – 31 December
* the week ending with the Sunday in the period 28 December – 3 January
* If 31 December is on a Monday, Tuesday, or Wednesday, it is in week 01 of the next year, otherwise in week 52 or 53.

So this plugin when calculating the weekno and if there is a WKST specification in the rule, uses “the week with December 28 in it” to calculate the last week and handle negative BYWEEKNO’s that way.

The logic is something like this

  • get the end of the year (ie 28th Dec)
  • determine the weekno (will be 52 or 53?)
  • go to the start of that week, using wkst
  • “save” the this and next 6 dates as our week

What do you think is the “first week” of the year ?

Week numbers and BYWEEKNO and weeks start with Monday, Sunday, Saturday (WKST)

How the week number is entered and sent in an ics file is important in two areas of this events plugin.

  1. For communication with other calendar systems, one must stick to the ical RFC5545 (ie : ISO 8601) definition so that recurring dates will be accurately reflected.
  2. For listing of events (agenda or calendar style) however there may be expectations of other week numberings (For example many timeshare resorts use very different week numbering systems, depending on when “their” weeks start – eg: Friday, Saturday, Sunday.)  It is simply not possible to cope with all of these, at this stage .  The RFC5545 spec (see below) implies that one can combine BYWEEKNO and WKST to give some flexibility.  The amr events plugin will pick up the week start defined in your wordpress website.

Entering the week number
Entering the week number for a recurring date in wordpress event plugin

What does the plugin do wrt week numbers ?

When entering a week number, the ISO8601 in combination with the weekstart (WKST ) will be expected.  To aid data entry, it will be checked against the start date (which must be in the week number) and the error message will tell you the wek number of the start date.

At launch, the listing plugin is limited to using the PHP functions for calculating the week number.

Week number definitions:

Wikipedia has some discussion on various usages or week number definitions under the 7 day week, week numbering heading.   There are many – it is not just a case of

  • which day the week starts on (Monday, Sunday, Saturday, Wednesday (Hungary?)), but also
  • what defines where one begins in the year with partial weeks or full weeks
    • Week containing Jan 1 (Eastern European, India, Arabic countries, Canada, China etc..)
    • Week containing Jan 4 (European countries)
    • Week containing Jan 7 & Monday  (Eastonia and Pakistan)

A list of these is available at and more information from JR Stockton

Technical Definitions of BYWEEKNO

From the RFC5545 Specification:

The BYWEEKNO rule part specifies a COMMA-separated list of ordinals specifying weeks of the year. Valid values are 1 to 53 or -53 to -1. This corresponds to weeks according to week numbering as defined in [ISO.8601.2004]. A week is defined as a seven day period, starting on the day of the week defined to be the week start (see WKST). Week number one of the calendar year is the first week that contains at least four (4) days in that calendar year. This rule part MUST NOT be used when the FREQ rule part is set to anything other than YEARLY. For example, 3 represents the third week of the year.
Note: Assuming a Monday week start, week 53 can only occur when Thursday is January 1 or if it is a leap year and Wednesday is January 1.

This note from advises: Use BYWEEKNO only when conformance with ISO 8601 is required. Week numbers as defined by ISO 8601 are very different from week numbers in “common” sense.    According to ISO 8601, week number one of the calendar year is the first week of a calendar year that contains at least four days. This rule makes the algorithm specific to applications requiring conformance to ISO 8601 and make it almost inapplicable to other “normal” uses.

ISO 8601 is supported by some European banking and financial applications. It is also used in Television for booking commercials. An ISO week calculator can be found at

The BYWEEKNO rule specifies a comma-delimited list of numbers identifying weeks of the year. Valid values are 1 to 53 and 1 to 53. This corresponds to weeks according to week numbering as defined in ISO 8601. BYWEEKNO is only valid for YEARLY rules.

To illustrate, the following are two very different recurrence patterns:

  • Friday of 1st ISO 8601 week of the year: FREQ=YEARLY;BYWEEKNO=1;BYDAY=FR
  • 1st Friday of the year : FREQ=YEARLY;BYDAY=1FR

In 1999, for example, 1st Friday of the year is 1999/01/01, while Friday of the 1st ISO 8601 week is 1999/01/08.

So what is the current week number?

These sites help if your week starts on a Monday: