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

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

詳細はこちら
PHP

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

Q&A

解決済

3回答

919閲覧

date()関数で時間を指定し、日にちと時間を加減算する方法

pegy

総合スコア245

PHP

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

0グッド

0クリップ

投稿2019/11/17 06:15

編集2019/11/17 06:49

現在のYmdだけ取得して、時間だけを絶対的に指定したく以下のように指定しているのですが

php

1$date=date('Y/m/d 03:00:00'); 2echo $date //2019-11-17 03:00:00

ここから+1日の1秒前を指定したく

php

1$dateMinus=data($date,strtotime("1 day")) 2echo $dateMinus //2019-11-17 03:00:00

上記のように日にちが1日加算されないのですが、

  1. これを正しく1日加算するにはどうすれば良いのでしょうか?
  2. また、実際にはさらに1秒減算して2019-11-17 02:59:59としたいのですがstrtoTimeには-1 sのように時間減算のようなものが内容なのですが、秒数を減らす方法はあるのでしょうか?

ご助言をいただけると嬉しいです。
よろしくお願い申し上げます。

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

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

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

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

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

guest

回答3

0

strtotimeの書き方はココの例を見れば良いとして、変数名や関数名が混乱気味のようなので落ち着いて見直すのが良いと思います

投稿2019/11/17 06:35

hentaiman

総合スコア6426

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

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

pegy

2019/11/17 06:50

コメントありがとうございます。 失礼しました、変数名等コードを修正させていただきます。
hentaiman

2019/11/17 07:37

書き方分かりましたか? マニュアル確認してstrtotimeをechoを見てみると分かると思いますが、返されるのは秒です なので数値で1引けば1秒前になるし1足すと1秒後です。1dayと書かなくても86400足せば一日追加です
pegy

2019/11/17 10:18

コメント有難うございます。 echoしても同じ値しか出力されず、おそらく問題は別に指定している秒数部分が文字列で足しているため、出力フォーマットになっていない点ではないため、加算も減算もされないと推察致します
guest

0

strtotime() の書式をご確認いただいた方が良いと思います。

php

1<?php 2$t1 = mktime(3, 0, 0, date("m"), date("d"), date("Y")); 3$t2 = strtotime("+1 day -1 sec", $t1); 4echo date("Y/m/d H:i:s", $t1) . PHP_EOL; 5echo date("Y/m/d H:i:s", $t2) . PHP_EOL;
  • 実行結果
2019/11/17 03:00:00 2019/11/18 02:59:59

投稿2019/11/17 07:33

takepan1973

総合スコア821

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

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

pegy

2019/11/17 10:20

コメント有難うございます。 おそらくdate関数まで時間を文字列で足した場合には適切なフォーマットを満たしておらず、ご指摘のようにmktime関数で指定してフォーマット化する必要がある点が問題であったと思います。 有難う御座います
guest

0

ベストアンサー

第2引数に期待されるのはUNIXタイムなので、strtotime()の結果から1引けばよいと思います。
strtotime("1 day")-1

英語なのでsecondを利用しても良いかもしれませんがかえって煩雑になる気もします。

丁寧にやるとこう。

php

1$date=date('Y/m/d 03:00:00'); 2var_dump($date); 3$date_strtotime = strtotime($date.' -1 day'); 4var_dump($date_strtotime); 5var_dump(date('Y/m/d H:i:s',$date_strtotime)); 6var_dump(date('Y/m/d H:i:s',$date_strtotime - 1));

投稿2019/11/17 06:35

編集2019/11/17 09:37
m.ts10806

総合スコア80875

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

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

pegy

2019/11/17 06:48

コメント寄せていただきありがとうございます。 $date1=data($date,strtotime("1 day")-1) を出力したっ結果、//2019-11-17 03:00:00のままですがですが ご意図とは相違しますでしょうか? よろしくお願い申し上げます。 hentaim様のおっしゃる通り、strtotimeは見直しているのですが、一旦コメントさせていただきます
m.ts10806

2019/11/17 09:31

間違いです。 PHPマニュアル読んだら分かりますが、date()の第一引数は出力フォーマットです。
pegy

2019/11/17 10:13

有難うございます。なるほど、マニュアルを見て理解する事ができました。 date()で一部時間だけ指定して、ymdを現在値を出力する方法が不明でしたがtakepan 1973様ご教示のmktime()で実装ができそうです。 御礼申し上げます。
m.ts10806

2019/11/17 10:31

回答にコード追記してます。
pegy

2019/11/17 16:43 編集

追記ありがとうございます、その後マニュアルも含めて1日考え続けたのですが、以下の理解で概ね正しいのかをお尋ねさせてください。言い回しは不慣れでわかりづらい箇所もあるのかもしれませんが精一杯自分なりに理解に努めてみたつもりで、私のようにすぐ直感的にわからない人のために残したつもりでございます。 よろしくお願い申し上げます。 //ご提示のcode $date=date('Y/m/d 03:00:00'); var_dump($date); // A $date_strtotime = strtotime($date.' -1 day'); var_dump($date_strtotime);// B var_dump(date('Y/m/d H:i:s',$date_strtotime));// C var_dump(date('Y/m/d H:i:s',$date_strtotime - 1));// D Aは 正しくフォーマット化された時間(文字列)である。従って、正しくフォーマットされたものであるから、strtotimeでUNIXタイムスタンプ型に変換可能である。ただし、あくまでdata関数は時間のフォーマット化を目的とした関数でありPHP上では現在や特定の日時から時間を加減算する場合にはUNIXタイムスタンプ形式で実行する必要がある。 Bは strtotimeでUNIXタイムスタンプ形式の結果を得ることが目的であるが、第一引数のみで絶対日時を取得しする場合、同じ引数ないで適切なフォーマットであれば上記のようにご提示いただいた、 '2019/11/18 03:00:00 -1 day"のような記法を用いて、指定したフォーマットから1日減算したUNIXタイムスタンプ型の値を得ることができる(このような記法が可能であることを知らなかったのでここを理解するのに5時間かかりました。。。) 一方で、相対的な日時を算定することも可能でその場合第一引数に、加減算すべき文字列、第二引数にUNIX型タイムスタンプ形式の日付を指定方法となる。この場合は以下のように冗長なコードで少し見栄えは悪いですが $date_strtotime = strtotime('-1 day',strtotime($date)); で同じ結果を得ることができました。おそらくご提示のコードとの違いは絶対日時か相対日時の違いであるものの得られる結果は同じであると考えました。 蛇足になりますが、私は検証でよく形式を理解できておらず以下のように理解不能な結果を出力してしまい苦戦していたのですが $date_strtotime = strtotime('-1 day',$date); //"1969/12/31 09:33:39" よくよくマニュアルを見たらUNIXタインムスタンプを指定とあったので、やっと答えにたどり着くことができました。正しいUNIXタイムスタンプ型ではなくとも、エラーは出力されずに、結果を返す以上、PHPは何かを理解してそうしているものかと想像したので、試しに以下のようなコードの結果を出力してみたのですが、おそらく限られた数字から変換を試みようとしてくれているのかと推察いたしました。 $date_strtotime = strtotime('-1 day','2000happynewyear');//int(-84400) $date_strtotime = strtotime('-1 day','1999happynewyear');//int(-84401) $date_strtotime = strtotime('-1 day','happynewyear');//bool(false) さすがにやりすぎ。。。 Cは 第二引数のstrtotimeでUNIXタイムスタンプにした値を、第一引数の'Y/m/d H:i:s'でフォーマットをしている Dは 第二引数のstrtotimeでUNIXタイムスタンプにした値で単位は秒なのでUNIXタイムスタンプベースで1秒引いた値を、第一引数の'Y/m/d H:i:s'でフォーマット 何れにしても一旦、お力添えに御礼申し上げさせていただきます。 よろしくお願い申し上げます。
m.ts10806

2019/11/17 22:57

私まだ上記に応えてないですけど解決でいいんですか?
pegy

2019/11/18 01:50

いつも解決済みのタイミングに迷うのですが、 個別のコメントが質問者と回答者では続いているが本質的に当初の問題が解決した場合には一旦「解決済み」を付けるようにしていました。理由としては以下の2点です。 ●未解決ということで重ねて他の方からも追加でコメントをたくさんいただく機会もあるので、それに対する申し訳なさがあります。もちろん、あとから頂いたコメントで新たな気づきや情報として残すことに意味があるケースも数多くあったりすると思いますが。 ●また、m.ts10806にご回答いただいたケースではこれまでないのですが、最終的なコメントでお尋ねしましたが、コメントバックがなく(無論こちらからお願いをしてお尋ねしているので、100%常にコメントバックがあると期待して良いわけではないと理解しています)未解決で放置されてしまうケースもあるので、当初の問題を解決する具体的な方法が明らかになった時点で一旦「解決済み」にしています。 「teratailとは?(https://teratail.com/tour)」などで解決のタイミングについての指針も調べたことがあるのですが、具体的な言及がなかったので、上記の判断に基づき解決のタイミングを決定しております。 ・もちろん個別のコメントが続いている以上、当初の問題が解決(実装ができた)としても解決を一旦取り消すべきとのご判断であればそのようにいたします。 ・また、上記のコメントについても一日かけて必死に調べたので是非後学のためにもコメントバックを頂戴できると嬉しいです! 宜しくお願い申し上げます。
m.ts10806

2019/11/18 01:55

個人的には「当該質問に関係あることで質問者の疑問点が全て解消すれば」が「解決済み」にするタイミングとしては良いと思っています。 疑問点があるのに解決済みにしたり、解決済みにしたあとに追加でコメントで質問されると「解決したんじゃないの?」と戸惑いがあります。 こちらも一人の人間でこればっかりやってるわけではないので、その辺りは配慮してもらえたらお互いやりやすくなると思います。 追加でコメントいただいた確認事項についてはちょっとお時間いただきます。
pegy

2019/11/18 03:07

なるほど、もろもろご意見を頂きありがとうございます。なるほど、確かに回答者からすると「ん、すべてが解決してcloseなの?」という感覚があるのも理解することができます。 一つの判断基準として、今後の解決済みタイミングを考える際の一つのご参考とさせていただきます。 もちろん、悪意はなく一旦ベストアンサーを解除させて頂きました。 宜しくお願い申し上げます。
m.ts10806

2019/11/18 03:16

>A date()が第一引数でエラー返すことってほぼないはずで、第一引数はあくまで「日付のフォーマット方法を指定する」だけです。 第2引数によってフォーマットする時間が決まります(つまり内部的にはUNIXタイムを持っているということ。デフォルトは今) つまり確実にstrtotime()は通せます。 >B おおよそあってると思います。 私の場合はあまりstrtotimeを重ねたくないのと、文章として成り立たせたく「基点とした日時から1日」としたためそのような記述になっています。 蛇足ですが日本語は使えません。 >C,D その通りです。 気になったのが下記 >UNIXタイムスタンプ型 そういう型は存在しません。争点はあくまで「strtotime()がきちんと解釈できるフォーマットが引数で渡されているか」というところで、関数名が示すようにあくまで文字列が渡されます。 解釈できない適当な文字列だととりあえず1970/1/1 00:00:00を返すという仕様です。
pegy

2019/11/18 05:05

コメント頂き、ありがとうございます。 ●UNIXタイムスタンプ型の表現について 確かにそのような「型」は存在しないので、不明確な表現でした。また解釈ができない場合の起点が「1970/1/1 00:00:00」ということを初めてしりました。有難うございます。 ●「date()が第一引数でエラー返すことってほぼないはず」について 確かにdata()の第一引数にいろいろな文字列を入れてみたのですが、何かを返してくれるようでエラーが返らないことが確認できました。ただしstrtotime()は正しいフォーマットでないと適切なUNIXタイムスタンプを返してくれないことも確認できました。 1) 一方でこれらの点からエラーが出力されないということはバグの原因になる可能性があるので出力は注意深くチェックしようと思います。 2) 最後に蛇足ですがstrtotime()はUNIXタイムスタンプで999以下と1000以上で返す結果が異なることがわかりました。 var_dump (strtotime(date('1000')));?>/// int(1574071200) var_dump (strtotime(date('999')));?>///bool(false) ここからUNIXタイムスタンプにおいては、1000をカットオフに意味があるものかもしれませんが、(最低単位がmsでこれが1/1000sなので1000なのかと解釈しておりますが)もはや私の興味の世界に入ってしまいそうなので、自分で調べてみようと思います。 兎にも角にも最後までお付き合いいただきまた解決と理解にお導き下さり重ねて御礼申し上げます。 宜しくお願い申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問