提案されたアイデアに基づいて、最終的に時差を返すための実用的な多言語ソリューションにたどり着きました。
私はオブジェクト指向スタイルのプログラミングの完全な初心者であり、これは実際には私の最初のタスクであるため、優しくしてください。コメントや提案されたアイデアを残していただければ幸いです。
Jon に感謝します。あなたのアイデアをすべて具現化できなかったことを残念に思います。とても素敵な提案と説明があるので、あなたの答えを受け入れます!
説明
私のデータベースにはadded_time
、アップロードされた各ビデオの作成時刻を Unix タイムスタンプ形式で参照するフィールドがあります1345284190
。
このタイムスタンプは、次のようにコンストラクターに渡され new creationTime( '@' . $timestamp)
ます。
各ビデオをループして挿入する特別な機能があります。
例: ビデオは27 日前に追加されました。
PHP Time ManualでCokidoo が提供する美しい例を使用して、最終的にこれを達成し、多言語 Web サイトのサポートを追加してyears ago
、months ago
、days ago
、などを言語ファイルから派生したテキストに置き換えました。
微調整
英語で書かれた初期値 (つまり 、 year ago、month ago、day agoなど) を (多言語 Web サイトで使用できるようにするために) 簡単に処理できるものに変更しました。 : year_ago
、month_ago
、day_ago
など
次に、出力を返していた初期$value
変数を展開しました。たとえば、 1年前、1か月前、1日前sprintf
、提案されたとおりに使用されました。
最後にgetLocalized
、このクラスを自分の言語ファイルに接続する関数を追加しました。
これは、警告をスローしない最終的な作業コードです (警告が有効になっています; PHP バージョン 5.4.6 )。
クラス名を からCokidoo_DateTime
に変更しましたcreationTime
:
class creationTime extends DateTime {
private $strings = array(
'y' => array('1 year_ago', '%d years_ago'),
'm' => array('1 month_ago', '%d months_ago'),
'd' => array('1 day_ago', '%d days_ago'),
'h' => array('1 hour_ago', '%d hours_ago'),
'i' => array('1 minute_ago', '%d minutes_ago'),
's' => array('just_now', '%d seconds_ago'),
);
private function getLocalized($string) {
global $lang;
$string == 'year_ago' ? $string = $lang['global.year_ago'] : null;
$string == 'years_ago' ? $string = $lang['global.years_ago'] : null;
$string == 'month_ago' ? $string = $lang['global.month_ago'] : null;
$string == 'months_ago' ? $string = $lang['global.months_ago'] : null;
$string == 'day_ago' ? $string = $lang['global.day_ago'] : null;
$string == 'days_ago' ? $string = $lang['global.days_ago'] : null;
$string == 'hour_ago' ? $string = $lang['global.hour_ago'] : null;
$string == 'hours_ago' ? $string = $lang['global.hours_ago'] : null;
$string == 'hour_ago' ? $string = $lang['global.hour_ago'] : null;
$string == 'hours_ago' ? $string = $lang['global.hours_ago'] : null;
$string == 'minute_ago' ? $string = $lang['global.minute_ago'] : null;
$string == 'minutes_ago' ? $string = $lang['global.minutes_ago'] : null;
$string == 'just_now' ? $string = $lang['global.just_now'] : null;
$string == 'seconds_ago' ? $string = $lang['global.seconds_ago'] : null;
return $string;
}
/**
* Returns the difference from the current time in the format X time ago
* @return string
*/
public function __toString() {
$now = new DateTime('now');
$diff = $this->diff($now);
foreach($this->strings as $key => $value){
if( ($text = $this->getDiffText($key, $diff)) ){
return $text;
}
}
return '';
}
/**
* Try to construct the time diff text with the specified interval key
* @param string $intervalKey A value of: [y,m,d,h,i,s]
* @param DateInterval $diff
* @return string|null
*/
protected function getDiffText($intervalKey, $diff){
$pluralKey = 1;
$value = $diff->$intervalKey;
if($value > 0){
if($value < 2){
$pluralKey = 0;
}
$value = explode(' ', sprintf($this->strings[$intervalKey][$pluralKey], $value) );
return sprintf('%d %s', implode(array_slice($value, 0)), $this->getLocalized(implode(array_slice($value, 1))));
}
return null;
}
}
編集済み
この素晴らしいソリューションは、同じことを行いますが、フォーマットと構造が優れています ( Jonによる)。
class DateFormatter {
private $localizer;
private $strings = array(
'y' => array('global.years_ago_1', 'global.years_ago_n'),
'm' => array('global.months_ago_1', 'global.months_ago_n'),
'd' => array('global.days_ago_1', 'global.days_ago_n'),
'h' => array('global.hours_ago_1', 'global.hours_ago_n'),
'i' => array('global.minutes_ago_1', 'global.minutes_ago_n'),
's' => array('global.seconds_ago_1', 'global.seconds_ago_n'),
);
public function __construct(Localizer $localizer) {
$this->localizer = $localizer;
}
/**
* Returns the difference from the current time in the format X time ago
* @return string
*/
public function formatHowLongAgo(DateTime $date) {
$now = new DateTime('now');
$diff = $date->diff($now);
foreach($this->strings as $unitOfTime => $formatStrings){
$howMany = $diff->$unitOfTime;
if (!$howMany) {
continue;
}
$plural = $howMany > 1;
return $this->localizer->format($this->strings[$unitOfTime][$plural], $howMany);
}
return '??';
}
}
// Packaged the localization stuff inside a class so that it's not
// just hanging around in the global scope. Not much to see here,
// a "real" localizer would have more features.
class Localizer {
private $lang = array(
'global.years_ago_1' => '1 year ago',
'global.years_ago_n' => '%d years ago',
'global.months_ago_1' => '1 month ago',
'global.months_ago_n' => '%d months ago',
'global.days_ago_1' => '1 day ago',
'global.days_ago_n' => '%d days ago',
'global.hours_ago_1' => '1 hour ago',
'global.hours_ago_n' => '%d hours ago',
'global.minutes_ago_1' => '1 minute ago',
'global.minutes_ago_n' => '%d minutes ago',
'global.seconds_ago_1' => 'just now',
'global.seconds_ago_n' => '%d seconds ago',
);
public function format($string /*, $param1, $param2, ... */) {
$params = func_get_args(); // get variable # of params
array_shift($params); // remove first item, we already have it in $string
if (!isset($this->lang[$string])) {
return '[['.$string.']]'; // a placeholder
}
return vsprintf($this->lang[$string], $params);
}
}
$localizer = new Localizer;
$timestamp = '1345284190'; // Example of Unix Timestamp
$datetime = new DateTime("@$timestamp");
$formatter = new DateFormatter($localizer);
echo $formatter->formatHowLongAgo($datetime);