0

I wrote a function \projlib_datetime_calculate_day_of_week_with_year_month_day:nnn to calculate the "day of week" given the year, month and day (the algorithm adopted should work for dates after 1800s), and also a function \projlib_datetime_display_week_english:n to convert a given number from 1 to 7 to English words. However, I don't know how to combine them to show the day of week of a given date in English. I thought \exp_args:Ne would be enough for getting the value of the first one and then passing to the second, but it doesn't.

Below is my code. Thanks in advance for any help!

\documentclass{article}

% \usepackage{projlib-datetime}

\ExplSyntaxOn

\int_new:N \l__projlib_datetime_day_of_week_day_int
\int_new:N \l__projlib_datetime_day_of_week_month_int
\int_new:N \l__projlib_datetime_day_of_week_year_int
\int_new:N \l__projlib_datetime_day_of_week_century_int
\int_new:N \l__projlib_datetime_day_of_week_result_int
\cs_new:Nn \projlib_datetime_calculate_day_of_week_with_year_month_day:nnn
  {
    \int_set:Nn \l__projlib_datetime_day_of_week_day_int { #3 }
    \int_compare:nNnTF { #2 } < { 3 }
      {
        \int_set:Nn \l__projlib_datetime_day_of_week_year_int { \int_eval:n { #1 - 1 } }
      }
      {
        \int_set:Nn \l__projlib_datetime_day_of_week_year_int { #1 }
      }
    \int_set:Nn \l__projlib_datetime_day_of_week_century_int { \int_eval:n { \l__projlib_datetime_day_of_week_year_int / 100 } }
    \int_set:Nn \l__projlib_datetime_day_of_week_year_int { \int_mod:nn { \l__projlib_datetime_day_of_week_year_int } { 100 } }
    \int_set:Nn \l__projlib_datetime_day_of_week_month_int
      {
        \int_case:nnF { #2 }
          {
            {  1 } { 0 }
            {  2 } { 3 }
            {  3 } { 2 }
            {  4 } { 5 }
            {  5 } { 0 }
            {  6 } { 3 }
            {  7 } { 5 }
            {  8 } { 1 }
            {  9 } { 4 }
            { 10 } { 6 }
            { 11 } { 2 }
            { 12 } { 4 }
          }        { 0 }
      }
    \int_set:Nn \l__projlib_datetime_day_of_week_result_int
      {
        \int_eval:n
          {
              \l__projlib_datetime_day_of_week_day_int
            + \l__projlib_datetime_day_of_week_month_int
            +\l__projlib_datetime_day_of_week_year_int
            + \int_div_truncate:nn { \l__projlib_datetime_day_of_week_year_int } { 4 }
            + \int_div_truncate:nn { \l__projlib_datetime_day_of_week_century_int } { 4 }
            - 2 * \l__projlib_datetime_day_of_week_century_int
          }
      }
    \int_set:Nn \l__projlib_datetime_day_of_week_result_int
      {
        \int_mod:nn { \l__projlib_datetime_day_of_week_result_int } { 7 }
      }
    \int_compare:nNnT { \l__projlib_datetime_day_of_week_result_int } < { 1 }
      {
        \int_set:Nn \l__projlib_datetime_day_of_week_result_int
          {
            \int_eval:n { \l__projlib_datetime_day_of_week_result_int + 7 }
          }
      }
    \int_use:N \l__projlib_datetime_day_of_week_result_int
  }



\cs_new:Nn \projlib_datetime_display_week_english:n
  {
    \int_case:nnF { #1 }
      {
        { 1 }  { Monday    }
        { 2 }  { Tuesday   }
        { 3 }  { Wednesday }
        { 4 }  { Thursday  }
        { 5 }  { Friday    }
        { 6 }  { Saturday  }
        { 7 }  { Sunday    }
      } { ??? }
  }


\ExplSyntaxOff

\begin{document}

\ExplSyntaxOn

\projlib_datetime_calculate_day_of_week_with_year_month_day:nnn { 2022 } { 02 } { 16 }

\projlib_datetime_calculate_day_of_week_with_year_month_day:nnn { 2022 } { 02 } { 28 }

\projlib_datetime_calculate_day_of_week_with_year_month_day:nnn { 2022 } { 03 } { 01 }

% \exp_args:Ne
% \projlib_datetime_display_week_english:n
%   {
%     \projlib_datetime_calculate_day_of_week_with_year_month_day:nnn { 2022 } { 02 } { 01 }
%   }

\ExplSyntaxOff

\end{document}
2
  • e argument is expansion actually the \expanded primitive, so like \edef so it can only expand expandable macros but your function does assignments so can not be expandable and can not work in an context Commented Feb 16, 2022 at 21:28
  • If you removed the\int_use:N \l__projlib_datetime_day_of_week_result_int from theend then calling the first would leave theresul it \l__projlib_datetime_day_of_week_result_int which you could then pass to your second function Commented Feb 16, 2022 at 21:32

1 Answer 1

1

As written your first function is not expandable so can not be used in an expansion context such as e argument. You could write it to be expandable by removing all the internal assignments, but simpler is remove the final \use so the result is just left in the local variable, which you can then either use or pass to your second function as required.

enter image description here

\documentclass{article}

% \usepackage{projlib-datetime}

\ExplSyntaxOn

\int_new:N \l__projlib_datetime_day_of_week_day_int
\int_new:N \l__projlib_datetime_day_of_week_month_int
\int_new:N \l__projlib_datetime_day_of_week_year_int
\int_new:N \l__projlib_datetime_day_of_week_century_int
\int_new:N \l__projlib_datetime_day_of_week_result_int
\cs_new:Nn \projlib_datetime_calculate_day_of_week_with_year_month_day:nnn
  {
    \int_set:Nn \l__projlib_datetime_day_of_week_day_int { #3 }
    \int_compare:nNnTF { #2 } < { 3 }
      {
        \int_set:Nn \l__projlib_datetime_day_of_week_year_int { \int_eval:n { #1 - 1 } }
      }
      {
        \int_set:Nn \l__projlib_datetime_day_of_week_year_int { #1 }
      }
    \int_set:Nn \l__projlib_datetime_day_of_week_century_int { \int_eval:n { \l__projlib_datetime_day_of_week_year_int / 100 } }
    \int_set:Nn \l__projlib_datetime_day_of_week_year_int { \int_mod:nn { \l__projlib_datetime_day_of_week_year_int } { 100 } }
    \int_set:Nn \l__projlib_datetime_day_of_week_month_int
      {
        \int_case:nnF { #2 }
          {
            {  1 } { 0 }
            {  2 } { 3 }
            {  3 } { 2 }
            {  4 } { 5 }
            {  5 } { 0 }
            {  6 } { 3 }
            {  7 } { 5 }
            {  8 } { 1 }
            {  9 } { 4 }
            { 10 } { 6 }
            { 11 } { 2 }
            { 12 } { 4 }
          }        { 0 }
      }
    \int_set:Nn \l__projlib_datetime_day_of_week_result_int
      {
        \int_eval:n
          {
              \l__projlib_datetime_day_of_week_day_int
            + \l__projlib_datetime_day_of_week_month_int
            +\l__projlib_datetime_day_of_week_year_int
            + \int_div_truncate:nn { \l__projlib_datetime_day_of_week_year_int } { 4 }
            + \int_div_truncate:nn { \l__projlib_datetime_day_of_week_century_int } { 4 }
            - 2 * \l__projlib_datetime_day_of_week_century_int
          }
      }
    \int_set:Nn \l__projlib_datetime_day_of_week_result_int
      {
        \int_mod:nn { \l__projlib_datetime_day_of_week_result_int } { 7 }
      }
    \int_compare:nNnT { \l__projlib_datetime_day_of_week_result_int } < { 1 }
      {
        \int_set:Nn \l__projlib_datetime_day_of_week_result_int
          {
            \int_eval:n { \l__projlib_datetime_day_of_week_result_int + 7 }
          }
      }
%    \int_use:N \l__projlib_datetime_day_of_week_result_int
  }



\cs_new:Nn \projlib_datetime_display_week_english:n
  {
    \int_case:nnF { #1 }
      {
        { 1 }  { Monday    }
        { 2 }  { Tuesday   }
        { 3 }  { Wednesday }
        { 4 }  { Thursday  }
        { 5 }  { Friday    }
        { 6 }  { Saturday  }
        { 7 }  { Sunday    }
      } { ??? }
  }


\ExplSyntaxOff

\begin{document}

\ExplSyntaxOn

\projlib_datetime_calculate_day_of_week_with_year_month_day:nnn { 2022 } { 02 } { 16 }
\int_use:N \l__projlib_datetime_day_of_week_result_int

\par\bigskip

\projlib_datetime_calculate_day_of_week_with_year_month_day:nnn { 2022 } { 02 } { 28 }
\int_use:N \l__projlib_datetime_day_of_week_result_int

\par\bigskip

\projlib_datetime_calculate_day_of_week_with_year_month_day:nnn { 2022 } { 03 } { 01 }
\int_use:N \l__projlib_datetime_day_of_week_result_int

\par\bigskip

\projlib_datetime_calculate_day_of_week_with_year_month_day:nnn { 2022 } { 02 } { 01 }
\projlib_datetime_display_week_english:n\l__projlib_datetime_day_of_week_result_int


\ExplSyntaxOff

\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .