2011-02-10 11 views
2

月と日の部分がオプションの日付を処理する必要があるという問題があります。たとえば、その年はいつも知られていますが、時には昼または月と日が分からないこともあります。データベース作業の中からMySQLの日付フィールドのオプションの月または日PHP

(YYYY-MM-DD format): 
2011-02-10 // Current date 
2011-02-00 // Day unknown so replaced with 00 
2011-00-00 // Day and month unkown so replaced with 00-00 

テストの計算:私は日付フィールドを持つテーブルを作成することができますし、私はMySQLのマニュアルの参照を見つけることができない一方で、それは有効なものとして、以下を受け入れるMySQLでは

結果を簡単に並べ替えることができます。マニュアルでは、その月は01から12、そして01から31の間の日付でなければならないと言いますが、00を受け取ります。

最初の質問:月または日の部品で00を使用して問題に遭遇しますか?それとも完璧に受け入れられますか?

次の質問:次の日付を必要な書式文字列に自動的に書式設定するPHP関数(またはMySQL書式コマンド)はありますか?

2011  becomes 2011-00-00 
2011-02 becomes 2011-02-00 

これを処理するには特殊な関数を記述する必要がありますか?

以下は動作しません:

<?php 
$date = date_create_from_format('Y-m-d', '2011-00-00'); 
echo date_format($date, 'Y-m-d'); 
// Returns 2010-11-30 

$date = date_create_from_format('Y-m-d', '2011-02-00'); 
echo date_format($date, 'Y-m-d'); 
// Returns 2011-01-31 
?> 

3番目の質問:PHPで使用するための日付をフォーマットするPHP関数(またはMySQLのコマンド)がありますか?

最後に、これが最善のアプローチですか?または、「ベストプラクティス」方法がありますか?


EDIT:

を日付フィールドには、フォーマットYYYYの日付を受け入れるYYYY-MM、またはYYYY-MM-DDと前にすることができます:ここで

は、私が現在やっているものですそれは、この関数内で処理されたデータベースへの送信:

/** 
* Takes a date string in the form: 
* YYYY or 
* YYYY-MM or 
* YYYY-MM-DD 
* and validates it 
* 
* Use date_format($date, $format); to reverse. 
* 
* @param string $phpDate Date format [YYYY | YYYY-MM | YYYY-MM-DD] 
* 
* @return array 'date' as YYYY-MM-DD, 'format' as ['Y' | 'Y-m' | 'Y-m-d'] or returns false if invalid 
*/ 
function date_php2mysql($phpDate) { 
    $dateArr = false; 
    // Pattern match 
    if (preg_match('%^(?P<year>\d{4})[- _/.]?(?P<month>\d{0,2})[- _/.]?(?P<day>\d{0,2})%im', trim($phpDate), $parts)) { 
     if (empty($parts['month'])) { 
      // Only year valid 
      $date = $parts['year']."-01-01"; 
      $format = "Y"; 
     } elseif (empty($parts['day'])) { 
      // Year and month valid 
      $date = $parts['year']."-".$parts['month']."-01"; 
      $format = "Y-m"; 
     } else { 
      // Year month and day valid 
      $date = $parts['year']."-".$parts['month']."-".$parts['day']; 
      $format = "Y-m-d"; 
     } 
     // Double check that it is a valid date 
     if (strtotime($date)) { 
      // Valid date and format 
      $dateArr = array('date' => $date, 'format' => $format); 
     } 
    } else { 
     // Didn't match 
     // Maybe it is still a valid date 
     if (($timestamp = strtotime($phpDate)) !== false) { 
      $dateArr = array('date' => date('Y-m-d', $timestamp), 'format' => "Y-m-d"); 
     } 
    } 
    // Return result 
    return $dateArr; 
} 

は、だから、パターンは、それが4桁、月と日の数字の後、必要に応じてペアで開始する必要があります入力の$ phpDateにマッチします。これらは$ partsという配列に格納されます。

次に、フォーマット文字列を指定して日付を作成しているかどうかを確認します。

最終的にすべてがチェックアウトされた場合、有効な日付とフォーマット文字列が返されます。それ以外の場合はFALSEを返します。

私のデータベースの有効な日付形式になってしまい、戻ってくるときにもう一度使用する方法があります。

誰かがこれを行うより良い方法を考えていますか?

+0

サンプルにはどのような結果が期待されますか? – zerkms

+0

MySQLのサンプルは、00かどうかに関係なく、YYYY-MM-DDの形式で動作します。 PHPの例ではコメントの結果が返されますが、最初の2011-00-00と2番目の2011-02-00の形式にしたいと思っていました。 – Das123

答えて

0

データ部分はすべてオプションですので、月、日、年の部分を別々の整数フィールドに格納するのは面倒ですか?または、VARCHARフィールドに? 2011-02-00は有効な日付ではなく、mysqlまたはPHPがそれに興奮しているとは思いません。 str_to_timeでテストし、どのような結果が得られたかを確認してください。また、ソートがMySQLで正しく機能していることを確認しましたか? docsが1から31までが必要で、それが00を取っていると言うならば、本質的に何がバグかに頼っているかもしれません。

2011-02-00は有効な日付ではないため、PHPの書式設定関数はこの結果を提供しません。それがまったくそれを処理したら、あなたが試してみれば2001年1月31日を持っていれば驚くことはありません。データベースに文字列として格納する理由、または月、日、年を別々の整数フィールドに入れる理由があります。後者のルートを使用した場合でも、それらの列をソートすることはできます。

+0

私は自分のコードがバグに頼っている可能性があることを懸念していました。 :) MySQLは00で動作しますが、PHPでは動作しません。 これまでは、日付用とフォーマット用の2つのフィールドがありました。だから、もし私が2011年1月1日に 'Y'の形式で2011年1月1日を置く年を知っていたら、その月を知っていたら2011年2月1日と 'Y-m'になります。私は日付フィールドを介して簡単に並べ替え、返されたときにデータを提示することができました。 – Das123

+0

まだ十分ですが、私はまだ3つの整数列が扱いやすいと思います。これはフォームでの簡単なプレゼンテーション、柔軟な並べ替えを可能にします。表示したいときにフォーマットで踊る必要はありません。フィールドを一緒に詰め込んで表示するだけです。 –

+0

3つの整数フィールドの問題は、MySQLが日付であることを知らないため、日付関数を使用できないということです。可能であれば、私はまだ何らかの日付形式を保つことを好みます。 – Das123

0

この問題も発生しました。私はPEAR Dateパッケージを使用して終了しました。ほとんどの日付クラスはオプションの月または任意の日には機能しませんが、PEAR日付パッケージは機能します。これは、カスタムの書式設定機能が不要で、日付パッケージで提供される見栄えのよい書式設定メソッドを使用できることを意味します。

2

月と日の部分がオプションの日付を処理する必要があるという問題があります。 たとえば、年は常にわかりますが、時には曜日または月が 不明になることがあります。多くの場面で

、我々はそのような「多かれ少なかれ正確な」日付が必要です、と私は2011-04-01(精密)ならびに2011-04(= 2011年4月)と2011(年日付のみ)などの日付を使用メタデータをアーカイブします。 MySQLの日付フィールドは '2011-00-00'を許容していますが、それについてのFAQはありませんが、それは問題ありません。
しかし、MySQL databaseODBCに接続し、日付フィールド は、 '許容される'日付(例: '2011-04-00'の結果がMySQL-ODBC接続のACCESSデータベース
そのため、私は、MySQLの日付フィールドを普通のVARCHAR(10)フィールドに変換することができたという結論に達しました:特定のMySQLの日付関数が必要でない限り、それはうまく動作し、もちろん、

MySQLの日付フィールドが必要な唯一のケースは です。複雑なSQLクエリが必要な場合は、を使用してください。日付はクエリ自体に機能します。 (しかし、そのようなクエリは、「多かれ少なかれ正確な」日にもう働かないでしょう...!)

結論:「多かれ少なかれ正確な」日付については、 私は現在、MySQLの日付フィールドを破棄し、平野VARCHAR(10)を使用フィールド とaaaa-mm-jjのデータ。シンプルは美しい。

0

私はこのリンクを教科書で見つけました。これは、月と日の値は、あなたがそれは3つのフィールドだかのようにあなたがそれを得ることができ、データベースからバラバラにあなたの日付を引く場合

http://books.google.co.uk/books?id=s_87mv-Eo4AC&pg=PA145&lpg=PA145&dq=mysql+date+of+death+when+month+unknown&source=bl&ots=tcRGz3UDtg&sig=YkwpkAlDtBP1KKTDtqSyZCl63hs&hl=en&ei=Btf5TbL1NIexhAfkveyTAw&sa=X&oi=book_result&ct=result&resnum=8&ved=0CFMQ6AEwBw#v=onepage&q&f=false

0

不完全または未知のデータを格納するpossiblityを可能にするためにゼロになることができると述べています。

YEAR(dateField) as Year, MONTH(dateField) as Month, DAY(dateField) as DAY 

これらをPHPの次のビットの対応するフィールドにプッシュすると、探している結果が得られます。

$day = 0; 
$month = 0; 
$year = 2013; 


echo $datestring; 

$format = "Y"; 
if($month) 
{ 
    $format .= "-m"; 
    if($day) 
     $format .="-d"; 
    else 
     $day = 1; 
} 
else 
{ 
    $month = 1; 
    $day = 1; 
} 

$datestring = strval($year)."-".strval($month)."-".strval($day); 

$date = date($format, strtotime($datestring)); 
echo $date; // "2013", if $month = 1, "2013-01", if $day and $month = 1, "2013-01-01" 
関連する問題