8

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
  • 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, 2012 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, 2012 at 7:17

2 Answers 2

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
3
  • 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, 2012 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, 2012 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, 2012 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.

You must log in to answer this question.

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