平衡点


2013/03/12

_ 日付の計算...?

TeX でじたばた

とある申請書のフォーマットを更新することになって, 今年から「申請第一希望日程」〜「申請第三希望日程」 という(感じの)項目が増えることに.

それ自体は良いのだけれど

  • 開始日から終了日までの「期間」を求めて
  • 三つの期間が等しい事を検証して, 等しくない場合には typeset を停止する

という処理を入れたい, という要望.

日付自体はソースから適当に持ってくれば良いのだけれど, \TeX (not \LaTeX ) で暦を計算する, というのは無理ゲーな気がするので, どうしようか思案 . ちなみに, 他の言語で日付だけ計算して, というのも(要件として)駄目.

結局

  • 年度単位の申請書なので「総日数」を定義しておいて閏年判定に使用
  • 入力された月日の経過総日数を計算, 差をとって区間を計算

としてみた.

とりあえず動いているから良しとするけれど, もっと上手い方法無いかなぁ.

日付のパース

入力が \start1={平成25年4月1日} みたいな塩梅なので, この入力値から年, 月, 日のみを取得する, みたいな.

# source: latex
   \def\YearElement#1年#2月#3日{#1}
   \def\MonthElement#1年#2月#3日{#2}
   \def\DayElement#1年#2月#3日{#3}
   \def\xYearElement#1{\expandafter\YearElement\the#1}
   \def\xMonthElement#1{\expandafter\MonthElement\the#1}
   \def\xDayElement#1{\expandafter\DayElement\the#1}

当然ながら, 文字コードが一致していないと駄目です. はい.

入力された月の日数を\tempdayカウンタに出力

  • 閏年は 2 月が 29 日になる. それ以外は 28 日
  • 7月以前(< 8) は, 奇数月が31日, 偶数月が30日
  • 8月以降は, 奇数月が30日, 偶数月が31日

という塩梅で.

# source: latex
   \newcount\tempday
   \def\monthday#1{
     \tempday=0
     \ifnum#1=2
       \ifnum\totalday>365
         \tempday=29\relax
       \else
         \tempday=28\relax
       \fi
     \else
       \ifnum#1<8
          \ifodd#1
            \tempday=31\relax
          \else
            \tempday=30\relax
          \fi
       \else
          \ifodd#1
            \tempday=30\relax
          \else
            \tempday=31\relax
          \fi
       \fi
     \fi
   }

入力された月からその月の前月までの経過日数を\TotalElapseDaysに出力

4月始まり, 翌年3月締なので, 1月から3月を13月から15月にして \loop する

# source: latex
   \newcount\tempmonth
   \newcount\TotalElapseDays
   \def\countTotalElapseDays#1{
     \tempday=0 \TotalElapseDays=0 \tempmonth=#1\relax
     \monthday\tempmonth
     \advance \TotalElapseDays by - \tempday
     \ifnum\tempmonth<4
       \advance\tempmonth by 12
     \fi
     \loop
        \ifnum4<\tempmonth
         \ifnum\tempmonth>12
            \ifnum\tempmonth=13\monthday1\fi
            \ifnum\tempmonth=14\monthday2\fi
            \ifnum\tempmonth=15\monthday3\fi
          \else
            \monthday\tempmonth
          \fi
          \advance\TotalElapseDays by \tempday
          \advance\tempmonth by - 1
     \repeat
   }

入力された二つの月日から期間を計算して\Periodに出力

入力は{開始月日}{終了月日}といった塩梅

# source: latex
   \newcount\Period
   \newcount\tempcounter
   \def\calcPeriod#1#2{
     \Period=0 \tempcounter=0
     \tempcounter=\xMonthElement#2 \relax
     \countTotalElapseDays{\tempcounter}
     \Period=\TotalElapseDays
     \advance\Period by \xDayElement#2 \relax
     \tempcounter=\xMonthElement#1 \relax
     \countTotalElapseDays{\tempcounter}
     \advance\Period by - \TotalEpalseDays
     \advance\Period by - \xDayElement#1 \relax
     \advance\Pediod by 1  % 植木
   }

うーん

とりあえずやりたかったことはできた訳ですが, なんというか. 手元の pTeX

This is pTeX, Version 3.1415926-p3.3 (utf8.euc) (TeX Live 2012/Debian)
 restricted \write18 enabled.

と pLaTeX

This is e-pTeX, Version 3.1415926-p3.3-110825-2.4 (utf8.euc) (TeX Live 2012/Debian)
 restricted \write18 enabled.

ではちゃんと動きましたが.

毎度ながら ad hoc.

どなたか \TeX で修正ユリウス通日とか計算するマクロとか もってらっしゃいませんかね?

(2013/03/13 微修正)

本日のツッコミ(全3件) [ツッコミを入れる]
_ ujimushi at スラドJ (2013/03/14 01:22)

pgfという強大なグラフィックパッケージの中に<br> \pgfcalendardatetojulian{<date>}{<counter>}<br>というものがあったような気がします。マクロ使いではないので1時間ぐらい苦しみましたが<br> \newcount\mycounter<br> \pgfcalendardatetojulian{2013-03-13}{\mycounter}<br>とかして<br> \the\mycounter<br>とかで表示できました。<br>\pgfcalendarjuliantodate{2456365}{\myyear}{\mymonth}{\myday}<br>とかで逆変換もできて便利そうです。

_ うわばみ (2013/03/14 02:08)

pgf って、plain Tex で動くんでしたっけ?

_ うわばみ (2013/03/14 02:18)

追伸。<br>ついでに言うと pgf 持ってない古い TeX の人々のことも考える必要があったので、<br>pgfcalendar の存在は知っていたけれど、はなから考えてませんでした。<br>いまとなってはそっち見た方が良かったのかもしれませんね。


連絡先など
最近の日記
  • 2024/12/05
    • 1. 11月末〜12月の出張三昧がようやく一段落
    • 2. サイトの scss を Dart Sass v3.5 に対応
  • 2024/10/09
    • 1. Mastodon でのメール通知, というか Exim4 と Apparmor
  • 2024/06/19
    • 1. WSL2 での gpg-agent, ssh-agent
  • 2024/06/18
    • 1. WSL で Windows 側のフォントを利用する
  • 2024/06/17
    • 1. WSLとWindowsの時刻同期
一覧
2006|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|02|03|04|08|09|10|11|12|
2013|01|02|03|04|05|06|08|09|10|11|12|
2014|01|02|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|09|10|
2016|02|03|
2017|01|02|03|05|06|07|09|11|12|
2018|03|06|07|10|11|12|
2019|01|02|03|04|05|07|10|12|
2020|01|02|03|04|05|08|09|10|11|12|
2021|01|02|03|05|06|07|08|09|11|12|
2022|01|02|03|04|05|06|08|10|11|12|
2023|02|03|04|06|08|09|11|12|
2024|01|02|03|04|05|06|10|12|
Back to Top ▲