Tikz 日历中的整周

Tikz 日历中的整周

我正在尝试使用 Tikz 创建月历。

我在用这个模板。一切正常,除了我希望能够获得显示周数中的前几个月和后几个月的天数,就像这个例子(图 7.7)。我发现使用 PGF 是可行的。我可以用 Tikz 日历来实现吗?

答案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 beforeadd day from week after。(“直接”的意思是它们甚至在调用实际的当前日期之前就执行了——将此代码添加到可能更合乎逻辑execute at end day scope。)

由于这是作为 s 的一部分执行的,if因此它可能会继承最初适用于实际当前日期的设置。但是,如果我们if尽早添加 s,我们可能会顺利完成。

和模拟时间旅行到当前处理的一天之前/之后add day from week beforeadd 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}

输出

在此处输入图片描述

相关内容