2012-09-08 64 views

回答

7

python-dateutil包中沒有方法或函數來執行此操作。查看此錯誤以獲取可能有所幫助的修補程序:https://bugs.launchpad.net/dateutil/+bug/943512

+0

應該注意行摺疊http:// www .apps.ietf.org/RFC/rfc2445.html#仲丁基4.1 – oberron

0

下面是rrule的一個子類,它包含兩個建議的python-dateutil補丁,它們使rrule輸出成爲可能。請注意,補丁程序未被接受可能有很好的理由,並且我只對最簡單的情況進行了測試。不處理摺疊線。

見討論的bug跟蹤系統: https://bugs.launchpad.net/dateutil/+bug/943512
https://bugs.launchpad.net/dateutil/+bug/943509

FREQNAMES = ['YEARLY', 'MONTHLY', 'WEEKLY', 'DAILY', 'HOURLY', 'MINUTELY', 'SECONDLY'] 


class ConvertibleRRule(rrule.rrule): 
    # Subclass of the `rrule class that provides a sensible __str__() 
    # method, outputting ical formatted rrules. 
    # Combined from the patches in these dateutil issues: 
    # https://bugs.launchpad.net/dateutil/+bug/943512 
    # https://bugs.launchpad.net/dateutil/+bug/943509 
    _bysecond_internal = False 
    _byminute_internal = False 
    _byhour = False 
    _bymonth_internal = False 
    _bymonthday_internal = False 
    _byweekday_internal = False 

    def __init__(self, freq, dtstart=None, 
       interval=1, wkst=None, count=None, until=None, bysetpos=None, 
       bymonth=None, bymonthday=None, byyearday=None, byeaster=None, 
       byweekno=None, byweekday=None, 
       byhour=None, byminute=None, bysecond=None, 
       cache=False): 
     super(ConvertibleRRule, self).__init__(
      freq, dtstart=dtstart, 
      interval=interval, wkst=wkst, count=count, until=until, bysetpos=bysetpos, 
      bymonth=bymonth, bymonthday=bymonthday, byyearday=byyearday, byeaster=byeaster, 
      byweekno=byweekno, byweekday=byweekday, 
      byhour=byhour, byminute=byminute, bysecond=bysecond, 
      cache=cache) 

     if (byweekno is None and byyearday is None and bymonthday is None and 
        byweekday is None and byeaster is None): 
      if freq == rrule.YEARLY: 
       if not bymonth: 
        self._bymonth_internal = True 
       self._bymonthday_internal = True 
      elif freq == rrule.MONTHLY: 
       self._bymonthday_internal = True 
      elif freq == rrule.WEEKLY: 
       self._byweekday_internal = True 

     # byhour 
     if byhour is None: 
      if freq < rrule.HOURLY: 
       self._byhour_internal = True 

     # byminute 
     if byminute is None: 
      if freq < rrule.MINUTELY: 
       self._byminute_internal = True 

     # bysecond 
     if bysecond is None: 
      if freq < rrule.SECONDLY: 
       self._bysecond_internal = True 

    freq = property(lambda s: s._freq) 
    dtstart = property(lambda s: s._dtstart) 
    interval = property(lambda s: s._interval) 

    @property 
    def wkst(self): 
     if self._wkst == rrule.calendar.firstweekday(): 
      return None 
     return rrule.weekday(self._wkst) 

    count = property(lambda s: s._count) 
    until = property(lambda s: s._until) 
    bysetpos = property(lambda s: s._bysetpos) 

    @property 
    def bymonth(self): 
     if self._bymonth_internal: 
      return None 
     return self._bymonth 

    @property 
    def bymonthday(self): 
     if self._bymonthday_internal: 
      return None 
     return self._bymonthday + self._bynmonthday 

    byyearday = property(lambda s: s._byyearday) 
    byeaster = property(lambda s: s._byeaster) 
    byweekno = property(lambda s: s._byweekno) 

    @property 
    def byweekday(self): 
     if self._byweekday_internal: 
      return None 
     bynweekday, byweekday =(),() 
     if self._bynweekday: 
      bynweekday = tuple(rrule.weekday(d, n) for d, n in self._bynweekday) 
     if self._byweekday: 
      byweekday = tuple(rrule.weekday(d) for d in self._byweekday) 
     return bynweekday + byweekday 

    @property 
    def byhour(self): 
     if self._byhour_internal: 
      return None 
     return self._byhour 

    @property 
    def byminute(self): 
     if self._byminute_internal: 
      return None 
     return self._byminute 

    @property 
    def bysecond(self): 
     if self._bysecond_internal: 
      return None 
     return self._bysecond 

    def __str__(self): 
     parts = ['FREQ=' + FREQNAMES[self.freq]] 

     if self.interval != 1: 
      parts.append('INTERVAL=' + str(self.interval)) 
     if self.wkst: 
      parts.append('WKST=' + str(self.wkst)) 
     if self.count: 
      parts.append('COUNT=' + str(self.count)) 

     for name, value in [ 
      ('BYSETPOS', self.bysetpos), 
      ('BYMONTH', self.bymonth), 
      ('BYMONTHDAY', self.bymonthday), 
      ('BYYEARDAY', self.byyearday), 
      ('BYWEEKNO', self.byweekno), 
      ('BYWEEKDAY', self.byweekday), 
      ('BYHOUR', self.byhour), 
      ('BYMINUTE', self.byminute), 
      ('BYSECOND', self.bysecond), 
     ]: 
      if value: 
       parts.append(name + '=' + ','.join(str(v) for v in value)) 

     return ';'.join(parts) 
0

雖然這是寫四年有人問後,dateutil現在有一個__str__方法(見source code),它允許一個print其形式如下:

In [1]: from dateutil.rrule import * 

In [2]: my_rrule = rrule(DAILY, count=5) 

In [3]: print(my_rrule) 
DTSTART:20161202T184513 
FREQ=DAILY;COUNT=5