• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

PHP Code to show relative date/time for Threads

LPH

Well-known member
#1
Code currently uses the WordPress method of date time format but the XenForo way of showing the relative date information is much nicer. How is this done in XenForo?

Current code:
PHP:
        $featured_forum_threads = $featured_threadModel->getThreadsInForum( $featured_forum, $conditions, $fetchOptions );

        foreach ( $featured_forum_threads as $featured_forum_thread) {
           
            $threadTitle        = $featured_forum_thread['title'];
            $threadDate         = date_i18n( get_option('date_format'), $featured_forum_thread['post_date'] );
            $lastThreadDate     = date_i18n( get_option('date_format'), $featured_forum_thread['last_post_date'] );
        }
Reading older threads suggests people were using 'l, F j - g:i a' but that isn't relative and would always show the name of the day of the week, etc.

XenForo_Input::DATE_TIME is simply returning a string.

Any suggestions?
 

LPH

Well-known member
#3
Thank you. I was looking at XenForo_Locale::getRelativeDateTime() and trying to figure out how to call it.
 

katsulynx

Well-known member
#4
No problem. If you need any further help just ask. Was only short on time this morning, so I had only time to locate the files for you.
 

LPH

Well-known member
#5
This is the current state of trying to get relative time outside of XenForo on a WordPress widget.

1. Created a file named class-xenword-relative.php which is based off the human_time_diff in WordPress.

PHP:
<?php

/**
 * Filename: class-xenword-relative-time.php
 *
 * Formats time in human readable format.
 *
 * Based on human_time_diff in /wp-includes/formatting.php
 */

class XenWord_Time {

    public static function xenword_time_diff( $from, $to = '' ) {
        if ( empty( $to ) ) {
            $to = time();
        }

        $diff = (int) abs( $to - $from );

        if ( $diff < HOUR_IN_SECONDS ) {
            $mins = round( $diff / MINUTE_IN_SECONDS );
            if ( $mins <= 1 )
                $mins = 1;
            /* translators: min=minute */
            $since = sprintf( _n( '%s min', '%s mins', $mins ), $mins );
        } elseif ( $diff < DAY_IN_SECONDS && $diff >= HOUR_IN_SECONDS ) {
            $hours = round( $diff / HOUR_IN_SECONDS );
            if ( $hours <= 1 )
                $hours = 1;
            $since = sprintf( _n( '%s hour', '%s hours', $hours ), $hours );
        } elseif ( $diff < WEEK_IN_SECONDS && $diff >= DAY_IN_SECONDS ) {
            $days = round( $diff / DAY_IN_SECONDS );
            if ( $days <= 1 )
                $days = 1;
            $since = sprintf( _n( '%s day', '%s days', $days ), $days );
        } elseif ( $diff < MONTH_IN_SECONDS && $diff >= WEEK_IN_SECONDS ) {
            $weeks = round( $diff / WEEK_IN_SECONDS );
            if ( $weeks <= 1 )
                $weeks = 1;
            $since = sprintf( _n( '%s week', '%s weeks', $weeks ), $weeks );
        } elseif ( $diff < YEAR_IN_SECONDS && $diff >= MONTH_IN_SECONDS ) {
            $months = round( $diff / MONTH_IN_SECONDS );
            if ( $months <= 1 )
                $months = 1;
            $since = sprintf( _n( '%s month', '%s months', $months ), $months );
        } elseif ( $diff >= YEAR_IN_SECONDS ) {
            $years = round( $diff / YEAR_IN_SECONDS );
            if ( $years <= 1 )
                $years = 1;
            $since = sprintf( _n( '%s year', '%s years', $years ), $years );
        }

        /**
        * Filter the human readable difference between two timestamps.
        *
        * @since 4.0.0
        *
        * @param string $since The difference in human readable text.
        * @param int    $diff  The difference in seconds.
        * @param int    $from  Unix timestamp from which the difference begins.
        * @param int    $to    Unix timestamp to end the time difference.
        */
        return apply_filters( 'xenword_time_diff', $since, $diff, $from, $to );
    }
}

new XenWord_Time();

// End class-xenword-relative-time.php
2. Call method in the featured forum widget

PHP:
$threadDate         = XenWord_Time::xenword_time_diff( $featured_forum_thread['post_date'], XenForo_Application::$time ) . ' ago';
$lastThreadDate     = XenWord_Time::xenword_time_diff( $featured_forum_thread['last_post_date'], XenForo_Application::$time ) . ' ago';
The XenWord_Time::xenword_time_diff isn't perfect. There is no "yesterday" and I need to change the cut off so that month, date, year are shown after certain time difference. The "Today at " isn't there either.

Please let me know if you have any suggestions. It would be nicer to simply have a XenForo human readable time method to call.
 

LPH

Well-known member
#6
My times are off for some reason. It can be noon at the post will say "Today at 6pm." Guess I'll have to break this apart some more.
 

Jeremy P

Well-known member
#7
For what it's worth, XenForo accomplishes this with JavaScript, which is a better solution for lots of reasons. It allows the relative information to be updated without page refreshes, and the correct timestamps can be picked up by things like search engines/caches/etc.
 

LPH

Well-known member
#8
XenForo accomplishes this with JavaScript
It's worth tons, but I don't know how to call the XenForo script properly so that it formats it. Was looking through the code and couldn't find something that made sense to me. This is why I built my own, which is off on time.

Can you point in me in the right direction to call it externally (from a WP post, page, etc)?
 

Jeremy P

Well-known member
#9
I believe it's a matter of including xenforo.js on your pages and formatting the elements in a way XF expects. The latter is the tricky part. A relevant element in XF looks like:
Code:
<span class="DateTime" title="Mar 25, 2016 at 4:29 PM">Mar 25, 2016</span></a>
Having the "DateTime" class on your element is key.