Skip to content
Advertisement

Date in a loop – display the first / skip the rest [closed]

A chat has a message date from an SQL database. The timestamp is formatted with php date:

 $dateabove = date("d.m.Y : H:i",$row['message_time']);

The date is in a loop (while):-

Today has to show today and yesterday has to show yesterday. Then only the date comes. It should look something like Whatsapp.

Example:- ( $dateabove – $row[‘message_text’] ) :

me: 28.10.2020 : 13:75  - Hello

you: 28.10.2020 : 14:01  - Hello

me: 31.10.2020 : 11:01  - How are you?

you: 31.10.2020 : 12:01  - fine

me: 01.11.2020 : 10:05  -  Where you from?

Should look like:

*28.10.2020*

me: 28.10.2020 : 13:75  - Hello

you: 28.10.2020 : 14:01  - Hello


*Yesterday*

me: 31.10.2020 : 11:01  - How are you?

you: 31.10.2020 : 12:01  - fine


*Today*

me: 01.11.2020 : 10:05  -  Where you from?

The problem is, how can you only display the date above the first message within the loop and not on the subsequent messages on that day.

This is how my loop looks like:

while ($row = $db->sql_fetchrow($result));

for ($i = 0, $size = sizeof($rowset); $i < $size; $i++)
{
echo $row['message_time']);
}

Advertisement

Answer

Here’s a little demonstration of one possible approach. Please read the comments for a detailed explanation of what’s going on. See this eval for a live demo. You can play around with it and you can see its output.

<?php

// Current time as UNIX timestamp.
$now = time();
// Find yesterday's date by subtracting one day ('P1D') from today (new DateTime).
$yesterday = (new DateTime)->sub(new DateInterval('P1D'));

// Mock a bunch of messages.
$messages =
[
    // Yesterday's messages
    [
        'user_id' => 1,
        'user_natural_name' => 'me',
        // format('U') will give us UNIX timestamp.
        'timestamp' => $yesterday->setTime(19, 0)->format('U'),
        'text' => 'Hiya'
    ],
    [
        'user_id' => 2,
        'user_natural_name' => 'you',
        'timestamp' => $yesterday->setTime(19, 5)->format('U'),
        'text' => 'Hey, how are you?'
    ],
    
    // Today's messages
    [
        'user_id' => 1,
        'user_natural_name' => 'me',
        'timestamp' => $now,
        'text' => 'Hello'
    ],
    [
        'user_id' => 2,
        'user_natural_name' => 'you',
        // Three seconds later.
        'timestamp' => $now + 3,
        'text' => 'Hi'
    ],
    [
        'user_id' => 1,
        'user_natural_name' => 'me',
        'timestamp' => $now + 6,
        'text' => 'What's up'
    ],
    [
        'user_id' => 2,
        'user_natural_name' => 'you',
        'timestamp' => $now + 9,
        'text' => 'Not much'
    ],
    [
        'user_id' => 1,
        'user_natural_name' => 'me',
        'timestamp' => $now + 12,
        'text' => 'Awesome'
    ]
];

// If $lastWindowDate differs from the current message in the queue,
// then display it as a separator between day-to-day conversations.
$lastWindowDate = NULL;

// $index will tell us whether we already had output from earlier days so we can
// show a separating newline.
foreach ($messages as $index => $message)
{
    // Window as a perspective on the message flow.
    $windowDate = date('Ymd', $message['timestamp']);
    // If current message's date is not last message's date, then output it to the user.
    if ($windowDate !== $lastWindowDate)
    {
        // Translate today's YMD and yesterday's YMD to something more naturally interpretable for a better UX.

        // Compare against current message's datestamp.
        switch (date('Ymd', $message['timestamp']))
        {
            // date('Ymd') without a second argument defaults to 'today'.
            case date('Ymd'):
                $dateLabel = 'today';
            break;
            // Format $yesterday DateTime as Ymd.
            case $yesterday->format('Ymd'):
                $dateLabel = 'yesterday';
            break;
            // Neither? Pass through as numeric date.
            default:
                $dateLabel = $windowDate;
            break;
        }
        
        // Already had previous output? Show a newline now as visual separator.
        if ($index)
            echo "n";

        // Output date label at the top of message list for that day.
        echo "$dateLabeln";
        
        // Reset the last date seen for the conditional to work.
        $lastWindowDate = $windowDate;
    }
 
    // Show message.   
    echo "{$message['user_natural_name']}: " . date('d.m.Y : H:i', $message['timestamp']) . " - {$message['text']}n";
}
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement