掲示板

サンデープログラマーの悩み

世の中には真剣に悩まなくても全く困らないこともたくさんありますが、ちゃんとした教育を受けずにプログラミングの楽しみを知ってしまった故につまらないことに悩むことがままあります

今日は皆さんならどうやって解決するのかに興味があったのでお題を出しますので解決方法を考えてみてみてください

たぶん正解はいくつもあると思いますのでいくつ回答しても良いです

ただし回答には計算方法や前提条件、回答実例も記載してください
日付時間は日本標準時を使います


お題「今日の3か月後は何日?」

プログラミングのお話ですので今日が〇月〇日なら何日?は△月△日と一発で決まる回答を期待します


面白い回答にはチップを差し上げます
なるほど!と感心した回答を見かけたら皆さんもチップをはずんで下さいね


136 件のコメント
1 - 36 / 136
プログラミングは面白いですね。

PCだとエクセルでは日付は整数ですので、日数の加減算の計算は表示を変えるだけで出来ますね。
使用される言語がPHPならば
echo date("Y/m/d", strtotime('+3 month'));
で3ヶ月後の日付が得られます。
今日だと、
2019/03/01
ですね。来年の2月は28日までなので。
VBA派です。
Sub smp()
Dim TGD As Date
TGD = DateSerial(Year(Now), Month(Now) + 3, Day(Now))
MsgBox TGD
End Sub
前提条件 Z80 アセンブラ →日付関数をつかわずに対処する。
方法 12×31=372のテーブルを作ってあらかじめ計算しておく
 →旧世代でも「一発で」回答を出せるようにする。

3か月後=120日で割り切ってもいいか?
3か月後が月を跨いでいいのか?
閏年の対処はするか?(ただし今回は年は与えられない)
など、ある意味「どうでもいいかもしれない」迷路に私落ちた人は
例外処理のループから私は抜けらませんでした。

これにとらわれていては「面白い回答」は出せないので以下を追加します。

 処理ステップが1000を超えたら「リレミト」が唱えられる
 MPを加算する。

8bitではこの程度が限界のようで・・・・(^^;
問題の趣旨は何でしょうか。以下想像

【1】2月は28日までしかないが、どう処理するかを知りたい
3ヵ月後は来年の2月で、2019年の場合28日までしかない。
さて、2月28日とするか、3月1日とするか、どっちかという事?
及び、うるう年の場合どう計算するかのロジックを知りたい?

【2】月を足すアルゴリズムを知りたい
月だけ足し算するのか、あるいは1ヵ月を○日として、例えば(○×3)日を足す、という計算にするのか、の足し算の仕方を知りたい?

【3】年が繰り上がるアルゴリズムを知りたい
1年は12か月で繰り上がるので、11月+3ヵ月=14月、その後の年の繰り上がりする為の計算方法を知りたい?

まあ、多分上記の全部を知りたいのでしょうけどね~(笑)
ちなみに、ExcelのEDATE関数で3ヵ月後を計算した結果は、
「2019年2月28日」
です(^^♪

a1424865035128_1_.png

ちなみに、うるう年かどうかの判定方法。
みなさんの書き込みを読みまして。

存在しない3ヶ月後の日付についての話ですね。(たぶん)
(繰上げるのか、存在する手前の日にするのか)

私の思うポイントはその3ヶ月後の日付の存在意義
有効期限が3ヶ月であるなら手前の日が重要。
3ヶ月経過が条件の場合は翌日が重要

ここを決めるのはプログラムではありませんが、ここが一番重要という話かと
かくいちさんの話のように、もしも「経過後」か「有効期限」かで日付が変わるのだとしたら、2月の月末にかかわらず日が変わってしまわないでしょうか。

例えば、2018年11月5日の3ヵ月後は、
・有効期限3ヵ月なら、2019年2月4日
・3ヵ月経過後なら、2019年2月5日
と言う風に。

それ以外にも、今日の午前0時から3ヵ月なのか、今日の24時からなのか、によって3ヵ月後の意味が変わって来る場合もあり得ますね。
今日1日を、3ヵ月の中に含むのか含まないのか、いつを起算にするのか、という事です。

その辺り全部曖昧な質問なので難しいですね。

でも一般的な日常会話で「○ヵ月後」と言うと、EXCEL関数の計算結果の通り月だけ月数分シフトした物になると思います。
そして、日はそのまま、もしくは日が少ない月の場合は、その月の末日に繰り上げるのが、日常会話での感覚だと思います。
(契約事など、日常会話以外では異なった計算方法があると思いますが)
年齢の計算なども、ややこしいですね。
一般的な日常会話では、誕生日のその日になったら、次の満年齢に繰り上がると考えますよね。
例えば、2018年1月1日生まれの赤ちゃんは、2019年1月1日に1歳になったおめでとう!と言います。

ところが、お役所等での計算では、誕生日の前日に次の年齢になる事が多いですね(多分)。
例えば、2018年1月1日生まれの赤ちゃんは、2018年12月31日に1歳になり、2019年1月1日には、満1歳+1日、となります。

つまり、2018年1月1日生まれの赤ちゃんは、午前0時0分から起算し、2018年12月31日24時時点で満1歳になったと考えるんですね。
誕生日の計算について載っていました。
http://www.mext.go.jp/a_menu/shotou/shugaku/detail/1309966.htm

引用:「年齢の計算については、年齢計算ニ関スル法律と民法第143条によりその考え方が示されており、それによれば、人は誕生日の前日が終了する時(午後12時)に年を一つとる(満年齢に達する)、とされています。」

やっぱり法律で、前日の終わる時点で満年齢に達する、と決まっているのですね。
しゅう さん、f uckerさん、達のコードのように、日付の関数を使った場合、次のような結果になるようですね。
ExcelのDATE関数を使った場合も、下記結果となります。

引数 → 結果
2019年2月29日→2019年3月1日
2019年2月30日→2019年3月2日
2019年2月31日→2019年3月3日
2018年14月29日→2019年3月1日
2018年14月30日→2019年3月2日
2018年14月31日→2019年3月3日

これらの結果は、「○○ヵ月後」と一般に言う結果と異なりますよね。
私の感覚ではこうなって欲しい。
2019年2月29日→2019年2月28日
2019年2月30日→2019年2月28日
2019年2月31日→2019年2月28日
2018年14月29日→2019年2月28日
2018年14月30日→2019年2月28日
2018年14月31日→2019年2月28日
Siriにまんま話しかけたら答えてくれた(プログラミングになっていない:汗)。
流しのモバイル人さん

おおーSiri賢い!ちゃんと「2019年2月28日」でした。

OKグーグルに聞いてみたら「すみません、お役に立てそうにありません」ですと。ダメですね。1日後や2日後は答えてくれましたが、1週間後や1ヵ月後は理解してくれませんでした。

今の所、一発OKはSiriとExcelのEDATE関数だけですね。
absente
absenteさん・投稿者
Gマスター
>マイネ神さん
>西向くサムライじゃ!
これ、今の若い人でもポピュラーな言葉なんでしょうかね
日本人はうまいこと言うもんですね
absente
absenteさん・投稿者
Gマスター
>hisaさん
EXCELの関数を自分で作るってことなんですよ
absente
absenteさん・投稿者
Gマスター
>しゅうさん
>echo date("Y/m/d", strtotime('+3 month'));
+3とした根拠は何でしょう?

>〇uckerさん
TGD = DateSerial(Year(Now), Month(Now) + 3, Day(Now))
しゅうさんと同じ質問です+3とした根拠を示しましょう

なぜか
コメントに以下に該当する表現が含まれているため、投稿できません。
・卑猥な表現
・差別用語
・暴力的な表現
・紹介URLの記載
と叱られました
absente
absenteさん・投稿者
Gマスター
>フォースさん
>方法 12×31=372のテーブルを作ってあらかじめ計算しておく
テーブルはいつの分まで用意するのでしょう?

>3か月後=120日で割り切ってもいいか?
割り切るという意味をもう少し詳しく説明して頂けると思い白いと思います

>閏年の対処はするか?(ただし今回は年は与えられない)
これはお題のミスでした
日付の問題にはうるう年の処理が必須でしたね

>赤いカローラバンさん
>仕事がプログラムな方は避けたいお題です(笑)
全くその通りだと思います

>さとさん
>問題の趣旨は何でしょうか。
答えを知りたいわけではありません
皆さんはどうやって悩むのかを知りたかったのです

え?悩まない?

>かくいちさん
>私の思うポイントはその3ヶ月後の日付の存在意義
そうなんです、ここなんですよww

>流しのモバイル人さん
>Siriにまんま話しかけたら答えてくれた(プログラミングになっていない:汗)。
方法がユニークで良いと思いますw


重大ヒントです
お題はある日の3か月後ですが、「3か月」どういう値なのかを考える問題なのです
マイネ神様のお言葉が身に凍みますね
absente
absenteさん・投稿者
Gマスター
個人的にはさとさんの悩みっぷりが一番好きですw
absente
absenteさん・投稿者
Gマスター
面白いと思ってもチップが送れないのは残念です
エアチップをどうぞ
absente さん

プログラムの組み方の話、ではなくて期間の数え方について(皆がどう考えているかを)知りたい、という事でしょうか?

今検索してみたら、民法で定められているそうです。https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1480537619

>民法 第143条第2項の規定により、
>起算日(1月31日)の3か月後に応当する日(4月31日)がないので、最後の月の末日(4月30日)が有効期間の満了日になります。

という訳で、答えは、「2019年2月28日」ですよね?
感想は「やっぱり」「それ以外ないでしょ」という所(笑)。

absente さんの意図がわからなかったのと、「2019年3月1日」と答えている人が複数居てビックリしたのと、が大半の興味です。
プログラムのアルゴリズムを考えていたのですが、関係無かった( ;∀;)
--------

民法

第六章 期間の計算

(期間の計算の通則)
第百三十八条 期間の計算方法は、法令若しくは裁判上の命令に特別の定めがある場合又は法律行為に別段の定めがある場合を除き、この章の規定に従う。

(期間の起算)
第百三十九条 時間によって期間を定めたときは、その期間は、即時から起算する。

第百四十条 日、週、月又は年によって期間を定めたときは、期間の初日は、算入しない。ただし、その期間が午前零時から始まるときは、この限りでない。

(期間の満了)
第百四十一条 前条の場合には、期間は、その末日の終了をもって満了する。

第百四十二条 期間の末日が日曜日、国民の祝日に関する法律 (昭和二十三年法律第百七十八号)に規定する休日その他の休日に当たるときは、その日に取引をしない慣習がある場合に限り、期間は、その翌日に満了する。

(暦による期間の計算)
第百四十三条 週、月又は年によって期間を定めたときは、その期間は、暦に従って計算する。
2 週、月又は年の初めから期間を起算しないときは、その期間は、最後の週、月又は年においてその起算日に応当する日の前日に満了する。ただし、月又は年によって期間を定めた場合において、最後の月に応当する日がないときは、その月の末日に満了する。

--------
だそうです。引用の引用ですが。
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1480537619
■起算日=2018年11月30日(期間の初日29日は含めない)

根拠:「日、週、月又は年によって期間を定めたときは、期間の初日は、算入しない。ただし、その期間が午前零時から始まるときは、この限りでない。」

■満了日=2019年2月28日(最後の月=2月、起算日相当の前日=29日だが相当日無しでその月の最終日=28日)

根拠:「週、月又は年の初めから期間を起算しないときは、その期間は、最後の週、月又は年においてその起算日に応当する日の前日に満了する。」
「ただし、月又は年によって期間を定めた場合において、最後の月に応当する日がないときは、その月の末日に満了する。 」
>absenteさん
>重大ヒントです
>お題はある日の3か月後ですが、「3か月」どういう値なのかを考える問題なのです

すみません、意味がわかりません( ;∀;)
『「3か月」どういう値』って何?
「リレミト」があるなら・・・「ぱるぷんて」もあるんじゃ。。。
例えば定期券の場合…
(うるう年でない場合)
11月28日にその日から使える3ヵ月定期を買う →期限2月27日
11月29日にその日から使える3ヵ月定期を買う →期限2月28日
11月30日にその日から使える3ヵ月定期を買う →期限2月28日
12月1日にその日から使える3ヵ月定期を買う →期限2月28日
12月2日にその日から使える3ヵ月定期を買う →期限3月1日

となりますね。
「その日から使える」と書いたのは、その期間が午前零時から始まる為、期間の初日を算入する為です。
満了日は、3ヵ月後の相当日の前日、相当日が無い場合はその月の末日です。
absente
absenteさん・投稿者
Gマスター
>さとさん
3か月後という言葉と数値をどうとらえるかです

法律で定めていたことは知りませんでしたが、それほど微妙な表現だと思いませんか?
おそらくその法律の法文はサンデープログラマー流に解釈すると仕様書となります

なにを解としてプログラムするかなので、場合によっては法律に従ってプログラムするというのが一つの解になるかもしれません
さて、この場合どうプログラムを記述しましょうか?

プログラミングとは言語をプログラム言語に翻訳することも含みます
アルゴリズムを考える工程もそう言えるのだと思います

サンデープログラマーは生産性を考慮しないのでもう少し悩みましょうw
absente
absenteさん・投稿者
Gマスター
>さとさん
>例えば定期券の場合…
(うるう年でない場合)

これが前提条件とします
で、計算結果がこれです
仕様に従った計算結果になりますね

>11月28日にその日から使える3ヵ月定期を買う →期限2月27日
> 11月29日にその日から使える3ヵ月定期を買う →期限2月28日
>11月30日にその日から使える3ヵ月定期を買う →期限2月28日
>12月1日にその日から使える3ヵ月定期を買う →期限2月28日
>12月2日にその日から使える3ヵ月定期を買う →期限3月1日

仕様がしっかりしてたらあまり悩まないんですよw
お題には仕様が書かれていません、というか意図的に書きませんでした
なので自分で仕様を作って先に進めてほしかったのです
absente さん
まさに、この民法が仕様書ですね。

「どうプログラムするか」ですが…全部自分で計算する場合:
普通は、年と日はそのままで、月だけ加算すればOK。
ただし例外があって、12月より大きい月になったら翌年の月へ繰り上げる。
もう一つの例外は、該当日がその月に無い場合(西向く侍)、その月の末日にする(閏年も考慮)。
それだけですね。
Excelなら、「=EDATE(TODAY(),3)」だけで求まります。

ただし、起算日も期間に含む場合(午前0時から開始の場合)は、前日を求めないといけないのですが、その計算を自前でするとなると、少々面倒。
Excelなら、「=EDATE(TODAY()-1,3)」だけで求まりますが。
absente
absenteさん・投稿者
Gマスター
>さとさん
なんかプログラミングっぽくなってきましたねw
これなら例外処理も含めてすぐ記述を始められそうです

基本は計算式を使って結果を求めるスタイルが好きなのですが、最初の段階で同じように紙に書きだして規則性を確認することも良くやります
ちゃんとしたプログラマーはフローチャートを書くと思いますがw

横着なときは途中結果までをEXCELで行い、その先をプログラムするなんてこともしたりします

それにしてもEXCEL最強ですね
すみません、ちょっと書き直しです。
下は、その日の午前0時から開始せず、その日の途中から期間開始する場合の仕様です。
(定期券のように午前0時開始の場合、前日を求める計算を自分で書くとなると超面倒)

---------
本日Y年M月D日 のaヵ月後を、year年month月day日とする

//月の計算
a÷12=bあまりc  //「aヵ月」を「b年cヵ月」に単位変換
M+c→d       //cヵ月後の月を計算

d>12の場合、d-12→month  //13月以上は月を再計算
上記以外の場合、d→month  //12月以下は月そのまま


//年の計算
Y+b→e          //今年のb年後
d>12の場合、e+1→year  //13月以上は年を繰り上げる
上記以外の場合、e→year  //12月以下は年を繰り上げない


//日の計算
month=4または6または9または11かつD=31の場合、30→day //30日迄の月の31日は30日に繰り上げ
上記以外で、month≠2またはD≦28の場合、D→day     //2月の月末以外は日そのまま
上記以外の場合、下の計算へ

//うるう年かどうか (うるう年の時f=1)
year÷4≠0の場合、0→f        //4で割り切れない場合平年
上記以外で、year÷100≠0の場合、1→f //100で割り切れない場合うるう年
上記以外で、year÷400≠0の場合、0→f //400で割り切れる場合平年
上記以外、1→f            //400で割り切れない場合うるう年

f=1の場合、29→day          //うるう年の場合月末は29日
上記以外の場合、28→day       //平年の場合月末は28日

//結果
year年month月day日
absente
absenteさん・投稿者
Gマスター
わずかの時間で素晴らしいですね
さとさん、もしかしてプログラマー?
absente
absenteさん・投稿者
Gマスター
すいません、ちっちゃな突込みを一つ
西向く侍ではなく、西向く士です
侍→士、そうでした!(笑)
プログラマーじゃないです。昼間からちょこちょこ書いてたので。
absente
absenteさん・投稿者
Gマスター
じゃあ、プロのつかないグラマーでしょう

EXCELに無料のVBAついてますから遊んでみたら良いと思います
コメントするには、ログインまたはメンバー登録(無料)が必要です。