8月31日の10時に $next = strtotime("+1 month");  で10月になっている - PHPプロ!Q&A掲示板

1461

  • 200P

8月31日の10時に $next = strtotime("+1 month");  で10月になっている

質問日時 / 2008年8月31日 22:24 (最終編集:8月31日 22:26)    回答数 / 5件

Questioner:  yumisaiki  このエントリーをはてなブックマークに追加 

キーワード / strtotime   

http://www.phppro.jp/qa/detail.php?id=805
でお世話になった占いのサイト

ですが、夜たまたま見て、本日8月31日の9時ころに見たら来月がないのです。
で、確認したら10月になっているのです。
http://taishinkan.co.jp/unsei.php?y=08&m=9&unsei=9

  1. <?php
  2. $num =intval($HTTP_GET_VARS["unsei"]);
  3. $y = ($HTTP_GET_VARS["y"]);
  4. $m = intval($HTTP_GET_VARS["m"]);
  5.    if( $HTTP_GET_VARS['y'] == "" && $HTTP_GET_VARS[m] == "" ){
  6.   //年月指定がない場合のケア
  7.  $y = date('y');
  8.  $m = date('n');
  9.  }
  10.  $file = "<img border=\"0\" src=\"".$y.$m."/unsei-zu.gif\" alt=\"京都 占い\">";
  11.  $file2 = "/".$y.$m."/".$y.$m.".gif";
  12.   $next = strtotime("+1 month");
  13.   $nyear = date("y",$next);
  14.    $nmonth = date("n",$next);
  15.     $prev = strtotime("-1 month");
  16.     $pyear = date("y",$prev);
  17.    $pmonth = date("n",$prev);
  18.   $filename  = "./".$y.$m."/".$num.".txt"
  19.    if (file_exists($filename)) {
  20.     // ファイルが存在する場合はファイル名を返す
  21.    $handle = @fopen($filename"r");
  22.   $ary1=array();
  23.   if($handle){
  24.           while (!feof($handle)){
  25.              $buffer = fgets($handle4096);
  26.              array_push($ary1,$buffer);
  27.           }
  28.           fclose($handle);
  29.           }
  30.   ?>

 の $nmonth  をecho すると 10 になるので、
 とりあえず 本日は strtotime("+30 days") にしましたが、 また明日になったら1 month にもどします。

 これは サーバーの時間帯の違いによるものなのではないかと思うのですが、これってどうしたらいいですか。 私の力だと 31日だった時はこうしろ、と条件分岐を書き込むくらいしか浮かんでこないのですが。

 アドバイスありましたらお願いします。
 

この質問への意見の募集は締め切られ、ポイントは既に配分されました。
意見を投稿することはできますが、ポイントを受け取ることはできません。



ツリー一覧

┣A01yakou850自分もよくわかっていないのですがstrtotimeはちょっ
┣A02win_php答えのあるサイト http://study.rakuto.net/php/ph
┣A03tezcello年と月しか利用しないのですよね? 大の月と小の月の
┗A04yumisaikiありがとうございました。 30日の月と31日の月がある
 ┗A04-1tezcello> ご心配ありがとございます。 14月とかないように 

回答一覧

並び替え:

A01 満足
answereryakou850 [8月31日 23:38]

自分もよくわかっていないのですがstrtotimeはちょっと一癖ありそうですね。
このサイトでも
http://www.phppro.jp/phptips/archives/vol3/1
というページがあり、今回の例とは逆のパターンでバグってます。

年・月だけでいいのならmktimeを使うことができるかもしれません。
こちらの質問内容が近いので参考になるかもしれません
http://questionbox.jp.msn.com/qa3218824.html?StatusCheck=ON

この意見に回答する

ツリーへ TOPへ

A02 満足
answererwin_php [9月1日 00:23] (最終編集:9月1日 01:14)

答えのあるサイト

http://study.rakuto.net/php/phptips/strtotime/


 strtotime("+1 month");  じゃだめということです。

 //年月指定がない場合のケア 
 $y = date('y'); 
 $m = date('n'); 

の $m 使ったほうが手っ取りはやいような気もするのですが。


date('Y-m-d H:i:s');

でまれに時間が9時間ずれてることもありますので確認していただき、

$m に +1 , -1 したらどうでしょうね。

まあ、年またぐときの+-のときの処理が面倒なら、参考サイトのように。

この意見に回答する

ツリーへ TOPへ

A03 満足
answerertezcello [9月1日 00:51]

年と月しか利用しないのですよね?
大の月と小の月の関係で、前後の月の同一日が無い場合におこる問題ですよね?
(例えば、8/31の1ヶ月後は9/31で、9/31は9/30の翌日という事で10/1になってしまう)
これって、月末の日付を使うから起きる訳なので、月初の日にちに固定してしまえば解決しません?

  1. $next = strtotime("+1 month");
のように現在のタイムスタンプからの計算では無く、この時点で年($y)と月($m)がわかっているのだから
  1. $next = strtotime("+1 month", mktime(0, 0, 0, $m, 1, $y));
のようにして $y 年 $m 月1日のタイムスタンプで計算するのはどうでしょう?



ついでに気になったので...
コードの他の部分を見ていませんので、ハズしているかも知れませんが、
form から得られた値を鵜呑みにして $y, $m  に代入しているように思うのですが?
-3000年とか、14月とかの値が与えられる事は有り得ませんか?

この意見に回答する

ツリーへ TOPへ

A04
answereryumisaiki [9月1日 13:49] (最終編集:9月1日 13:58)

ありがとうございました。 30日の月と31日の月があるから 単純じゃないというのは初めて知りました。

 1日を起点としてshorttime を使うために mktime 1日のタイムスタンプを取得する

  1. // 1日に設定
  2. $nowtime = mktime(0,0,0,$m,1,$y);
  3. $next = strtotime('+1 month',$nowtime);
  4. $prev = strtotime(' -1 month',$nowtime);

と改善しました。

 正直、まだまだ部分的にしかわかってなくて、アドバイスしていただいたことを理解するのも大変です。
 本当にありがとうございました。

これからもがんばります。

 ご心配ありがとございます。 14月とかないように nextyear を設定しているつもりなんですが…。
  1. if( $HTTP_GET_VARS['y'] == "" && $HTTP_GET_VARS[m] == "" )
  2.     {
  3.       print("<a href=\"unsei.php?y={$pyear}&m={$pmonth}&unsei={$HTTP_GET_VARS['unsei']}\">");
  4.       print("先月");
  5.       print("</a>");
  6.       print("&nbsp;&nbsp;");  
  7.       print("<a href=\"unsei.php?y={$nyear}&m={$nmonth}&unsei={$HTTP_GET_VARS['unsei']}\">");
  8.       print("来月");
  9.       print("</a>");
  10.       
  11.       print("<br />");
  12.       print("<a href=\"index.php\">");
  13.       print("topへ");
  14.       print("</a>");
  15.     }
  16.       else{
  17.       print("<a href=\"unsei.php?unsei={$HTTP_GET_VARS['unsei']}\">");
  18.       print("もどる");
  19.       print("</a>");
  20.       print("<br />");
  21.       print("<a href=\"index.php\">");
  22.     print("topへ");
  23.     print("</a>");
  24.       }
  25.      } else {
  26.          // ファイルが存在しない場合はfalseを返す
  27.          require_once("gaib.php");
  28.      }
  29. ?>
が 表記部分です
 また なんかあったらよろしくお願いいたします。

この意見に回答する

ツリーへ TOPへ

A04-1 満足
replyertezcello [9月1日 17:57]

> ご心配ありがとございます。 14月とかないように nextyear を設定しているつもりなんですが…。
ご提示のスクリプトは、問題ない値が $pyear, $pmonth, $nyear, $nmonth に与えられているという前提のもおですね。
質問文のスクリプトと、この返信のスクリプトの間、または、質問文のスクリプトの以前に、フォームから受け取ったクエリの値が意味のある値なのかのチェックがあるのだとは思います。

Aタグつけてあるクエリが返ってくる事を期待しているのだと思いますが、どんな事があるのか分からないので月は1~12、年は1970~2038である事をチェックして、それ以外の場合はエラーを出して再入力させるなり現在の年月を使うなりするべきだろうな...と。

checkdate() という関数で、簡単なチェックが出来るようですが、mktime() はそれよりも狭い範囲でしか使えませんからご注意を。
   うちの環境では、111~1901 の間(両端を含む)と2039以上は1970年と解釈してくれました。
   (マニュアルとチョッと違う...)
   範囲外の値を自動修正してくれるそうで、
   mktime(0, 0, 0, 12, 32, 1997) は1998/1/1 の値になるそうです。
   なので、使い方によっては、自力でチェックが必要ですね。

この意見に回答する

ツリーへ TOPへ

<<質問一覧へ



Pick Up Q&A

Q
ログファイルの中の空のデータ行を削除したい
 このエントリーをはてなブックマークに追加 
A
ログのデータ個数(列数)が固定で、空のログが"<><><>"だと既知であれば if ($line === "<><><>") { continue; } で読み飛ばしてもいいのでは? ...

>>続きを読む

まずは配列や文字列の扱いから、じっくり勉強して行きましょう。

▲解説者:岡本(アシアル株式会社 教育コーディネーター兼 システムエンジニア)