7

I still struggle with the expansion of Latex. I try to calculate the a real number from a date format and put this into a macro \value. I need to expand the command with \edef because I plan to use the value as a parameter in pgfplots.

\documentclass[10pt]{article}

\usepackage{tikz} 
\usepackage{pgfcalendar} 

\newcount\mycount

\begin{document}

\newcommand{\dateconvert}[1]{%
 \pgfcalendardatetojulian{#1}{\mycount}
 \pgfcalendarjuliantodate{\mycount}{\myyear}{\mymonth}{\myday}
 \pgfmathparse{(\myday-1)/365+(\mymonth-1)/12+\myyear}\let\mydate\pgfmathresult
 \mydate
}

\dateconvert{2010-07-01} %works

\edef\value\dateconvert{2010-07-01}
\value %does not work: Use of \value doesn't match its definition

\end{document}

Calling \dateconvert directly works. However, when I try to copy the result into \value, it fails.

  • 2
    Since \dateconvert performs various assignments it’s not fully expandable. So you can’t use it in an \edef context. By the way, if \dateconvert were fully expandable you would have to write \edef\value{\dateconvert{2010-07-01}}. – mhp Sep 21 '12 at 7:08
  • 3
    @MartinL. In addition to the comments above, \value is a LaTeX kernel macro, so it's a bad idea to redefine it: you should pick a different name! – Joseph Wright Sep 21 '12 at 7:17
4

Is this procedure right for you?

\documentclass[10pt]{article}
\usepackage{pgfmath} 
\usepackage{pgfcalendar} 

\newcount\mydatecount
\def\settodate#1#2{%
  \pgfcalendardatetojulian{#2}{\mydatecount}
  \pgfcalendarjuliantodate{\mydatecount}{\myyear}{\mymonth}{\myday}%
  \pgfmathsetmacro{#1}{(\myday-1)/365+(\mymonth-1)/12+\myyear}%
}

\begin{document}
\settodate\x{2010-07-01}
\settodate\y{2010-03-01}

\x{} and \y{}
\end{document}

Result

2010.5 and 2010.16666
  • I get an error when compiling your MWE (! Undefined control sequence \pgfkeys). This error disappears when using \usepackage{pgf} instead of \usepackage{pgfmath}. – mhp Sep 21 '12 at 7:25
  • Obviously \pgfmathsetmacro solved the problem. If I would use \edef instead of \pgfmathsetmacro, this would not work anymore. My question now: Since \pgfmathsetmacro only works for numbers, how would I solve the problem if the command would not set a number but a string. – Martin L. Sep 21 '12 at 7:57
  • @MartinL. That's somewhat different to the question here. Perhaps post a second question, linking to this and show the context of what you want to do. If all you want to do is store a string, why not just \def\myvalue{<string>}? – Joseph Wright Sep 21 '12 at 8:10
6

The error you get arises from the fact that

\edef\value\dateconvert{2010-07-01}

defines \value as a macro which must be immediately followed by \dateconvert and which is replaced by the text 2012-07-01. As mentioned in comments, you'd need

\edef\value{\dateconvert{2010-07-01}}

to set \value in the way you intend, but this requires that \dateconvert is expandable. As it performs an assignment, this is not the case (and indeed pgfmath is not expandable at all).

One relatively simple approach is

\documentclass[10pt]{article}

\usepackage{expl3,xparse}
\ExplSyntaxOn
\DeclareExpandableDocumentCommand { \dateconvert } { m }
  { \dateconvert:n {#1} }
\cs_new:Npn \dateconvert:n #1
  { \__dateconvert:w #1 \q_stop }
\cs_new:Npn \__dateconvert:w #1 - #2 - #3 \q_stop
  { \fp_eval:n { #1 + ( #2 - 1 ) / 12 + ( #3 - 1 ) / 365 } }
\ExplSyntaxOff

\newcount\mycount

\begin{document}

\dateconvert{2010-07-01} %works

\edef\myvalue{\dateconvert{2010-07-01}}
\myvalue
\end{document}

This works using the expandable LaTeX3 FPU, and a simple set up for the date parsing: from the question, it's not clear now robust this needs to be. I've renamed \value to \myvalue as \value is a LaTeX kernel command, and you really should not use this name.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.