晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。 林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。 见渔人,乃大惊,问所从来。具答之。便要还家,设酒杀鸡作食。村中闻有此人,咸来问讯。自云先世避秦时乱,率妻子邑人来此绝境,不复出焉,遂与外人间隔。问今是何世,乃不知有汉,无论魏晋。此人一一为具言所闻,皆叹惋。余人各复延至其家,皆出酒食。停数日,辞去。此中人语云:“不足为外人道也。”(间隔 一作:隔绝) 既出,得其船,便扶向路,处处志之。及郡下,诣太守,说如此。太守即遣人随其往,寻向所志,遂迷,不复得路。 南阳刘子骥,高尚士也,闻之,欣然规往。未果,寻病终。后遂无问津者。
|
Server : Apache System : Linux srv.rainic.com 4.18.0-553.47.1.el8_10.x86_64 #1 SMP Wed Apr 2 05:45:37 EDT 2025 x86_64 User : rainic ( 1014) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/akaindir/www/crm/modules/Mobile/third-party/qCal/qCal/DateTime/ |
Upload File : |
<?php
/**
* This is a class that is used within qCal_Value_Recur to internally store a recur property
* @todo The RFC says that invalid byXXX rule parts should simply be ignored. So I'm not sure if
* I should be hurling exceptions at the poor user all over the place like I am in here.
*/
abstract class qCal_DateTime_Recur {
/**
* @var array An array of week days. Used throughout this class to validate input.
*/
protected $weekdays = array(
'MO' => 'Monday',
'TU' => 'Tuesday',
'WE' => 'Wednesday',
'TH' => 'Thursday',
'FR' => 'Friday',
'SA' => 'Saturday',
'SU' => 'Sunday',
);
/**
* @var qCal_Date The start date/time of the recurrence
*/
protected $dtstart;
/**
* @var string frequency of the recurrence
*/
protected $freq;
/**
* @var qCal_Date The date/time which the recurrence ends
*/
protected $until;
/**
* @var integer The amount of recurrences
*/
protected $count;
/**
* @var integer Interval of recurrence (for every 3 days, "3" would be the interval)
*/
protected $interval;
/**
* @var integer|array An integer between 0 and 59 (for multiple, set as an array)
*/
protected $bysecond;
/**
* @var integer|array An integer between 0 and 59 (or an array of integers for multiple)
*/
protected $byminute;
/**
* @var integer|array An integer or array of integers between 0 and 23
*/
protected $byhour;
/**
* @var string If present, represents the nth occurrence of a specific day within monthly or yearly
* so it can be something like +1MO (or simply 1MO) for the first monday within the month, whereas
* -1MO for the last monday of the month. Or it can be simply MO to represent every monday within the month
*/
protected $byday;
/**
* @var integer|array An integer or array of integers. -31 to -1 or 1 to 31. -10 would mean the tenth to last
* day of the month. [1,5,-5] would be the 1st, 5th, and 5th to last days of the month
*/
protected $bymonthday;
/**
* @var integer|array An integer or array of integers. -366 to -1 or 1 to 366. -306 represents the 306th to last
* day of the year (March 1st)
*/
protected $byyearday;
/**
* @var integer|array An integer or array of integers. -53 to -1 or 1 to 53. Only valid for yearly rules.
* 3 represents the third week of the year.
*/
protected $byweekno;
/**
* @var integer|array An integer or array of integers. 1 to 12. 3 would represent March
*/
protected $bymonth;
/**
* @var integer If present, it indicates the nth occurrence of the specific occurrence within the set of
* events specified by this recurrence rule
*/
protected $bysetpos;
/**
* @var string Must be one of the weekdays specified above (2 char). Specifies the day on which the work week
* starts. This is significant when a weekly rule has an interval greater than 1 and a byday rule part is specified.
* This is also significant when in a yearly rule when a byweekno rule part is specified. Defaults to "MO"
*/
protected $wkst = "MO";
/**
* Constructor
* @param $freq string Must be one of the freqtypes specified above.
* @throws qCal_Date_Exception_InvalidRecur if a frequency other than those specified above is passed in
*/
public function __construct($dtstart = null) {
$this->dtstart = is_null($dtstart) ? null : qCal_DateTime::factory($dtstart);
}
/**
* Specifies the date when the recurrence stops, inclusively. If not present, and there is no count specified,
* then the recurrence goes on "forever".
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param $until string|qCal_Date|DateTime If time is specified, it must be UTC
* @throws qCal_Date_Exception_InvalidRecur
* @return self
*/
public function until($until = null) {
if (is_null($until)) return $this->until;
if ($this->count()) throw new qCal_DateTime_Exception_InvalidRecur('A recurrence count and an until date cannot both be specified');
$this->until = qCal_DateTime::factory($until);
return $this;
}
/**
* Specifies the amount of recurrences before the recurrence ends. If neither this nor "until" is specified,
* the recurrence repeats "forever".
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param $count integer The amount of recurrences before it stops
* @throws qCal_Date_Exception_InvalidRecur
* @return self
*/
public function count($count = null) {
if (is_null($count)) return $this->count;
if ($this->until()) throw new qCal_DateTime_Exception_InvalidRecur('A recurrence count and an until date cannot both be specified');
$this->count = (integer) $count;
return $this;
}
/**
* Specifies the start of the work-week, which is Monday by default
*/
public function wkst($wkst = null) {
if (is_null($wkst)) return $this->wkst;
$abbrs = array_keys($this->weekdays);
if (!in_array($wkst, $abbrs)) throw new qCal_DateTime_Exception_InvalidRecur('"' . $wkst . '" is not a valid week day, must be one of the following: ' . implode(', ', $abbrs));
$this->wkst = $wkst;
// @todo I wonder if re-sorting the weekdays array would help me in any way...
}
/**
* Specifies the interval of recurrences
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param $interval integer The interval of recurrences, for instance every "3" days
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function interval($interval = null) {
if (is_null($interval)) return $this->interval;
$this->interval = (integer) $interval;
return $this;
}
/**
* Specifies a rule which will happen on every nth second.
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param $second integer|array Can be an integer (or array of ints) between 0 and 59
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function bySecond($second = null) {
if (is_null($second)) return $this->bysecond;
if (!is_array($second)) $second = array($second);
$this->bysecond = $second;
return $this;
}
/**
* Specifies a rule which will happen on every nth minute
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param $minute integer|array Can be an integer (or array of ints) between 0 and 59
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function byMinute($minute = null) {
if (is_null($minute)) return $this->byminute;
if (!is_array($minute)) $minute = array($minute);
$this->byminute = $minute;
return $this;
}
/**
* Specifies a rule which will happen on every nth hour
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param $hour integer|array Can be an integer (or array of ints) between 0 and 23
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function byHour($hour = null) {
if (is_null($hour)) return $this->byhour;
if (!is_array($hour)) $hour = array($hour);
$this->byhour = $hour;
return $this;
}
/**
* Specifies a rule which will happen on whichever day is specified. For instance, "MO" would
* mean every monday.
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* Sets $this->byday into an array of arrays like array('SU' => 1) for '1SU' and array('SU' => 0) for 'SU'
* @param $day string|array Must be one of the 2-char week days specified above. Can be preceded by
* a positive or negative integer to represent, for instance, the third monday of the month (3MO) or second to last
* Sunday of the month (-2SU)
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function byDay($day = null) {
if (is_null($day)) {
$ret = array();
foreach ($this->byday as $val) {
$num = (current($val) == 0) ? "" : current($val);
$ret[] = $num . key($val);
}
return $ret;
}
if (!is_array($day)) $day = array($day);
$days = array();
foreach ($day as $d) {
// optional plus or minus followed by a series of digits as group 1
// two-character week day as group 2
if (preg_match('/^([+-]?[0-9]+)?(MO|TU|WE|TH|FR|SA|SU)$/', $d, $matches)) {
$num = ($matches[1] == "") ? "0" : $matches[1];
$wday = $matches[2];
if (substr($num, 0, 1) == "+") {
$num = substr($num, 1);
}
$days[] = array($wday => $num);
}
}
$this->byday = $days;
return $this;
}
/**
* Specifies a rule which will happen on the month days specified. For instance, 23 would mean the 23rd of every month.
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param integer|array Must be between 1 and 31 or -31 to 1 (or an array of those values)
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function byMonthDay($monthday = null) {
if (is_null($monthday)) return $this->bymonthday;
if (!is_array($monthday)) $monthday = array($monthday);
$this->bymonthday = $monthday;
return $this;
}
/**
* Specifies a rule which will happen on the nth day of the year
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param integer|array Must be between 1 and 366 or -366 to -1.
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function byYearDay($yearday = null) {
if (is_null($yearday)) return $this->byyearday;
if (!is_array($yearday)) $yearday = array($yearday);
$this->byyearday = $yearday;
return $this;
}
/**
* Specifies a rule which will happen on the nth week of the year
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param integer|array Must be between 1 and 53 or -53 to -1.
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function byWeekNo($weekno = null) {
if (is_null($weekno)) return $this->byweekno;
if (!is_array($weekno)) $weekno = array($weekno);
$this->byweekno = $weekno;
return $this;
}
/**
* Specifies a rule which will happen on the nth month of the year
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @param integer|array Must be between 1 and 12
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function byMonth($month = null) {
if (is_null($month)) return $this->bymonth;
if (!is_array($month)) $month = array($month);
$this->bymonth = $month;
return $this;
}
/**
* Indicates the nth occurrence of the specific occurrence within the set of
* events specified by the rule.
* This is a getter as well as a setter (if no arg is supplied, it is a getter)
* @todo I don't really understand how this works... :( Figure out wtf it is for.
* @throws qCal_DateTime_Exception_InvalidRecur
* @return self
*/
public function bySetPos($setpos = null) {
if (is_null($setpos)) return $this->bysetpos;
$this->bysetpos = (integer) $setpos;
return $this;
}
/**
* Factory method generates the correct recur type based on the string it is passed: "yearly, weekly, etc."
* @param string The frequency type of recurrence rule you want to generate
* @param mixed The start date/time for the recurrence. Accepts anything qCal_Date accepts
*/
static public function factory($freq, $start) {
$freq = ucfirst(strtolower($freq));
$className = "qCal_DateTime_Recur_" . $freq;
$fileName = str_replace("_", DIRECTORY_SEPARATOR, $className) . ".php";
qCal_Loader::loadFile($fileName);
$class = new $className($start);
return $class;
}
/**
* Fetches instances of the recurrence rule in the given time period. Because recurrences
* could potentially go on forever, there is no way to fetch ALL instances of a recurrence rule
* other than providing a date range that spans the entire length of the recurrence.
*
* The way this will need to work is, depending on the frequency, I will find all possible
* occurrence of the rule. For instance, if this is a "monthly" rule, I'll find out which month
* to start in, then find all occurrence possible. Then narrow down by the other rules I guess.
*
* @idea Maybe I should build classes for each of the frequency types. That way I could loop over
* the object and get methods like qCal_DateTime_Recur_Monthly::isNthDay('SU') to find out what sunday
* of the month it is... stuff like that... I dunno... ?
*
* @throws qCal_DateTime_Exception_InvalidRecur
* @todo The giant switch in this method is a glaring code smell, but it works for now. I will refactor
* after version 0.1 and remove the switch (probably will implement qCal_DateTime_Recur_Yearly, qCal_DateTime_Recur_Monthly, etc.)
*/
public function getRecurrences($start, $end) {
$start = qCal_DateTime::factory($start);
$end = qCal_DateTime::factory($end);
if ($start->getUnixTimestamp() > $end->getUnixTimestamp()) throw new qCal_DateTime_Exception_InvalidRecur('Start date must come before end date');
if (!$this->interval) throw new qCal_DateTime_Exception_InvalidRecur('You must specify an interval');
$rules = array(
'bymonth' => array(),
'byweekno' => array(),
'byyearday' => array(),
'byday' => array(),
);
// byMonth rules
if (is_array($this->bymonth)) {
foreach ($this->bymonth as $bymonth) {
$rules['bymonth'][] = new qCal_DateTime_Recur_Rule_ByMonth($bymonth);
}
}
// byWeekNo rules
if (is_array($this->byweekno)) {
foreach ($this->byweekno as $byweekno) {
$rules['byweekno'][] = new qCal_DateTime_Recur_Rule_ByWeekNo($byweekno);
}
}
// byYearDay rules
if (is_array($this->byyearday)) {
foreach ($this->byyearday as $byyearday) {
$rules['byyearday'][] = new qCal_DateTime_Recur_Rule_ByYearDay($byyearday);
}
}
// byMonthDay rules (these get applied to bymonth rules)
if (is_array($this->bymonthday)) {
foreach ($this->bymonthday as $bymonthday) {
$bmdrule = new qCal_DateTime_Recur_Rule_ByMonthDay($bymonthday);
foreach ($rules['bymonth'] as $bymonth) {
$bymonth->attach($bmdrule);
}
}
}
// byDay rules (these get applied to bymonth rules if they exist, otherwise simply to year)
if (is_array($this->byday)) {
foreach ($this->byday as $byday) {
$bdrule = new qCal_DateTime_Recur_Rule_ByDay($byday);
if (is_array($rules['bymonth']) && !empty($rules['bymonth'])) {
foreach ($rules['bymonth'] as $bymonth) {
$bymonth->attach($bdrule);
}
} else {
$rules['byday'][] = $bdrule;
}
}
}
// byHour rules (these get applied to each rule above)
if (is_array($this->byhour)) {
foreach ($this->byhour as $byhour) {
$bhrule = new qCal_DateTime_Recur_Rule_ByHour($byhour);
foreach ($rules as $type => $ruleset) {
foreach ($ruleset as $rule) {
$rule->attach($bhrule);
}
}
}
}
// byMinute rules (these get applied to each rule above)
if (is_array($this->byminute)) {
foreach ($this->byminute as $byminute) {
$bmrule = new qCal_DateTime_Recur_Rule_ByMinute($byminute);
foreach ($rules as $type => $ruleset) {
foreach ($ruleset as $rule) {
$rule->attach($bmrule);
}
}
}
}
// bySecond rules (these get applied to each rule above)
if (is_array($this->bysecond)) {
foreach ($this->bysecond as $bysecond) {
$bsrule = new qCal_DateTime_Recur_Rule_BySecond($bysecond);
foreach ($rules as $type => $ruleset) {
foreach ($ruleset as $rule) {
$rule->attach($bsrule);
}
}
}
}
return $this->doGetRecurrences($rules, $start, $end);
}
/**
* Each type of rule needs to determine its recurrences so this is left abstract
* to be implemented by children.
*/
abstract protected function doGetRecurrences($rules, $start, $end);
}