Skip to content

Instantly share code, notes, and snippets.

@renyi
Forked from kagesenshi/epiweek.py
Last active August 29, 2015 14:27
Show Gist options
  • Save renyi/c736d76cd1da83c53e4f to your computer and use it in GitHub Desktop.
Save renyi/c736d76cd1da83c53e4f to your computer and use it in GitHub Desktop.

Revisions

  1. @kagesenshi kagesenshi created this gist Aug 18, 2015.
    122 changes: 122 additions & 0 deletions epiweek.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,122 @@
    from datetime import date
    from datetime import timedelta
    import copy

    # ported from npmjs epi-week package
    # https://github.com/wombleton/epi-week

    #
    #getFirstWeek = (year) ->
    # end = new Date(year, 0, 1)
    # end.setHours(0, 0, 0, 0)
    # days = 0
    # while ++days < 4 or end.getDay() isnt 6
    # end.setDate(end.getDate() + 1)
    # start = new Date(end.getTime())
    # start.setDate(start.getDate() - 6)
    # start

    def getFirstWeek(year):
    """
    >>> getFirstWeek(2012).strftime('%A %Y-%m-%d')
    'Sunday 2012-01-01'
    >>> getFirstWeek(2011).strftime('%A %Y-%m-%d')
    'Sunday 2011-01-02'
    >>> getFirstWeek(2013).strftime('%A %Y-%m-%d')
    'Sunday 2012-12-30'
    >>> getFirstWeek(2007).strftime('%A %Y-%m-%d')
    'Sunday 2006-12-31'
    """
    end = date(year, 1, 1)
    days = 0
    while days < 3 or end.weekday() != 5:
    end += timedelta(1)
    days += 1
    start = end - timedelta(6)
    return start


    #
    #calculate = (date = new Date(), marker) ->
    # date.setHours(0, 0, 0, 0)
    #
    # firstWeekThisYear = getFirstWeek(date.getFullYear())
    # firstWeekNextYear = getFirstWeek(date.getFullYear() + 1)
    #
    # marker ?= new Date(date.getTime())
    # marker.setMonth(0, 1)
    # week = 0
    # while marker < date
    # day = marker.getDay()
    # week++ if day is 6
    # marker.setDate(marker.getDate() + 1)
    # if week is 0
    # if date >= firstWeekThisYear
    # week: 1
    # year: date.getFullYear()
    # else
    # marker.setFullYear(date.getFullYear() - 1, 0, 1)
    # calculate(date, marker)
    # else
    # if week >= 51 and date >= firstWeekNextYear
    # week: 1
    # year: date.getFullYear() + 1
    # else
    # week: week + 1
    # year: date.getFullYear() - (if date < firstWeekThisYear then 1 else 0)

    def calculate(d, marker=None):
    """
    >>> calculate(date(2013,4,24))
    (17, 2013)
    >>> calculate(date(2013,4,28))
    (18, 2013)
    >>> calculate(date(2013,4,27))
    (17, 2013)
    >>> calculate(date(2013,4,21))
    (17, 2013)
    >>> calculate(date(2013,4,20))
    (16, 2013)
    >>> calculate(date(2013,12,31))
    (1, 2014)
    >>> calculate(date(2007,1,1))
    (1, 2007)
    >>> calculate(date(2006,12,30))
    (52, 2006)
    """
    firstWeekThisYear = getFirstWeek(d.year)
    firstWeekNextYear = getFirstWeek(d.year + 1)
    if marker is None:
    marker = date(d.year, 1, 1)
    else:
    marker = date(marker.year, 1, 1)
    week = 0
    while marker < d:
    day = marker.weekday()
    if day == 5:
    week += 1
    marker += timedelta(1)
    if week == 0:
    if d >= firstWeekThisYear:
    return (1, d.year)
    else:
    marker = date(marker.year -1, 1, 1)
    return calculate(d, marker)
    else:
    if week >= 51 and d >= firstWeekNextYear:
    return (1, d.year + 1)
    else:
    return (week + 1, d.year - (1 if d < firstWeekThisYear else 0))


    def test_calculate():
    for d, o in [
    ((2014,1,1), (1,2014)),
    ((2013,12,31), (1,2014)),
    ((2007,1,1), (1,2007)),
    ((2006,12,31), (1,2007)),
    ((2006,12,30), (52,2006))
    ]:
    assert epiweek.calculate(date(*d)) == o