🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

5回答

922閲覧

日付の計算方法について

kinisinai

総合スコア28

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

1クリップ

投稿2019/11/07 12:53

編集2019/11/09 06:28

PHPにて西暦の計算をしたいと考えています。
外部のプラグインなしで実装したいのですがどうすれば良いかわからず困っています。

イメージとしては
2000年1月と2002年2月があったときに結果として2年1ヶ月というような結果が返ってくるのが理想です。

JavaScriptのMoment.jsなどが検索してきたら出てきたのですが上記にも記載しているように外部プラグインは使用しない方向で考えています。

追記

今回みなさまのコメントを見て自分の甘さを知りました。
今一度自分で仕様を見つめ直し色々試行錯誤して試しています。
後ほどもう一度改めてこちらに質問させていただきます。

追記

PHP

1$t1 = date('Ym', strtotime('2018-12')); 2 3$dayhikizan = intval(date('Ym')) - intval($t1); 4$j = 0; 5$t = 0; 6$wari = floor($dayhikizan / 12); 7for ($i = 0; $i < $wari; $i ++) { 8 if ($i < 11) { 9 $t ++; 10 $itinenika = ($t) . 'か月'; 11 } else {} 12} 13echo $itinenika;

上記のようなものを考えてみたのですが1年以内のものはうまくカウントしてくれるのですが1年以上のものになる時の条件の絞り込み方が分からず詰まっております。ご教授いただければ幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

papinianus

2019/11/07 12:59 編集

もっとたくさんの境界例を出してください。2000.02.29から2002.03.31は2年1ヶ月ですか?2年1ヶ月2日ですか?2000.02.28からならどうですか?2001.04.30の一ヶ月後は5.30ですか?5.31ですか?2000.05.31の一ヶ月後は6.30ですか?
kinisinai

2019/11/07 13:28

すみません。ご指摘ありがとうございます。 今回は◯年◯ヶ月までで◯年◯ヶ月◯日までは求めなくて大丈夫です。 月単位での結果が欲しいです。 その上で12ヶ月を上回った場合は1年2年と増えていくイメージです。
m.ts10806

2019/11/08 00:42

「PHPにおける外部のプラグイン」が何を想定されているかも追記してください。 あと、コメントにも書いてますが、まず、思う通りにやってみてください。何も調べてない試してないのでしたらまず調べるところからです
m.ts10806

2019/11/09 01:45

提示されたコードはそもそもSyntax Errorがでるので仰っている「1年以内」すら計算できていません。
kinisinai

2019/11/09 02:35

すみません。コードの方修正させていただきました。
m.ts10806

2019/11/09 03:02

「条件の絞り込み」ってなんでしょう。 検索の話はどこにもありませんが
m.ts10806

2019/11/09 03:05

>2000年1月1日と2002年2月1日があったときに結果として2年2ヶ月というような結果が返ってくる ここがずっと謎なのです。 何が言いたいかというと最初に指摘した「インプット」です。 「どこからどのように”2000年1月1日”と”2002年2月1日”という情報が受け渡されてきて、”何の結果”で”2年2ヶ月”となるのか」が全く示されていません。 そこが「仕様」です。質問者さんの中でしか思い描かれていないため、見ている人の頭には謎しかありません。謎があると「そこちゃんと決めてから質問してね」くらいしか思えないわけです。 それに提示のコードにはその「インプット」の部分が全く反映されていないため、余計に謎になっています。 「2000年1月1日と2002年2月1日があったときに」という振りなのであればその情報を使うべきです。
m.ts10806

2019/11/09 03:26 編集

↑つまり今のところ「コードは出てきたが答えようがない」状態がずっと続いています。
takepan1973

2019/11/09 06:09

「日」が要件から外れたのであれば、「イメージとしては〜」の文から削ってもらえませんか。 質問文とコードが乖離しすぎていて、余計に混乱します。
kinisinai

2019/11/09 06:27

2000年1月1日と2002年2月1日の2年2ヶ月というのは僕の計算ミスです。すみません。修正します。 日が要件から外れている点も修正します。申し訳ありません
takepan1973

2019/11/09 07:21

自分でも組んでみたんですが、 Kosuke_Shibuyaさんのコードが簡潔ですね。 ご確認を。
kinisinai

2019/11/09 14:22

ありがとうございます。
guest

回答5

0

ベストアンサー

https://www.php.net/manual/ja/class.datetime.php

php

1<?php 2 3$date1 = '2000-01-01'; 4$date2 = '2002-02-01'; 5 6$dt1 = new Datetime($date1); 7$dt2 = new Datetime($date2); 8 9$diff = $dt2->diff($dt1); 10 11$res = sprintf("%d年%dヶ月\n", $diff->y, $diff->m); 12 13echo $res; 14

投稿2019/11/09 06:36

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kinisinai

2019/11/09 14:23

ありがとうございます。 ベストアンサーにさせていただきます。
退会済みユーザー

退会済みユーザー

2019/11/10 03:46

BA以外の回答くれた人に対して、何のリアクションもないの?
guest

0

「2000年1月1日と2002年2月1日があったときに結果として2年2ヶ月というような結果が返ってくるのが理想です。」
もうこの時点で謎仕様ですよね。単純な日付の引き算であれば、
2002/02/01 - 2000/01/01 = 2/01
です。
なぜ2年1ヶ月ではないのか?

2000年1月1日から2000年1月31日までが1ヶ月であって、
2000年1月1日から2000年2月1日は1ヶ月を超えるので切り上げて2ヶ月だ、というのであれば、そういうことを書いてください、ということです。それが仕様です。

投稿2019/11/08 00:28

takepan1973

総合スコア821

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

まず、西暦1年1月1日からの通算日数を求めましょう
また、通算日数から年月日を求めれるようにもしましょう

#ぐぐればその方法は出てきます

それができたら、あとは加算減算でお好きにどうぞという話となります
これが日付計算の基本となりますな

投稿2019/11/07 13:21

y_waiwai

総合スコア88040

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

日付の差分計算のやり方ならネット上に幾らでも転がっていると思います。
ただ、インプットが提示の形式なのかとか諸々詰めなければならない要件が沢山あります。
まずそこをまとめないことには何も進められません。

どうすれば良いかわからず困っています

仕様を確定させてください。


適当サンプルコード (超冗長版)
日数を主にするとこうなる例。

php

1<?php 2$from = '2000年1月'; 3$to= '2001年2月'; 4 5$from_time = strtotime(str_replace('年','/',str_replace('月','/',$from)).'01'); 6$to_time = strtotime(str_replace('年','/',str_replace('月','/',$to)).'01'); 7 8$diff = ($to_time-$from_time); 9$day_diff = $diff/ (60 * 60 * 24); 10echo $day_diff. '日'.PHP_EOL; 11$year_diff = $day_diff/365; 12echo $year_diff.'年'.PHP_EOL; 13 14$yr = floor($year_diff); 15if($yr >= 0){ 16 echo $yr."年"; 17} 18$mr = ($year_diff-$yr)/(1/12); 19if($mr >= 0){ 20 echo ceil($mr)."ヶ月"; 21} 22

結局のところ仕様確定待ち。

最初の方で「もっとパターンを出して」と突っ込まれている通り、
本人も気づいていない仕様の漏れが沢山あるので、もっと考察していく必要があります。
現場でもお客さんが気づいてない漏れとかがあるわけで、そこをヒアリングで詰めて要件定義をしていくわけですが、
ここでは質問者はお客さんではないので、様々なパターンケースを出していって仕様を改定した上で質問をする必要があります。
質問テンプレートの「前提・実現したいこと」の項目は実は質問本文で最も丁寧でしっかり書き込まれている必要があります。

1つのことを実現するためのコードは1つではないですが、
その「1つのこと」が決まっていないので無限の可能性からの中から赤の他人が模索する必要がある質問はとても良い質問とは言えませんし、解決に至らずどんどん時間が過ぎるだけになっていきます。

投稿2019/11/07 13:06

編集2019/11/09 06:58
m.ts10806

総合スコア80875

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kinisinai

2019/11/07 13:13

仕様とはどの程度のことままででしょうか?
hentaiman

2019/11/07 13:26

この程度のプログラムなんだから試しに作ってみて期待しない動作をする点や分からない所や改善したい所をピックアップして質問すれば大体の回答者は問題点を察して回答してくれますよ
m.ts10806

2019/11/07 13:28 編集

kinisinaiさん それを決めるのはあなたです。 ただふわっとしたままではヌケモレがあったときに対応しきれません。 既にコメントで指摘があるようにふわっとしすぎていて要件がほとんど詰められていないことは明白です。 パターンをきちんと洗い出し、要件を確定させましょう。 どういう形式のインプットがあり、パターンがどれだけあり、制限事項には何があり、そして、どうなるのか。どうしたいのか。 それを持っているのはあなたであり他人ではありません。
m.ts10806

2019/11/07 13:29

hentaimanさん 私も「まず組んでみて」と思ってます。それで気づく要件の漏れもあるでしょうしね。 分からないなりに調べたこと試したことがあるはずですし。 丸投げの印象を与えたままなのが一番よくないです。
guest

0

外部のプラグインなしで実装したいのですがどうすれば良いかわからず困っています。

PHP標準でこんな↓に日時に関するものがあるのでお好みで使用ください。

(www.php.net)PHP マニュアル 関数リファレンス 日付および時刻関連 Date/Time - 日付・時刻 関数

投稿2019/11/08 00:37

Y.H.

総合スコア7918

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問