私は、次の難問で数日間頭を悩ませてきました。
私は基本的に次の複雑なmySQLテーブルを持っています:
| ID | TITLE | DESCRIPTION | EVENT | DATE |
|----|--------------|-------------------|-------|-------------------------|
| 1 | Big painting | 3-day work | No | 03/10/2013 |
| 2 | Meeting | With reps. | Yes | 02/15/2013 09:00 -05:00 |
| 3 | Presentation | 5 paintings | Yes | 08/02/2013 22:00 +02:00 |
| 4 | Round paint. | One week | No | 04/05/2013 |
| 5 | Conference | On Picasso | Yes | 04/22/2013 18:00 -05:00 |
(編集: おそらく、DATE 列が [データにタイムゾーンを含める必要があるため] DATE または DATETIME として設定されているのではなく、VARCHAR として設定されていることを明確にする必要があるため、最初から組織が複雑になっています。)
ご覧のとおり、これは、たとえばペインター向けのすべての「最新情報」項目を含むテーブルです。このペインターの Web サイトでは、PHP が値を呼び出して、"What's New" ニュース ティッカーとして表示するという考え方です。
すべての基本はそこにありますが、私は思わぬ障害にぶつかっています。
最初は、SELECT 段階でデータをフィルタリングして並べ替えたいと思っていましたが、それがうまくできませんでした。ご覧のとおり、イベントと非イベント アイテムのボットには日付がありますが、非イベント アイテムには、全体的なデータを整理する方法として日付が含まれているだけです。特定の日付と時刻は、イベントの場合にのみ重要です。これにより、ユーザーはこれらのイベントがいつ発生したかを知ることができます。したがって、基本的な考え方は、テーブルから特定の数の LATEST 項目を選択することです。したがって、すべての項目がテーブルから読み取られ、DATE の順に配置されてから、たとえば 20 個の項目が取り出されます。
前述したように、最初は SELECT 段階でこれを行うことを考えていましたが、複雑すぎる可能性があると思います。そのため、すべてのアイテムを抽出し、フィルタリングするためにそれらの後に PHP コードを設定しました。
そのため、日付を注文しようとすると問題が発生します。注文プロセスのために日付をタイムスタンプに変換してから、表示のために日付に戻そうとしています。ただし、日付-タイムスタンプまたはタイムスタンプ-日付 (またはその両方) の変換が機能しません。私はいつも、最初の日付とは異なる日付になってしまいます。
ご覧のとおり、タイムゾーンが原因で全体がより複雑になっています。タイムゾーンは非常に重要です。ユーザーは、これらのことがどこで発生しているか、または発生している場所に応じて何時に発生しているかを知ることができなければならないためです。
私は単純に前後に変換しようとしました:
$timestamped = strtotime($date);
$datetimed = date('m/d/Y h:i P',$timestamped);
うまくいかないので、テーブルで使用している日付形式に関係があると思いました。
それで、私はこれを試しました:
$var = DateTime::createFromFormat('m/d/Y H:i P',$date)->getTimestamp();
無駄に、まだ...
おそらく、プロセスの開始時、つまりデータ項目を挿入するときにタイムスタンプを設定する必要があると考えています。しかし、ここでも「人間の」日付をタイムスタンプに変換する必要があり、これを正しく管理できなければ、何も適切に機能しません。
この質問が複雑であることは理解していますが、おそらく私の説明が最も明確ではないでしょう! おそらく、出力例が役立つかもしれません。私が達成しようとしているのは、起こっていることのリストを含む「What's New」ニュース ティッカーです。そのうちのいくつかは、目に見える日付のない単なる情報 (ステータスの更新など) です (ここでの日付は内部組織のためだけのものです)。 ; ここで EVENT 列の出番です。日付を表示する必要があるアイテムと、日付を表示してはならないアイテム)、その他、ユーザーが招待される実際のイベント、およびユーザーの日付を表示するアイテムをフィルター処理します。まだ過去ではないイベントに「UPCOMING」タグを表示するために、日時が過去か未来かを計算するコードもあります。ただし、日付の処理と注文に問題があります。
これは、この例が最終的に多かれ少なかれ次のようになるはずです。
どんな助けでも大歓迎です!(また、このデータ検索/整理プロセスを処理する最も実用的で最もクリーン/エレガント/プロの方法であると思われるものについてのフィードバック...データ入力の場合、mySQL SELECT ステージの場合、後でなど. )
PSおそらく、同じテーブルに他のデータを処理することを追加するかもしれません。この特定の "What's New" データは、特定の WHATSNEW 列を検索する SELECT 関数によって選択され、この特定の "What's New" ニュース ティッカーに対して取得されるすべての行で TRUE の値を持ちます。
解決策(回答ではありません)
質問は、いわば時間とタイムゾーンを 1 つの文字列として整理することに関するものだったので、これら 2 つの優れた回答のいずれかを、その特定の問題について正しいとマークできるかどうかはわかりません。私がやったことは、タイムゾーンを取り除いて別の列に入れることでした。次に、日付列を日時としてフォーマットしました。mySQL Select が私に代わって注文を処理できるので、私はそれを解決しました。さて、タイムゾーンについてですが、私は少しごまかしてしまいました。私たちの「アーティスト」が、2 つの異なるタイムゾーンで同時に 2 つのイベントに参加することはあり得ないと考えました。それぞれのタイムゾーンが最初に来る本当の違いを生むほど接近しているイベント。したがって、私は物事自体を日付順に並べてから、スニペットを作成してタイムゾーンを処理し、それらを「GMT + 1」、「GMT-5」表示に変換して、ユーザーがその場所がどこにあるかを知るようにしました現地時間。結局使ってしまったDateTime::createFromFormat()->getOffset()
、2番目の回答者が推奨しているのを見て、正しい軌道に乗っていると言っていたので、そこに保管しておいてよかったです.これをさらに明確にするために、ウェブマスターができる場所列を追加しました.都市を指定するには、「パリ」、「ロンドン」などと言ってください。したがって、ユーザーは、私の例に示されているものと非常によく似たものを持つことになります... (Paris, GMT+1)
。
とにかく、まったく同じ問題を抱えていて、まったく同じことを考えてしまい、この方法がより実用的であるという人のために、ここに私が最終的に得たコードの核心があります. 残りは「埋める」だけです。楽しみ!そして、この問題の解決策を見つけるために時間を割いてくれた親切な二人に感謝します! (余計なことがあるかもしれ}
ません…申し訳ありません。SOに貼り付けるときの再フォーマットは本当に面倒です!コードを2回修正しましたが、問題は見つかりませんでした。)
if(isset($item) && $item['event'] == '1') {
$event = $item['event'];
$date = $item['date'];
$date_array = date_parse($date);
$minute = $date_array['minute'];
if($minute<10) {
$minute = '0'.$minute;
}
$timezone = $item['timezone'];
if($timezone!=='') {
$timezone = DateTime::createFromFormat('P',$timezone)->getOffset();
$timezone = $timezone/-3600;
if($timezone<0) {
$timezone = $timezone;
} else
if($timezone==0) {
$timezone = '-0';
} else {
$timezone = '+'.$timezone;
}
$timezone = 'Etc/GMT'.$timezone;
$timezone_real = $item['timezone'];
$timezone_real = DateTime::createFromFormat('P',$timezone)->getOffset();
$timezone_real = $timezone_real/-3600;
if($timezone_real<0) {
$timezone_real = str_replace('-','+',$timezone_real);//.':00';
} else
if($timezone_real==0) {
$timezone_real = '+0';//:00';
} else {
$timezone_real = '-'.$timezone_real;//.':00';
}
$timezone_real = 'GMT'.$timezone_real;
date_default_timezone_set($timezone);
}
$today = date('n/j/Y G:i', time());
$today = strtotime($today);
$event_date = $date_array['month'].'/'.$date_array['day'].'/'.$date_array['year'].' '.$date_array['hour'].':'.$minute;
$event_date_unformatted = strtotime($event_date);
if($date_array['hour'] == '0') {
$hour_convert = '12';
$hour_suffix = 'a.m.';
} else if($date_array['hour']<12) {
$hour_convert = $date_array['hour'];
$hour_suffix = 'a.m.';
} else if($date_array['hour'] == '12') {
$hour_convert = $date_array['hour'];
$hour_suffix = 'p.m.';
} else {
$hour_convert = $date_array['hour']-12;
$hour_suffix = 'p.m.';
}
$date_convert = array('1' => 'January', '2' => 'February', '3' => 'March', '4' => 'April', '5' => 'May', '6' => 'June', '7' => 'July', '8' => 'August', '9' => 'September', '10' => 'October', '11' => 'November', '12' => 'December');
$event_date = $date_convert[$date_array['month']].' '.$date_array['day'].', '.$date_array['year'].', '.$hour_convert.':'.$minute.' '.$hour_suffix;
if(($event_date_unformatted-$today)>0) {
echo '<h5>UPCOMING:</h5>';
echo '<h6>'.$item['location'].', '.$event_date.' <sup>('.$timezone_real.')</sup></h6>';
}
}