月の黄経、黄緯、および地心距離を計算する関数。

こちらについても、資料のデータをそのまま利用しただけなので、意味は理解していない。

<関数名>
  lunarPos —- 月の黄経、黄緯、および地心距離を計算する

<形式>
  long lunarPos(double *lng, double *lat, long j, double d);

<引数>
  lng (出力)黄経(単位、度)
  lat (出力)黄緯(単位、度)
  j  (入力)世界標準時から換算したユリウス日の整数部分
  d  (入力)世界標準時から換算したユリウス日の小数部分

<関数値>
  地心距離(月・太陽中心間の距離)(単位、キロ・メートル)

<注意事項>
  関数 ut2jd()世界標準時からユリウス日への換算)が必要。
  また標準数学ライブラリ cos() も必要。

用例
  double lng, lat;
  lunarPos(&lng, &lat, 2450266L. 0.5);

<関数本体>
  lunarPos.c

<説明>
  ある時刻の月の黄経・黄緯および地球までの距離を計算する。
  太陽と月の黄経を知ると、新月・満月・上弦・下弦の日時を計算できる。これらは月の黄経と太陽の黄経の差がそれぞれ0度、180度、90度、 270度になる瞬間だから。また、新月時に月の黄緯が0に近い値であれば日食となり、満月時に同様に近い値であれば月食となる。
  なお、日本時間JSTを世界標準時UTに直すには、UT = JST – 9 で計算すればよい。

太陽の黄経、地心距離を計算する関数。

正直にいって、関数が正しいかどうか、よく判らない。ここまで、天文学の知識は持ち合わせていないから。ニュートン力学の凄さを体験できるのは確かのようだ。日食や月食の発生時刻まで計算できるんだから、100年前だったら、神様と呼ばれたに違いない。が、コンピュータはまだ発明されてなかったので、判ってても結局凡人でしかならなかったかも。

<関数名>
  solarPos —- 太陽の黄経、地心距離の計算

<形式>
  long solarPos(double *lng, long j, double d);

<引数>
  lng (出力)黄経(単位、度)
  j (入力)世界標準時から換算したユリウス日の整数部分
  d (入力)世界標準時から換算したユリウス日の小数部分

<関数値>
  地心距離(地球・太陽中心間の距離)(単位、キロ・メートル)

<注意事項>
  関数 ut2jd()世界標準時からユリウス日への換算)が必要。
  また、標準数学ライブラリ cos() も必要。

用例
  double lng;
  solarPos(&lng, 12450266L, 0.0);

<関数本体>
  solarPos.c

<説明>
  地球から観察すると、太陽は恒星の間の、定まった道の上を動いている。太陽の通る道を黄道という。したがって、太陽の黄緯はほぼ 0。また、黄経の 0 度とは春分点に太陽のいるところ。
  いま使われているグレゴリオ暦では、毎年2月4日立春は黄経315度、 3月21日春分は 0 度、6月22日夏至は90度、8月8日立秋は135度、9月24日秋分は180度、12月22日冬至は270度に太陽が位置するらしい。
  本関数を使うと、ある時刻の太陽の黄経および地球までの距離がわかる。
  なお、日本時間JSTを世界標準時UTに直すには、UT = JST – 9 で計算すればよい。

ある日付に対し、n日後の日付を算出する関数。
nの値をマイナスにすれば、n日前の日付になる。

例えば、2004/8/10 から 5日後の日付は 2004/8/15、といった具合。

<関数名>
  dayAdd —- n日後の日付を算出する

<形式>
  void dayAdd(int *year2, int *month2, int *day2, int year1, int month1, int day1, int n);

<引数>
  year2, month2, day2 (出力)n日後の日付。西暦年月日。
  year1, month1, day1 (入力)基準となる日付。西暦年月日。
  n (入力)n日後。マイナス値にすれば、n日前になる。

<関数値>
  なし。

<注意事項>
  引数として渡された日付の実在性チェックはしない。
  関数 ut2jd()ユリウス日への換算)が必要。
  関数 jd2ut()ユリウス日からの換算)が必要。

用例
  int year, month, day;
  dayAdd(&year, &month, &day, 2004, 8, 1, 11);

<関数本体>
  dayAdd.c

<説明>
  内部では、基準日をまずユリウス日に換算してから、nの値を足し、最後に西暦年月日に戻す。そんな処理を行う。

前後異なる2つの日付に対し、間の離れた日数(差)を算出する関数。

例えば、2004/8/10 から 2004/8/15 まで の日数(差)は 5日、といった具合。

前後関係はが逆になっていれば、マイナスの結果になる。
例えば、2004/8/15 から 2004/8/10 まで の日数は -5日、との計算結果。

<関数名>
  dayDiff —- 2つの日付の間の日数を算出する

<形式>
  int dayDiff(int year1, int month1, int day1, int year2, int month2, int day2);

<引数>
  year1, month1, day1 前の日付。西暦年月日。
  year2, month2, day2 後の日付。西暦年月日。

<関数値>
  日数。マイナスの値であれば、日付の前後関係が逆になっていることを示す。

<注意事項>
  引数として渡された日付の実在性チェックはしない。
  関数 ut2jd()ユリウス日への換算)が必要。

用例
  dayDiff(2003, 8, 1, 2004, 9, 11);

<関数本体>
  dayDiff.c

<説明>
  内部では、2つの日付をそれぞれ、ユリウス日に換算してから、差の算出を行う。

今度は逆の、ユリウス日を世界標準時に換算する関数。

<関数名>
  jd2ut —- ユリウス日を世界標準時に換算

<形式>
  void jd2ut(int *year, int *month, int *day, int *hour, int *min, int *sec, long j, double d);

<引数>
  year, month, day (出力)西暦年月日
  hour (出力)時 (0 〜 23)
  min (出力)分 (0 〜 59)
  sec (出力)秒 (0 〜 59)
  j (入力)ユリウス日の整数部分
  d (入力)ユリウス日の小数部分

<関数値>
  なし

用例
  int year, month, day, hour, min, sec;
  jd2ut(&year, &month, &day, &hour, &min, &sec, 2448422L, 0.5);

<関数本体>
  jd2ut.c

<説明>
  ユリウス日の起算日紀元前4713年1月1日はユリウス暦による日付で、ユリウス暦は紀元前46年にユリウス・カエサルが採用したもの。ユリウス暦は1582年10月4日まで使われ、その翌日はグレゴリオ暦の同年10月15日だった。

あまり聞かない、ユリウス日に関する関数。天文学等、専門家の間では当たり前のように使っているようだが。

詳しいことについては、ここ をみてください。

<関数名>
  ut2jd —- 世界標準時をユリウス日に換算

<形式>
  long ut2jd(double *d, int year, int month, int day, int hour, int min, int sec);

<引数>
  d (出力)1日の時間を 1 としたときの正午からの時間。ユリウス日の小数値。
  year, month, day (入力)西暦年月日
  hour (入力)時 (0 〜 23)
  min (入力)分 (0 〜 59)
  sec (入力)秒 (0 〜 59)

<関数値>
  ユリウス日の値(の整数値)

<注意事項>
  引数として渡される西暦年月日が実在するかどうか については、本関数内ではチェックしない。
  ユリウス日の整数値は関数値から、小数値は第1引数から得られる。

用例
  double d;
  ut2jd(&d, 1996, 2, 29, 12, 0, 0);

<関数本体>
  ut2jd.c

<説明>
  日常生活で時刻といえば、年・月・日・時・分・秒を使っている。しかし計算には60進法、月の大小、閏年か平年、といったものが混在している。天文学の世界では、ある決められた起算日から日付を積算していくユリウス日(ユリウス通日)という非常に便利な時の尺度がある。
  そのユリウス日の0.0日は紀元前4713年(-4712年)1月1日の正午で、翌日の正午がユリウス日1.0日である。1991年6月15日世界標準時0時のユリウス日は2448422.5日になる。
  なお、日本時間(Japanese Standard Time; JST)は世界標準時より、9時間進んでいる。

大の月、小の月、つまりたとえば、3月は31日あるのに対し、4月は30日しかない。各月の日数、あなたなら、判ってらしゃるよね。

周りに聞いても、なかなか覚えてないひとが多いみたい。小さい頃、自分がよく教わっていたのに。

上の写真の意味はお分かりですか。
左手でも、右手でも、また、左端から数えても、右端から数えても、全く同じだが、山は大の月、谷は小の月(あるいは2月)を示すのだ。

たとえば、写真の通り、左手の右端から数えていこう。1月、2月、…、7月、と数えていき、左端の山に止まる。つぎの8月はもう1回、左端の山を使う。8月、9月、…、12月。どう? 大の月、小の月、これで生涯忘れないでしょ。ひとによっては、8月はもう片方の握り拳を使うらしいが、原理は皆同じ。

<関数名>
daysOfMonth —- 西暦年と月から、その月の日数を算出

<形式>
int daysOfMonth(int year, int month);

<引数>
year, month 西暦年月

<関数値>
その月の日数。たとえば、1月であれば31、4月であれば30。

<注意事項>
閏年にも対応している
引数の月の値が1〜12以外であれば、1月とみなす。

用例
daysOfMonth(2004, 2);

<関数本体>
daysOfMonth.c

<説明>
閏年の判定法が判れば、あとは簡単に理解できるはず。

閏年かどうか、常識問題として、あなたは判ってらしゃる?

4年一回、ということのようだが、正確には違う。世の中、天才プログラマと呼ばれた人たちでさえ、良く間違う。といっても、プログラマって案外常識のないひとが多い。

2000年問題やら、エクセルのバグやら、閏年にまつわるエピソードがいくらでもありそう。

さて、正しい知識とはこんなもの。下記の条件のうち、いずれかを満たす西暦年が閏年となる。
  条件1: 4で割り切れて100で割り切れない年
  条件2: 400で割り切れる年

早い話、1900, 2100年は平年だが、その間のほかの年については、4年おきと理解して正しい。いま生きているわれわれが生存している間、4年1回と思ってまず間違いない。

<関数名>
  leapYear —- 西暦年について閏年かどうかを判定

<形式>
  int leapYear(int year);

<引数>
  year 西暦年

<関数値>
  閏年であれば 1、平年(非閏年)であれば 0。

用例
  leapYear(2004);

<関数本体>
  leapYear.c

<説明>
  4の倍数でしかも100の倍数でない年、または400の倍数の年は閏年。
  1900年や2100は閏年ではない! 曜日までも自動表示と豪語するオートマチック機械時計は世界中数多くあるけど、1900年や2100年の曜日を正しく表示できるものはあるのだろうか。壊れてて、100%の確率で迎えられそうもない2100年のために、そのような時計をつくるのだろうか。とっても知りたい。
  閏年はなぜ必要なのだろうか。天文学によれば、地球が太陽を1周するのに、
    365.2422日 = 365日5時間48分46秒
  かかる。1年を365日とすると4年に約1日ずれてくる。閏年を作らねばならないわけだ。

Bフレッツの開通を記念して、数年前までに集めた、C言語プログラム(関数)を順次公開するね。

既にどこかで、多くの方々に見られていたものかもしれない。
ただ、サポート等は一切できないと思う。ご質問にお答えすることもままならないかもしれない。ご容赦を。

さて、1本目、曜日を正しく計算してくれる関数の公開。

染色体の異常に起因するダウン症患者、知的発達が遅れるといいながら、西暦と月日を尋ねれば瞬時に曜日を言い当ててしまう、ということが簡単にできるらしい。

しかし、一般のわれわれには、曜日の計算はなかなかできない。が、ツェラー公式 が判れば、スマートに計算できるはず。

<関数名>
  dayOfWeek —- 西暦年月日からその曜日を算出

<形式>
  int dayOfWeek(int year, int month, int day);

<引数>
  year, month, day 西暦年月日

<関数値>
  各曜日に対応する 0 〜 6 の値
     0: 日、1: 月、2: 火、3: 水、4: 木、5: 金、6: 土

<注意事項>
  引数として渡される西暦年月日が実在するかどうか については、本関数内ではチェックしない。
  1582年10月15日以降の日についてのみ正しく算出する。

用例
  dayOfWeek(2004, 8, 14);

<関数本体>
  dayOfWeek.c

<説明>
  ツェラー (Zeller) の公式 による計算法。
  現在使われているグレゴリオ暦の初日は1582年10月15日(金曜)である。本関数はその日以降の曜日を正しく算出。
  ちなみに、1582年10月15日(金曜)の前日はなんと、ユリウス暦1582年10月4日(木曜)。時間の空白があったわけだね(笑)。また、曜日だけは連続していて、休むことの大切さ、そこにもしみじみ感じる。

● もともとの話については、 ここ を参照されたい。

DDNSサーバに対する、IP 更新プログラム。
ベースとなったのが、お世話になっている ipServer.net サイト内の Perl スクリプト

<使用環境>
  OS Linus Fedora Core / Centos
  Perl  Ver 5.8.1以上
  DDNSサーバ www.ipServer.net

<使用するディレクトリ、およびファイル>
  ディレクトリ /usr/local/ddns/
  プログラム本体 ddns.pl
  データファイル ddns.dat 現在使用中のIP及び前回更新時刻の記録データ
  履歴ファイル ddns.log いままでの更新履歴
  データファイル及び履歴ファイルはプログラムが必要に応じて自動作成する。

<プログラム本体>
  Perl スクリプト ddns.pl
  注:アカウント名、ドメイン名、パスワードの3項目はご自分の環境に合せること!
  ちなみに、データファイルおよび履歴ファイルの中身はこちら。
  データファイル ddns.dat
  履歴ファイル ddns.log

<使い方>
  cron で Perl スクリプト ddns.pl を、10分間隔で走らせるといいだろう。必要でなければ、DDNSサーバに対する更新は実際、やらないのだ。
  ただし、日付が変わると強制更新を必ずやることになっている。ときたま声かけないと、DDNSサーバがこちらの存在を忘れるかもしれないから (というのは冗談)。
  履歴ファイル ddns.log の各行に書かれている言葉は、Updateが不可欠な更新; Dailyがただの生存連絡を意味する。

IP更新プログラムの良し悪しはサーバとしての信頼性を大きく左右するので、ご利用の際に十分吟味して欲しい。