% % This LaTeX file creates a calendar of all weeks in a person's lifetime, % similar to the life calendar created by Tim Urban in his blog: % % % This calendar correctly handles leap years, weekdays and calendar years. % % Each week takes 5mm x 5mm (shown as rectangle of 4mm x 4mm), so at most % 82 years fit onto a A3 page of paper. % % To create a PDF, manage to install required LaTeX packages and run: % % $ pdflatex calendar.tex % \documentclass[a3paper,12pt]{article} \usepackage{tikz} \usetikzlibrary{calc} \usetikzlibrary{backgrounds} \usepackage{xcolor} \usepackage{calc} \usepackage{datenumber} \newcounter{birthday} \newcounter{firstday} \newcounter{firstweek} \newcounter{daysleft} \newcounter{weeksleft} \newcounter{tmp} % expected life span in years \newcommand{\firstyear}{0} \newcommand{\lastyear}{81} % birthday, date format: year, month, day \setmydatenumber{birthday}{1990}{1}{1} % page and font layout \usepackage[left=0mm,top=3mm,bottom=0mm,right=0mm,nohead,nofoot]{geometry} \setlength{\parindent}{0pt} \renewcommand{\familydefault}{\sfdefault} \tikzstyle{week}=[ draw, shape=rectangle, minimum width=4mm, minimum height=4mm ] \tikzset{partial/.style n args={1}{ week, draw=none, append after command={ [shorten <= -0.5\pgflinewidth] ($(\tikzlastnode.north west)!#1/7!(\tikzlastnode.north east)$) edge (\tikzlastnode.north west) (\tikzlastnode.north west) edge (\tikzlastnode.south west) (\tikzlastnode.south west) edge ($(\tikzlastnode.south west)!#1/7!(\tikzlastnode.south east)$) } } } \begin{document} \thispagestyle{empty} \begin{center} \begin{tikzpicture} \setdatebynumber{\thebirthday} \newcounter{birthdaymonth}\setcounter{birthdaymonth}{\thedatemonth} \newcounter{birthdayday}\setcounter{birthdayday}{\thedateday} \node[anchor=south east,yshift=1mm] at (0,0) {\scriptsize age}; \foreach \age in {\firstyear,...,\lastyear} { % left: year of age \node[anchor=east] at (0,-5mm*\age) {\age}; % days counter at first day of this year of life \setcounter{firstday}{\thedatenumber} % first week \ifnum\value{datedayname}>1 % partial week \setcounter{firstweek}{\the\numexpr8-\value{datedayname}\relax} \node[rotate=180,partial=\thefirstweek] at (5mm,-5mm*\age) {}; \else % full week (starting at monday) \setcounter{firstweek}{7} \node[week] at (5mm,-5mm*\age) {}; \fi % skip to the day before next birthday \addtocounter{dateyear}{1} \setdatenumber{\thedateyear}{\thebirthdaymonth}{\thebirthdayday} \prevdate % number of days in this year of life (358...365) \setcounter{daysleft}{\thedatenumber} \addtocounter{daysleft}{-\thefirstday} \addtocounter{daysleft}{-\thefirstweek} \addtocounter{daysleft}{1} % full weeks left in this year of life (51...52) \pgfmathparse{int(floor(\thedaysleft/7))} \setcounter{weeksleft}{\pgfmathresult} % days left in the last week (0...6) \addtocounter{daysleft}{-7*\theweeksleft} \ifnum\value{daysleft}>0 \node[partial=\thedaysleft] at (5mm*\theweeksleft+5mm,-5mm*\age) {}; \fi \pgfmathsetlengthmacro{\endofyear}{5mm*\theweeksleft+2.5mm+5mm*\thedaysleft/7} % end of year \setcounter{tmp}{\thedatenumber} \setdatenumber{\thedateyear}{1}{1} \setcounter{daysleft}{\thedatenumber} \addtocounter{daysleft}{-\thefirstday} \addtocounter{daysleft}{1} %\node[color=blue] at (0,-5mm*\age) {\thedaysleft}; \pgfmathsetlengthmacro{\newyear}{2.5mm+5mm/7*\thedaysleft-5mm/7*\thefirstweek} \pgfmathsetlengthmacro{\startofyear}{7.5mm-\thefirstweek*5mm/7} %\draw[thick,color=red] (\endofyear,-5mm*\age+2.5mm) to +(0,-5mm); %\draw[thick,color=blue] (\startofyear,-5mm*\age+2.5mm) to +(0,-5mm); %\draw[thick,color=green] (\newyear,-5mm*\age+2.5mm) to +(0,-5mm); % draw full weeks \foreach \week in {2,...,\theweeksleft} \node[week] at (5mm*\week,-5mm*\age) {}; % right: calendar year at the day before next birthday \setdatebynumber{\thetmp} \ifodd\thedateyear \begin{scope}[on background layer] \path[fill=gray!20] (\startofyear,-5mm*\age+2.5mm) rectangle (\newyear,-5mm*\age-2.5mm); \end{scope} \else \begin{scope}[on background layer] \path[fill=gray!20] (\newyear,-5mm*\age-2.5mm) rectangle (\endofyear,-5mm*\age+2.5mm); \end{scope} \node[anchor=west] at (52.5*5mm,-5mm*\age) {\thedateyear}; \fi % skip to next birthday \nextdate \setdatenumber{\thedateyear}{\thebirthdaymonth}{\thebirthdayday} } \end{tikzpicture} \end{center} \end{document}