xo::ical::VCALITEM method parse RRULE (public)

 <instance of xo::ical::VCALITEM[i]> parse RRULE recurrule

Defined in packages/xotcl-core/tcl/ical-procs.tcl

parse recurrence rule provided in cal syntax. This method assumes that the instance variable dtstart is already set, before this method is called.

Parameters:
recurrule (required)

Testcases:
No testcase defined.
Source code:
set r_freq ""
set every_n 1
set r_error 0
set r_until ""
set days_of_week ""
set r_count 0
foreach rval [split $recurrule ";"] {
  if { [regexp {^FREQ\=+(.*)$} $rval _ freqval] } {
    switch $freqval {
      DAILY   { set r_freq "day" }
      WEEKLY  { set r_freq "week" }
      MONTHLY { set r_freq "month_by_day"}
      YEARLY  { set r_freq "year"}
      default { set r_error 1 }
    }
  } elseif { [regexp {^COUNT=(.*)$} $rval _ countval] } {
    set r_count $countval
  } elseif { [regexp {^UNTIL=([0-9]+)(T([0-9]+)Z?)?$} $rval _ untildate untiltime] } {
    if {$untiltime eq ""} {
      set untiltime 000000
    }
    append r_until  "[string range $untildate 0 3]-[string range $untildate 4 5]-[string range $untildate 6 7]"  " "  "[string range $untiltime 0 1]:[string range $untiltime 2 3]"
  } elseif { [regexp {^INTERVAL\=+(.*)$} $rval _ intval] } {
    set every_n $intval
  } elseif { [regexp {^BYDAY\=+(.*)$} $rval _ bydayval] } {
    #
    # Build days_of_week list
    #
    foreach dayval [split $bydayval ","] {
      switch $dayval {
        SU { lappend days_of_week "0" }
        MO { lappend days_of_week "1" }
        TU { lappend days_of_week "2" }
        WE { lappend days_of_week "3" }
        TH { lappend days_of_week "4" }
        FR { lappend days_of_week "5" }
        SA { lappend days_of_week "6" }
      }
    }
  } elseif { [regexp {^BYMONTHDAY\=+(.*)$} $rval _ bymonthdayval] } {
    set r_freq "month_by_date"
  } else {
    # other rules don't work with OpenACS recurrence model
    :debug "ignore recurrence rule <$rval> of <$recurrule>"
  }
  #check we can make this rule, else ignore
}

#
# We should have now 'r_freq' computed.  If 'r_until' is not
# provided, calculate it based on 'r_count' (COUNT is not
# directly supported by OpenACS).  If both UNTIL and COUNT are
# not set, it is an unlimited event and skipped.
#
if { $r_until eq "" && $r_freq ne "" && $r_count > 0 } {
  # current date + r_count * r_freq * every_n (/ num_days)
  # set num seconds per frequency
  switch $r_freq {
    day           { set r_freq_amount 86400 }
    week          { set r_freq_amount 604800 }
    month_by_day  { set r_freq_amount 2419200 }
    month_by_date { set r_freq_amount 2678400 }
    year          { set r_freq_amount 31449600 }
  }
  # start date is count=1, so adjust count
  set r_count [expr {$r_count - 1}]
  set r_extra [expr {$r_count * $r_freq_amount * $every_n}]
  if { $r_freq eq "week" && [llength $days_of_week] > 0} {
    set r_extra [expr {$r_extra / [llength $days_of_week]}]
  }
  set r_until [::xo::ical clock_to_oacstime [expr {[clock scan ${:dtstart}] + $r_extra}]]
}

#
# If we have no errors, and 'r_freq' is computed, then keep the
# computed values in form of a parameter list for
# calendar::item::add_recurrence
#
if { !$r_error && $r_freq ne ""} {
  set :recurrence_options [list -interval_type $r_freq -every_n $every_n]
  if {$days_of_week ne ""} {
    lappend :recurrence_options -days_of_week $days_of_week
  }
  if {$r_until ne ""} {
    lappend :recurrence_options -recur_until $r_until
  }
}
XQL Not present:
Generic, PostgreSQL, Oracle
[ hide source ] | [ make this the default ]
Show another procedure: