渲染文本日历

Rendering Text Calendar

我有一个函数应该为这样的日历构建 header:

' Sun Mon Tue Wed Thu Fri Sat '

它需要一个工作日('#Monday' 1, 2, 3, 4, 5, 6, 7 '#Sunday'之一)。

代码如下:

@staticmethod
def _isoweekday_to_str(isoweekday):
    isoweekday = isoweekday - 1
    isoweekday = str(isoweekday)
    x = datetime.strptime(isoweekday, '%w')
    return x.strftime('%a')

TEXT_CAL_MONTH_WEEK_HEADER = ""

iter_isoweekday = week_start
for _ in range(0,7):
    TEXT_CAL_MONTH_WEEK_HEADER += self._isoweekday_to_str(iter_isoweekday).rjust(TEXT_CAL_CELL_WIDTH, " ")

            if iter_isoweekday != 7:
                iter_isoweekday += 1
            else:
                iter_isoweekday = 1

当以 4 作为周开始时,我得到的输出是:

' Mon Mon Mon Mon Mon Mon Mon '

应该是:

' Thu Fri Sat Sun Mon Tue Wed '

我真的、真的不确定发生了什么。我认为这与分配变量的方式、字符串突变或日期时间库有关。

更新:看来 datetime.strptime 是问题所在。无论我传入什么,我都会得到 datetime(1900, 1, 1, 0, 0) ......你猜对了,是星期一。

帮忙?

我不确定你为什么要这样做,但你需要一个实际的日期来传递给 strptime 而不是一个工作日。例如,

from datetime import datetime
TEXT_CAL_CELL_WIDTH = 5
def _isoweekday_to_str(isoweekday):
    isoweekday = '1900-01-{:02d}'.format(isoweekday)
    x = datetime.strptime(isoweekday, '%Y-%m-%d')
    return x.strftime('%a')

TEXT_CAL_MONTH_WEEK_HEADER = ""

week_start = 4
iter_isoweekday = week_start
for _ in range(0,7):
    TEXT_CAL_MONTH_WEEK_HEADER += _isoweekday_to_str(iter_isoweekday).rjust(TEXT_CAL_CELL_WIDTH, " ")
    if iter_isoweekday != 7:
        iter_isoweekday += 1
    else:
        iter_isoweekday = 1
print(TEXT_CAL_MONTH_WEEK_HEADER )

输出:

Thu  Fri  Sat  Sun  Mon  Tue  Wed

(之所以有效,是因为 01/01/1900 是星期一)。

但为什么不对日期名称字典做类似的事情呢:

day_names = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
def weekday_header(week_start):
    header = ''.join(['{:4s}'.format(day_names[(day_number+week_start) % 7])
                     for day_number in range(7)])
    return header

print(weekday_header(4))

您可以从 calendar module:

中获取本地化的星期几
>>> import calendar
>>> list(calendar.day_name)
['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

或缩写名称,使用calendar.day_abbr:

>>> ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']

如果您需要其他语言环境,请参阅 the documentation

显然,该模块可以生成整个日历:

>>> print calendar.TextCalendar().formatmonth(2016, 1)
    January 2016
Mo Tu We Th Fr Sa Su
             1  2  3
 4  5  6  7  8  9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31