渲染文本日历
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
我有一个函数应该为这样的日历构建 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