万年历
请给出指定的某年(如 2020)的全年日历。使用字符串输出,仿照常见日历的格式,按月分隔,包含日期和星期信息。
循环十二个月,首先计算月标题和星期标题添加到万年历,然后循环月中的所有天,按周拼接日期,日期间隔为适当数量的空格,一周拼接结束把结果追加到万年历,然后继续下一周。
A | B | C | D | |
1 | 2020 | >y=A1,c=["Year"/y], w=day@w(date(y, 1, 1)), s=" ", d=6 | [Sun, Mon, Tue, Wed, Thu, Fri, Sat] | =C1.concat(pad("",s,d-3)) |
2 | [January,February,March,April,May,June,July,August,September,October,November,December] | |||
3 | for 12 | >c|=["\n",pad("",s,d*3)+A2(A3), D1] | >r=pad("",s,d*(w-1)) | |
4 | for days(date(y,A3,1)) | >w+=1 | >r/=pad@r(string(B4),s,d) | |
5 | if w==8 | >c|=r, w=1, r="" | ||
6 | if r!="" | >c|=r | ||
7 | =c |
https://try.esproc.com/splx?3Fu
A1设置准备生成哪一年的日历。B1中定义需要用到的几个参数,y表示年份;c存储日历结果,第一行记录年份;w表示周几,初始值为1月1日对应的结果,s为用来对齐的填充字符,这里用空格,d定义日历中每天占用的字符数,这里设为6。
C1为一周每天对应缩写,D1生成标题栏,每月中都要使用。这里的pad函数用填充字符s补齐剩余的标题中每天剩余的位置,用concat将C1中每个成员隔开拼为字串。A2列出每个月的月份。
A3按月循环,生成每个月的日历。B3中在日历结果c中,添加月份行和标题行,每月之前用\n添加一个空行。B2中的代码相当于>c=c|["\n",pad("",s,d*3)+A2(A3), D1],SPL中a=a?b这样的计算可以简写为a?=b,其中?表示运算符。C3中定义参数r来展示当前一行的日历的字串,在每月首日,需要根据它在一周中的位置,用填充字符填补前面的空位。
B4按该月的天数循环,C4将w递增,D4将本日的日期写入r,在其后用填充字符补满到d个位置。C5中判断,如果一周数据准备完成,D5将其记录到c,同时把w和r初始化,准备输出下一行日历。
一个月的日期循环完成后,可能当前行r的数据并不满一整周,此时在B6中判断是否需要把剩余的数据添加到日历c中。
SPL中,可以用for语句执行循环,用if/else执行判断。在执行循环或者分支语句时,会根据格子的位置决定语句的作用范围。
执行后,可以查看日历c中的数据,制表符等特殊字符是不显示的,A7结果如下:
显示时,需要选择空格和各个英文字母都同宽的等宽字体,如Courier,Consolas,宋体等,否则可能会不整齐。
英文版