2016-07-02 3 views
0

Я создал функцию для изменения заданного Y-m-d даты: 2016-07-02 в этот формат: July 2nd.Условные тернарные ошибки оператора (PHP)

Код:

// Format the given Y-M-D date 
function format_date($date) { 
    // Parse the date 
    list($year, $month, $day) = array_values(date_parse($date)); 

    // Give the appropriate subscript to the day number 
    $last_char = substr($day, -1); 
    $pre_last_char = (strlen($day) > 1) ? substr($day, -2, -1) : null; 
    $subscript = ($last_char === "1") ? "st" : 
       ($last_char === "2") ? "nd" : 
       ($last_char === "3") ? "rd" : "th"; 
    $subscript = ($pre_last_char === "1") ? "th" : $subscript; 
    $day .= $subscript; 

    // Get the month's name based on its number 
    $months = [ 
     "1" => "January", 
     "2" => "February", 
     "3" => "March", 
     "4" => "April", 
     "5" => "May", 
     "6" => "June", 
     "7" => "July", 
     "8" => "August", 
     "9" => "September", 
     "10" => "October", 
     "11" => "November", 
     "12" => "December" 
    ]; 
    $month = $months[$month]; 

    // Omit the year if it's this year and assemble the date 
    return $date = ($year === date("Y")) ? "$month $day $year" : "$month $day"; 
} 

Функция работает, как ожидалось, но есть улов. Первый условный тернарный оператор для $subscript возвращает "rd" для каждого числа, которое заканчивается на 1 и 2.

Пример:

echo format_date("2016-01-01"); // It will output January 1rd 

Как я могу исправить это?

+0

Используйте ['daysuf'] (http://php.net/manual/en/datetime.formats.date.php) –

+1

Возможный дубликат [PHP-тернарный оператор не работает как ожидалось] (http: // stackoverflow. com/questions/14214427/php-ternary-operator-not-working-as-expected) –

+1

Если вы хотите исправить свой код, посмотрите [https://eval.in/599572]. Проверьте версию с одной строкой, чтобы лучше визуализировать, где я открывал/закрывал (и). – FirstOne

ответ

4

Documentation гласит:

Примечание: Рекомендуется, чтобы избежать "укладки" тройные выражения. поведение PHP, при использовании более одного трехкомпонентную оператора в одного оператора является неочевидным:

<?php 
// on first glance, the following appears to output 'true' 
echo (true?'true':false?'t':'f'); 

// however, the actual output of the above is 't' 
// this is because ternary expressions are evaluated from left to right 

// the following is a more obvious version of the same code as above 
echo ((true ? 'true' : false) ? 't' : 'f'); 

// here, you can see that the first expression is evaluated to 'true', which 
// in turn evaluates to (bool)true, thus returning the true branch of the 
// second ternary expression. 
?> 
+0

Алекс, спасибо за детали, которые вы вошли в свой ответ. Кажется, я снова упал в той же ловушке, не вернувшись в скобки. Я попробовал ваше предложение, и это сработало! –

2

Не является прямым ответ на ваш вопрос, но если вам нужно только на английском языке, как в вашем примере, вы можете использовать стандартную date функцию РНР:

echo date('F jS', strtotime('2016-01-01')); 

Выход:

1 январь

См. working example here.

+1

Спасибо @jeroen. Я не знал об этой функции. Upvoted! –

2

Это потому, что PHP получил тройной оператор неправильно - это left-associative вместо right-associative of C, Java and so forth. Таким образом, при преобразовании кода C в PHP вы должны заключить в скобки выражения «true» и «false».

+0

Большое спасибо за ссылки @Antti. –

Смежные вопросы