有人能解释一下 Taco Hoekwater 计算周数的算法吗?

有人能解释一下 Taco Hoekwater 计算周数的算法吗?

Taco Hoekwater 在 2006 年编写了一个算法,计算周数。该算法大部分情况下都能正确计算周数,但显然遗漏了 2015 年的前 4 天。如果不解释该算法,就无法理解哪里出了问题。

有人能解释一下这个算法到底是怎么回事吗?

\documentclass{article}
%% calendarweek.tex
%% 2006 (C) Taco Hoekwater, public domain
%% Watch out: Dec 29 can be week 1 of the next year; and Jan 3 can be
%% week 53 of the previous year.

\def\Expr#1{\the\numexpr #1\relax}

\def\Modulonumber#1#2{\Expr{#2-((((#2+(#1/2))/#1)-1)*#1)}}
\def\Divisionnumber#1#2{\Expr{(2*#2-#1)/(2*#1)}}

\def\Mod#1#2{\Modulonumber{\Expr{#2}}{\Expr{#1}}}
\def\Div#1#2{\Divisionnumber{\Expr{#2}}{\Expr{#1}}}

\def\Jday#1#2#3%
    {\Expr{#1+\Div{((153*(\Expr{#2+(12*(\Div{14-#2}{12}))-3}))+2)}
     {5}+365*(\Expr{#3+4800-(\Div{14-#2}{12})})+
      (\Div{\Expr{#3+4800-(\Div{14-#2}{12})}}{4})-
      (\Div{\Expr{#3+4800-(\Div{14-#2}{12})}}{100})+
      (\Div{\Expr{#3+4800-(\Div{14-#2}{12})}}{400})-32045 }}

\def\cwhlp#1#2#3%
    {\Expr{\Mod {\Mod {\Mod {\Expr
     {\Jday{#1}{#2}{#3}+31741-\Mod{\Jday{#1}{#2}{#3}}{7}}}%
     {146097}}{36524}}{1461}}}

\def\calendarweek#1#2#3%
  {\Expr{\Expr{\Div{\Expr{\Mod{\cwhlp{#1}{#2}{#3}-
    \Expr{\Div{\cwhlp{#1}{#2}{#3}}{1460}}}{365}+
         \Expr{\Div{\cwhlp{#1}{#2}{#3}}{1460}}}}{7} +1}}}

\begin{document}

Week 1-1-2015 = \calendarweek{01}{01}{2015} %% returns 0

Week 2-1-2015 = \calendarweek{02}{01}{2015} %% returns 0

Week 3-1-2015 = \calendarweek{03}{01}{2015} %% returns 0

Week 4-1-2015 = \calendarweek{04}{01}{2015} %% returns 0

Week 5-1-2015 = \calendarweek{05}{01}{2015} %% returns 2


\end{document}

答案1

ISO,正如评论中提到的,一周是第一周还是第五十三周取决于它的星期四。或者说,一周在新年还是旧年有更多的天数。

为了以数学方式计算这一点,可以考虑Round()满足

  • Round(n+0.4)=n, 和
  • Round(n+0.6)=n+1

然后进行一些计算,如b := Round(a/7)c := b%53+1。(现在我想要 MathJax...)

问题是,在您的.tex文件中,该函数(a,b) |--> Round(b/a)的实现方式为

\def\Divisionnumber#1#2{\Expr{(2*#2-#1)/(2*#1)}}

MyRound[(2b-a)/2a] = MyRound[b/a-1/2]满足:

  • \Divisionnumber{7}{14}= 2
  • \Divisionnumber{7}{ 7}= 1
  • \Divisionnumber{7}{ 0}=-1
  • \Divisionnumber{7}{-7}=-2

这给出了错误的数字。

为了解决这个问题,因为在这种情况下分子总是非负的,我建议:

\def\Divisionnumber#1#2{\Expr{(2*#2+#1)/(2*#1)-1}}

因此[(2b+a)/2a]-1 = MyRound[b/a+1/2]-1满足:

  • \Divisionnumber{7}{14}= 2
  • \Divisionnumber{7}{ 7}= 1
  • \Divisionnumber{7}{ 0}= 0
  • \Divisionnumber{7}{-7}=-2

一些测试代码... 在此处输入图片描述

\documentclass{article}

\def\Expr#1{\the\numexpr #1\relax}
\def\Modulonumber#1#2{\Expr{#2-((((#2+(#1/2))/#1)-1)*#1)}}
\def\Divisionnumber#1#2{\Expr{(2*#2-#1)/(2*#1)}}
\def\Mod#1#2{\Modulonumber{\Expr{#2}}{\Expr{#1}}}
\def\Div#1#2{\Divisionnumber{\Expr{#2}}{\Expr{#1}}}
\def\Jday#1#2#3%
    {\Expr{#1+\Div{((153*(\Expr{#2+(12*(\Div{14-#2}{12}))-3}))+2)}
     {5}+365*(\Expr{#3+4800-(\Div{14-#2}{12})})+
      (\Div{\Expr{#3+4800-(\Div{14-#2}{12})}}{4})-
      (\Div{\Expr{#3+4800-(\Div{14-#2}{12})}}{100})+
      (\Div{\Expr{#3+4800-(\Div{14-#2}{12})}}{400})-32045 }}
\def\cwhlp#1#2#3%  H = (\J+31741-\J%7)%146097%36524%1461
    {\Expr{\Mod {\Mod {\Mod {\Expr
     {\Jday{#1}{#2}{#3}+31741-\Mod{\Jday{#1}{#2}{#3}}{7}}}%
     {146097}}{36524}}{1461}}}
\def\calendarweek#1#2#3%  W = [(H-H/1460)%365+H/1460]/7+1
  {\Expr{\Expr{\Div{\Expr{\Mod{\cwhlp{#1}{#2}{#3}-
    \Expr{\Div{\cwhlp{#1}{#2}{#3}}{1460}}}{365}+
         \Expr{\Div{\cwhlp{#1}{#2}{#3}}{1460}}}}{7} +1}}}
\def\temp#1#2#3{
    \def\a{\Expr{\Div{\cwhlp{#1}{#2}{#3}}{1460}}} % a = H/1460
    \def\b{\Expr{\cwhlp{#1}{#2}{#3}-\a}}          % b = H-a
    \def\c{\Expr{\Mod{\b}{365}}}                  % c = b%365
    \def\d{\Expr{\c+\a}}                          % d = c+a
    \def\e{\Expr{\Div{\d}{7}}}                    % e = d/7
    \def\f{\Expr{\e+1}}                           % f = e+1
    \a\ \b\ \c\ \d\ \e\ \f
}

\usepackage{pgfkeys,pgfcalendar}%\usepackage{tikz}\usetikzlibrary{calendar}
\newcount\jcount
\newcount\wcount
\def\pgfjday#1#2#3{%
    \pgfcalendardatetojulian{#3-#2-#1}{\jcount}%
    \the\jcount
}

\begin{document}

\begin{tabular}{lllllllll}
2015-1-1&\pgfjday11{2015}&\Jday11{2015}&\cwhlp11{2015}&\temp11{2015}&\calendarweek11{2015} \\
2015-1-2&\pgfjday21{2015}&\Jday21{2015}&\cwhlp21{2015}&\temp21{2015}&\calendarweek21{2015} \\
2015-1-3&\pgfjday31{2015}&\Jday31{2015}&\cwhlp31{2015}&\temp31{2015}&\calendarweek31{2015} \\
2015-1-4&\pgfjday41{2015}&\Jday41{2015}&\cwhlp41{2015}&\temp41{2015}&\calendarweek41{2015} \\
2015-1-5&\pgfjday51{2015}&\Jday51{2015}&\cwhlp51{2015}&\temp51{2015}&\calendarweek51{2015} \\
\end{tabular}
\par\bigskip
\underline{\Divisionnumber{7}{14}}
           \Divisionnumber{7}{13}
           \Divisionnumber{7}{12}
           \Divisionnumber{7}{11}
           \Divisionnumber{7}{10}
           \Divisionnumber{7}{ 9}
           \Divisionnumber{7}{ 8}
\underline{\Divisionnumber{7}{ 7}}
           \Divisionnumber{7}{ 6}
           \Divisionnumber{7}{ 5}
           \Divisionnumber{7}{ 4}
           \Divisionnumber{7}{ 3}
           \Divisionnumber{7}{ 2}
           \Divisionnumber{7}{ 1}
\underline{\Divisionnumber{7}{ 0}}
           \Divisionnumber{7}{-1}
           \Divisionnumber{7}{-2}
           \Divisionnumber{7}{-3}
           \Divisionnumber{7}{-4}
           \Divisionnumber{7}{-5}
           \Divisionnumber{7}{-6}
\underline{\Divisionnumber{7}{-7}}

\bigskip % % % % % % % % % % % % % % % 

\def\Divisionnumber#1#2{\Expr{(2*#2+#1)/(2*#1)-1}}
\begin{tabular}{lllllllll}
2015-1-1&\pgfjday11{2015}&\Jday11{2015}&\cwhlp11{2015}&\temp11{2015}&\calendarweek11{2015} \\
2015-1-2&\pgfjday21{2015}&\Jday21{2015}&\cwhlp21{2015}&\temp21{2015}&\calendarweek21{2015} \\
2015-1-3&\pgfjday31{2015}&\Jday31{2015}&\cwhlp31{2015}&\temp31{2015}&\calendarweek31{2015} \\
2015-1-4&\pgfjday41{2015}&\Jday41{2015}&\cwhlp41{2015}&\temp41{2015}&\calendarweek41{2015} \\
2015-1-5&\pgfjday51{2015}&\Jday51{2015}&\cwhlp51{2015}&\temp51{2015}&\calendarweek51{2015} \\
\end{tabular}
\par\bigskip
\underline{\Divisionnumber{7}{14}}
           \Divisionnumber{7}{13}
           \Divisionnumber{7}{12}
           \Divisionnumber{7}{11}
           \Divisionnumber{7}{10}
           \Divisionnumber{7}{ 9}
           \Divisionnumber{7}{ 8}
\underline{\Divisionnumber{7}{ 7}}
           \Divisionnumber{7}{ 6}
           \Divisionnumber{7}{ 5}
           \Divisionnumber{7}{ 4}
           \Divisionnumber{7}{ 3}
           \Divisionnumber{7}{ 2}
           \Divisionnumber{7}{ 1}
\underline{\Divisionnumber{7}{ 0}}
           \Divisionnumber{7}{-1}
           \Divisionnumber{7}{-2}
           \Divisionnumber{7}{-3}
           \Divisionnumber{7}{-4}
           \Divisionnumber{7}{-5}
           \Divisionnumber{7}{-6}
\underline{\Divisionnumber{7}{-7}}

\end{document}

相关内容