答案1
以一种非常简单的方式钾Z 可以使用命令的dates
键和if (<test date>) [<style>]
路径来完成此操作\calendar
。两者都在PGF手册。还有更巧妙的解决方案。例如,使用以下代码即可解决此问题:
\documentclass[border=3mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calendar}
\newcommand{\calOfTheMonth}[4]{%
\calendar [dates=2021-0#1-01+-#2 to 2021-0#1-last+#3,week list,month yshift=0pt]
if (between=2021-0#1-01+-#2 and 2021-0#1-01+-1) [gray]
if (between=2021-0#1-last+1 and 2021-0#1-last+#3) [gray];
\node[above=3ex,anchor=west] {#4};}
\begin{document}
%Explanation of the \calOfTheMonth macro
% \calOfTheMonth{n. of the month}{days to add before}{days to add after}{name of the month}
\tikz
\matrix{
\calOfTheMonth{1}{4}{0}{January}\\
\calOfTheMonth{2}{0}{0}{February}\\
\calOfTheMonth{3}{0}{4}{March}\\
\calOfTheMonth{4}{3}{2}{April}\\
\calOfTheMonth{5}{5}{6}{May}\\
\calOfTheMonth{6}{1}{4}{June}\\
\calOfTheMonth{7}{3}{1}{July}\\
\calOfTheMonth{8}{6}{5}{August}\\
\calOfTheMonth{9}{2}{3}{September}\\
\calOfTheMonth{10}{4}{0}{October}\\
\calOfTheMonth{11}{0}{5}{November}\\
\calOfTheMonth{12}{2}{2}{December}\\
};
\end{document}
答案2
有了ext.calendar-plus
我的图书馆tikz-ext
包裹我们可以一起破解一些更自动化的东西:
该方法使用以下条件首先在我的另一个答案中实现但现在是所提到的图书馆的一部分。
week of month = <value>
:
如果当前日期位于<value>
该月的第周,则返回 true。因为
week of month = 1
这基本上等于between = <month>-01 and <month>-07
但不进行太多的计算。week of month' = <value>
:
如果当前日期位于<value>
该月的倒数第一周,则返回 true。and = <list of conditions>
:
如果列表中的所有条件都为真,则返回 true
它还使用了为此答案创建的两个新条件,但现在它们也是库的一部分:
calendar week of month = <value>
如果当前日期位于<value>
该月的第周,则返回 true。calendar week of month' = <value>
如果当前日期位于<value>
该月的倒数第一周,则返回 true。
它们都使用当前日期和当前星期几来计算日历周数并将其与给定的值进行比较。
该calendar week of month'
条件使用calendar week of month
键,但在调用之前反转数字。
如果我们现在有and
两个条件
week of month = 1
(即一周的前七天)和calendar week of month = 2
(即第二个日历周的七天)
我们找到了那些想要将前一周的另一天添加到日历中的日子和星期几。
这同样适用于周末
week of month' = 1
(即一周的最后七天)和calendar week of month' = 2
。
如果这些条件适用,我们直接执行样式add day from week before
或add day from week after
。(“直接”的意思是它们甚至在调用实际的当前日期之前就执行了——将此代码添加到可能更合乎逻辑execute at end day scope
。)
由于这是作为 s 的一部分执行的,if
因此它可能会继承最初适用于实际当前日期的设置。但是,如果我们if
尽早添加 s,我们可能会顺利完成。
和模拟时间旅行到当前处理的一天之前/之后add day from week before
的add day from week after
一周。
这\pgftransformyshift
显然取决于日历的实际样式,最好将其放入样式中,add day from week …
以便该代码可以更好地重用于其他日历样式。
代码
\documentclass[border=3mm,tikz]{standalone}
\usetikzlibrary{ext.calendar-plus}
\makeatletter
\tikzset{
add day from week before/.default=, add day from week after/.default=,
add day from week before/.code={%
\begingroup % shift whole calendar 7 days in the past
\advance\pgfcalendarcurrentjulian by -7
\pgfcalendarjuliantodate{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\pgfcalendarcurrentmonth}{\pgfcalendarcurrentday}%
\pgfcalendarjuliantoweekday{\pgfcalendarcurrentjulian}{\pgfutil@tempcntb}%
\edef\pgfcalendarcurrentweekday{\the\pgfutil@tempcntb}%
\pgfcalendarjulianyeartoweek{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\pgfutil@tempcntb}%
\edef\pgfcalendarcurrentweek{\ifnum\pgfutil@tempcntb<10 0\fi\the\pgfutil@tempcntb}%
\pgftransformyshift{\pgfkeysvalueof{/tikz/day yshift}}%
\tikzset{every day from week before/.try,#1}%
\tikzdaycode
\endgroup},
add day from week after/.code={%
\begingroup % shift whole calendar 7 days in the future
\advance\pgfcalendarcurrentjulian by +7
\pgfcalendarjuliantodate{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\pgfcalendarcurrentmonth}{\pgfcalendarcurrentday}%
\pgfcalendarjuliantoweekday{\pgfcalendarcurrentjulian}{\pgfutil@tempcntb}%
\edef\pgfcalendarcurrentweekday{\the\pgfutil@tempcntb}%
\pgfcalendarjulianyeartoweek{\pgfcalendarcurrentjulian}{\pgfcalendarcurrentyear}{\pgfutil@tempcntb}%
\edef\pgfcalendarcurrentweek{\ifnum\pgfutil@tempcntb<10 0\fi\the\pgfutil@tempcntb}%
\pgftransformyshift{-(\pgfkeysvalueof{/tikz/day yshift})}%
\tikzset{every day from week after/.try,#1}%
\tikzdaycode
\endgroup}}
\makeatother
\begin{document}
\sffamily
\tikz\calendar[
dates=2022-01-01 to 2022-03-31, week list, month label above centered,
% as early as possible
if = {(and = {week of month = 1, calendar week of month = 2}) [add day from week before]},
if = {(and = {week of month'= 1, calendar week of month'= 2}) [add day from week after]},
every day from week before/.style=gray,
every day from week after/.style={gray,if=(Sunday)[red!25!gray]},
] if (Sunday) [red];
\end{document}