ツェラーの公式を用いて、日付(年月日)から曜日を算出する方法があります。
例えばY年M月D日の曜日は、下式で求められます。
(Y + Y/4 - Y/100 + Y/400 + (13*M + 8)/5 + D) % 7
*但し、1月・2月は、前年の13月・14月とする。
*答えは0=日曜~6=土曜
これを応用して(別に応用しなくても良いんですが・・・)日付と曜日から、1週間前の同一曜日の日付を求めるプログラムを考えております。
例)
入力:2005年9月21日、水曜日
出力(解):2005年9月14日
この例は非常に簡単に求められますが、完全汎用型のプログラムを考えております。
しかし、なかなか良い知恵が出ません!!
どなたかご教示頂けると助かります。
よろしくお願いします。
No.1ベストアンサー
- 回答日時:
yyyy年mm月dd日の 1週間前の日を求める, 手抜きな方法:
1. dd から 7 を引く
2. 1 の答が 0以下になったら mm から 1 を引き, (更新後の) その月の日数を dd に足す
3. mm が 0 になったら yyyy から 1 を引き mm を 12 にする
真面目にやると面倒なので, 一旦ユリウス通日にしてから 7 を引いて戻すのがよいかと.
ご回答ありがとうございます。
まず最初に、その方法を考えました。
やはり一番素直で簡素な回答ですよね?
月毎の末日はテーブルに入れておき、参照するようにすれば良いですね。
この方法でも試してみます。
ありがとうございました!
No.4
- 回答日時:
> 完全汎用型のプログラムを考えております。
完全汎用型というのはどんなものを想定していますか?一般的な意味で解釈すると、完全に汎用のものを作ることはかなり難しいと思います。
まず、グレゴリオ暦が採用されたのは(本能寺の変が起きた)1582年からですが、各国によって実際の導入時期はまちまちで、日本では1873年から導入されました。これを反映するには、ロケールに応じてユリウス暦とグレゴリオ暦を切り替えることになりますが、日本のように太陰太陽暦を用いていた国などではエラーにするしかないと思います。
また、曜日の概念が導入されたのは321年のコンスタンティヌス帝時代のローマですが、他の国の導入時期を正確に把握するのは困難です。
さらに、グレゴリオ暦(というより協定世界時)は、未来永劫修正なしで済ませられるほど、精度が高いわけでもありません。何万年後か知りませんが、必ず何らかの補正が必要になることでしょう。しかし、現在の我々には、未来の暦法を知るすべなどありません。
もし、単に最近の年代だけを扱えばよいのであれば、mktimeを使えば簡単にできます。
struct tm t;
t.tm_year = -1900 + 2005;
t.tm_mon = -1 + 9;
t.tm_mday = 21;
t.tm_hour = 0;
t.tm_min = 0;
t.tm_sec = 0;
t.tm_isdst = -1;
t.tm_mday -= 7; /* 1週間前 */
if (mktime(&t) == (time_t)-1)
fputs("エラー\n", stderr);
puts(asctime(&t));
ご回答ありがとうございます。
すいません、完全汎用型というのは大袈裟な表現でした。
その時代まで遡って正常に動くものは考えておりません。
過去100年間程度正常に動くもの、と考えています。
他の方のも参考に、出来るような気がしてきました。
ありがとうございました!
No.3
- 回答日時:
だいたいはNo.1の回答で説明されていますが、困っているのは「3月1日~3月7日の1週間前」だと思います。
この期間は、閏年の関係で「2月末日」が何日かを計算する必要がありますので。
閏年は、
「年を4で割って割り切れる年」かつ ←条件1
「但し、100で割って割り切れる場合は除外」かつ ←条件2
「但し、400で割って割り切れる場合は除外しない」 ←条件3
と言う判定を行って計算します。
ツェラーの公式の
Y + Y/4 - Y/100 + Y/400
の部分が、この判定に相当します。
正しく判定出来たならば、
1896年 閏年 ←条件1に該当
1900年 通常年 ←条件2に該当
1904年 閏年
|
1996年 閏年
2000年 閏年 ←条件3に該当
2004年 閏年
|
2096年 閏年
2100年 通常年
2104年 閏年
と判定される筈ですので、ご自分で書かれた判定プログラムを試してみて下さい。
蛇足ですが、古い「カレンダーICチップ」の中には「年を4で割って割り切れる年が閏年」とだけ計算していて、2つの例外条件を無視しているICチップがあります。
なぜなら、その条件のみで「1901~2099年」の約200年間は正しく動くからです。
コストダウンの為だと思いますが「どうせ2100年が来る前に耐用年数を超して壊れるだろう」と言うのもあったのでしょう。
ご回答ありがとうございます。
閏年の判定方法をご教示頂き、感謝致します。
参考にさせて頂きます。
確かに常識的な期間だけ正常に動けばいいや!と考えますね(^◇^;)
ありがとうございました!
No.2
- 回答日時:
回答と言うよりヒントですが……
まず、大抵の処理系には、「日付・時刻」を管理するクラスがあります。これまた大抵、「日付の連番」と「年月日それぞれの値」が使えますので、
・年月日→連番に変換
・連番になった状態で、7日分をマイナス
・それをさらに、年月日に戻す。
という手があります。
No.1 の形の回答にある、ユリウス通日に戻すのも同じ考え方です。
標準のCのライブラリの範囲では、time.h というヘッダに、一式関数が入っていますので、じっくり眺めれば使えると思います(使ったことはありません・いつも、処理系についているクラスを使っているので)
参考URL:http://wisdom.sakura.ne.jp/programming/c/c60.html
ご回答ありがとうございます。
連番でやる方法もあるんですねー。
全く考えもしませんでした。
面白そうなので、ヒントを参考に考えてみます。
組み込み機器のプログラムなのでライブラリは極めて少なく、
かつコードをスリム化するために使用出来ないのです(>_<)
言葉足らずで申し訳ありませんでした!
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
SQL Serverにおける小数部の0...
-
数値を通貨型に変換して(1000...
-
Request.QueryStringの型について
-
16進数を10進数に変換する方法...
-
36進数
-
特定のセルが空白だったら、そ...
-
i=cells(Rows.Count, 1)とi=cel...
-
VB.NETで DataRow()を利用して...
-
セル色なしの行一括削除
-
Excelで指定した日付から過去の...
-
【Excel VBA】先頭の「0」飛び...
-
ListView 項目の選択/選択解除...
-
【Excel VBA】指定行以降をクリ...
-
ExcelVBAを使って、値...
-
テキストボックスのvalueとtext...
-
値を返さないコード パス
-
array関数で格納した配列の型を...
-
Accessのクエリで、replace関数...
-
VB.NETでコンボボックスの1行目...
-
Excelのセルの色指定をVBAから...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
SQL Serverにおける小数部の0...
-
日付と曜日から、1週間前(7...
-
Request.QueryStringの型について
-
C言語のうるう年に関するプログ...
-
西暦を入力して、うるう年かど...
-
16進数を10進数に変換する方法...
-
和暦から西暦変換(C#)
-
和暦→西暦(有効範囲を考慮)
-
文中の単語にリンクを貼る
-
閏年が何個含まれるか求めるプ...
-
VB2008で西暦を和暦に変換...
-
ユリウス日から和暦(江戸時代...
-
エクセルのカレンダー
-
36進数
-
テキストボックスのvalueとtext...
-
VB.NETで DataRow()を利用して...
-
ExcelVBAを使って、値...
-
i=cells(Rows.Count, 1)とi=cel...
-
特定のセルが空白だったら、そ...
-
Accessのクエリで、replace関数...
おすすめ情報