Управление различиями форматов даты между PHP и MySQL - PullRequest
6 голосов
/ 06 января 2009

Я пишу свое первое PHP-приложение, которое должно напрямую работать с датами и, таким образом, напрямую учитывать тот факт, что PHP и MySQL имеют разные форматы дат.

Мой вопрос: какой самый элегантный способ справиться с этой разницей?

У меня есть две следующие функции для управления разницей с помощью php:

function mysql_date($php_date)  {
    return date( 'Y-m-d H:i:s', $php_date );
}

function php_date($mysql_date) {
    $val = explode(" ",$mysql_date);
    $date = explode("-",$val[0]);
    $time = explode(":",$val[1]);
    return mktime($time[0],$time[1],$time[2],$date[1],$date[2],$date[0]);
}

Есть ли более простой способ управлять этим напрямую в моих SQL-запросах?

Или не могли бы вы предложить какой-нибудь другой более изящный способ справиться с этим?

Ответы [ 7 ]

7 голосов
/ 06 января 2009

Начиная с PHP 5.2, в PHP появился встроенный класс / объект для работы с датами и временем, который называется DateTime . В пустоте всегда лучше использовать встроенную функцию, чем самостоятельно разбираться с грязными деталями.

Конструктор DateTime (или функция date_create) принимает дату в любом формате, понятном strToTime. Все, что вам нужно знать о strToTime, это его волшебное вуду, которое будет правильно распознавать дату практически в любом строковом формате. Когда я впервые столкнулся со strToTime, у меня была такая же внутренняя реакция, как и у вас сейчас («это фигня / кажется ненадежной»). Это не. Это просто работает таким образом, что ваше собственное хрупкое понимание дат никогда не будет (и если вы думаете, что понимаете даты, то нет. Поверьте мне.)

Итак, извлеките информацию из MySQL в виде строки даты / времени и немедленно создайте объект даты PHP. Используйте метод date_format (с некоторыми удобными константами ), когда / если вам снова нужна дата в виде строки.

3 голосов
/ 06 января 2009

Вы можете заменить php_date на strtotime.

$php = strtotime($mysql);

Эквивалентом MySQL будет UNIX_TIMESTAMP.

Хотя, если вы хотите обрабатывать форматирование в SQL, попробуйте MySQL DATE_FORMAT.

2 голосов
/ 06 января 2009

Я бы порекомендовал вам хранить все в формате mysql, пока вам не понадобится отобразить его пользователю, а затем использовать strtotime () , чтобы получить метку времени Unix и date () для форматирования это.

Если вы добавите какую-нибудь венгерскую запись, ошибиться будет еще сложнее:

$ymdDateAdded = date('Y-m-d');
$timeDateAdded = strtotime($ymdDateAdded);
$userDateadded = date('j F Y', $timeDateAdded);
2 голосов
/ 06 января 2009

Храните все в базе данных в поле даты и времени в UTC. Для работы с PHP используйте библиотеку PEAR Date . Я не большой пользователь PEAR, но эта библиотека великолепна и решит все досадные проблемы с конвертацией дат, о которых вам не следует беспокоиться.

1 голос
/ 06 января 2009

Я думаю, что было бы лучше хранить метки времени Unix в поле БД. Когда вам нужно отобразить даты на человеческом языке, вы всегда можете использовать функцию date () в php. Для всего остального просто используйте числовую метку времени.

0 голосов
/ 26 июня 2015

Это лучший способ сохранить время и дату в формате Unix, а не в других форматах.

Я создал класс для обработки даты и времени в php. Это простой в использовании и очень и очень полезный

<?php
define("NEW_LINE", "</BR>");
class scTimestamp
{
    private $timestamp;
    private $year;
    private $month;
    private $day;
    private $hour;
    private $minute;
    private $second;

    public function __construct() 
    {
        register_shutdown_function(array($this,'__destruct'));
        $this->setTimestamp($_SERVER['REQUEST_TIME']);
    }
    public function __destruct()
    {
        unset($this->timestamp);
        unset($this->year);
        unset($this->month);
        unset($this->day);
        unset($this->hour);
        unset($this->minute);
        unset($this->second);
    }
    private function rebuildTimestampFromDate()
    {
        $this->timestamp=mktime($this->hour,$this->minute,$this->second,$this->month,$this->day,$this->year);
    }
    private function rebuildDateFromTimestamp()
    {
        $this->day=date('j',$this->timestamp);
        $this->month=date('n',$this->timestamp);
        $this->year=date('Y',$this->timestamp);
        $this->hour=date('g',$this->timestamp);
        $this->minute=date('G',$this->timestamp);
        $this->second=date('s',$this->timestamp);       
    }
    public function setTimestamp($tempTimestamp)
    {
        $this->timestamp=$tempTimestamp;     
        $this->rebuildDateFromTimestamp();
    }
    public function getTimestamp()
    {
        return $this->timestamp;    
    }
    public function setYear($tempYear)
    {
        $this->year = $tempYear;
        $this->rebuildTimestampFromDate();
    }
    public function getYear()
    {
        return $this->year;
    }
    public function setMonth($tempMonth)
    {
        $this->month = $tempMonth;
        $this->rebuildTimestampFromDate();
    }
    public function getMonth()
    {
        return $this->month;
    }
    public function setDay($tempDay)
    {
        $this->day=$tempDay;
        $this->rebuildTimestampFromDate();
    }
    public function getDay()
    {
        return $this->day;
    }
    public function setHour($tempHour)
    {
        $this->hour = $tempHour;
        $this->rebuildTimestampFromDate();
    }
    public function getHour()
    {
        return $this->hour;
    }
    public function setMinute($tempMinute)
    {
        $this->minute = $tempMinute;
        $this->rebuildTimestampFromDate();
    }
    public function getMinute()
    {
        return $this->minute;
    }
    public function setSecond($tempSecond)
    {
        $this->second = $tempSecond;
        $this->rebuildTimestampFromDate();
    }
    public function getSecond()
    {
        return $this->second;
    }


    public function getDateDifferenceFromNow()
    {
        return $this->getDateDifferenceFrom($_SERVER['REQUEST_TIME']);
    }
    public function getDateDifferenceFrom($fromDate)
    {
        $return="";
        $sec=" Second";
        $min=" Minute";
        $hrs=" Hour";
        $before=" Before";
        $difference=$fromDate-$this->getTimestamp();
        if($difference<0)
            $return.="In the Future";
        else if($difference<60)
        {
            if($difference>1)
                $sec.="s";
            $return.= $difference.$sec.$before;
        }
        else if($difference<3600)
        {
            $difference=intval($difference/60);
            if($difference>1)
                $min.="s";
            $return.=$difference.$min.$before;
        }
        else if($difference<86400)
        {
            $difference=intval($difference/3600);
            if($difference>1)
                $hrs.="s";
            $return= $difference.$hrs.$before;
        }
        else if($difference<604800)
        {
            $return.= date("l g:i a",$this->getTimestamp());
        }
        else if($difference<28512000)
        {
            $return.= date("F j",$this->getTimestamp());
        }
        else
        {
            $return.= date("F j, Y, g:i a",$this->getTimestamp());
        }
        return $return;
    }
    public function getDateAsString()
    {
        return date("F j, Y",$this->getTimestamp());
    }
    public function getDateTimeAsString()
    {
        return date("F j, Y, g:i a",$this->getTimestamp());
    }


    public function __toString()
    {
        $return = NEW_LINE."^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^";
        $return.= NEW_LINE." ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^".NEW_LINE;
        $return.= NEW_LINE."@@ Timestamp: ".$this->getTimestamp()." @@".NEW_LINE;
        $return.= NEW_LINE."@@ Date: ".$this->getDateTimeAsString()." @@".NEW_LINE;
        $return.= NEW_LINE." ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^".NEW_LINE;
        return $return;
    }

}
?>

как только он включен, его можно использовать следующим образом

include_once("scTimestamp.php");
$test=new scTimestamp();

echo $test->getDateAsString();

$test->setTimestamp(1210203200);

echo $test->getDateDifferenceFromNow();

echo $test;

$test->setTimestamp(121020320022);
echo $test->getYear();

echo $test;

И результат хотел бы это.

26 июня 2015 г. 7 мая 2008 г., 23:33 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ @@ Timestamp: 1210203200 @@ @@ Дата: 7 мая 2008 г., 23:33 @@ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ 5804 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^ @@ Timestamp: 121020320022 @@ @@ Дата: 25 декабря 5804, 3:33 утра @@ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^

Этот класс может использоваться согласно потребностям

0 голосов
/ 06 января 2009

Вы можете создать небольшой объект даты, который просто преобразует дату по мере необходимости

$Date_p = new MagicDate($php_date);
$Date_m = new MagicDate($mysql_date);

$Date_p и $Date_m просто показывают, что вы можете засадить объект так, как вам нужно. Когда вы хотите дату mysql, вы должны иметь такой код. Реально это было бы что-то довольно общее, как $Date.

$query = "UPDATE SET Date='".$Date_p->toMysql()."' "...

и наоборот, когда вам нужно обратное. Вы можете использовать функции, которые вы уже создали. Просто добавьте «сниффер» в метод конструкции, например:

public function __construct($date)
{
    $phpdate = strtotime($date);
    if($phpdate) 
    {
        $this->phpdate = $phpdate;
        $this->mysqldate = $this->mysql_date($phpdate);
    }
    else
    {
        $this->phpdate = $this->php_date($phpdate);
        $this->mysqldate = $phpdate;
    }
}

Добавьте некоторую обработку ошибок, чтобы поймать вещи, которые идут плохо. Добавьте геттер для двух дат. И это установить и забыть ситуацию. Просто вытащите правильную дату, когда вам это нужно.

Возможны некоторые оптимизации, но это просто для того, чтобы показать вам, как это может работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...