`time`-modifier now behaves as its JS counterpart
authorAlexander Ebert <ebert@woltlab.com>
Sun, 24 Jan 2016 12:26:25 +0000 (13:26 +0100)
committerAlexander Ebert <ebert@woltlab.com>
Sun, 24 Jan 2016 12:26:37 +0000 (13:26 +0100)
com.woltlab.wcf/templates/headIncludeJavaScript.tpl
wcfsetup/install/files/acp/templates/header.tpl
wcfsetup/install/files/lib/system/template/plugin/TimeModifierTemplatePlugin.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index 082ef72e7f26e6c74eadefd5bf4a6f1c84037c4d..e414fd2b45968db8046f79b32b5dca332cc00864 100644 (file)
@@ -28,10 +28,10 @@ requirejs.config({
                        '__months': [ '{lang}wcf.date.month.january{/lang}', '{lang}wcf.date.month.february{/lang}', '{lang}wcf.date.month.march{/lang}', '{lang}wcf.date.month.april{/lang}', '{lang}wcf.date.month.may{/lang}', '{lang}wcf.date.month.june{/lang}', '{lang}wcf.date.month.july{/lang}', '{lang}wcf.date.month.august{/lang}', '{lang}wcf.date.month.september{/lang}', '{lang}wcf.date.month.october{/lang}', '{lang}wcf.date.month.november{/lang}', '{lang}wcf.date.month.december{/lang}' ], 
                        '__monthsShort': [ '{lang}wcf.date.month.short.jan{/lang}', '{lang}wcf.date.month.short.feb{/lang}', '{lang}wcf.date.month.short.mar{/lang}', '{lang}wcf.date.month.short.apr{/lang}', '{lang}wcf.date.month.short.may{/lang}', '{lang}wcf.date.month.short.jun{/lang}', '{lang}wcf.date.month.short.jul{/lang}', '{lang}wcf.date.month.short.aug{/lang}', '{lang}wcf.date.month.short.sep{/lang}', '{lang}wcf.date.month.short.oct{/lang}', '{lang}wcf.date.month.short.nov{/lang}', '{lang}wcf.date.month.short.dec{/lang}' ],
                        'wcf.clipboard.item.unmarkAll': '{lang}wcf.clipboard.item.unmarkAll{/lang}',
-                       'wcf.date.relative.now': '{lang}wcf.date.relative.now{/lang}',
-                       'wcf.date.relative.minutes': '{capture assign=relativeMinutes}{lang}wcf.date.relative.minutes{/lang}{/capture}{@$relativeMinutes|encodeJS}',
-                       'wcf.date.relative.hours': '{capture assign=relativeHours}{lang}wcf.date.relative.hours{/lang}{/capture}{@$relativeHours|encodeJS}',
-                       'wcf.date.relative.pastDays': '{capture assign=relativePastDays}{lang}wcf.date.relative.pastDays{/lang}{/capture}{@$relativePastDays|encodeJS}',
+                       'wcf.date.relative.now': '{lang}wcf.date.relative.nowJS{/lang}',
+                       'wcf.date.relative.minutes': '{capture assign=relativeMinutes}{lang}wcf.date.relative.minutesJS{/lang}{/capture}{@$relativeMinutes|encodeJS}',
+                       'wcf.date.relative.hours': '{capture assign=relativeHours}{lang}wcf.date.relative.hoursJS{/lang}{/capture}{@$relativeHours|encodeJS}',
+                       'wcf.date.relative.pastDays': '{capture assign=relativePastDays}{lang}wcf.date.relative.pastDaysJS{/lang}{/capture}{@$relativePastDays|encodeJS}',
                        'wcf.date.dateFormat': '{lang}wcf.date.dateFormat{/lang}',
                        'wcf.date.dateTimeFormat': '{lang}wcf.date.dateTimeFormat{/lang}',
                        'wcf.date.shortDateTimeFormat': '{lang}wcf.date.shortDateTimeFormat{/lang}',
index d130cd8a42f0cd02ae54341809cc370b5cdedd4b..e64c7f108ee75784427a017f05e8deb1e525126f 100644 (file)
                                '__monthsShort': [ '{lang}wcf.date.month.short.jan{/lang}', '{lang}wcf.date.month.short.feb{/lang}', '{lang}wcf.date.month.short.mar{/lang}', '{lang}wcf.date.month.short.apr{/lang}', '{lang}wcf.date.month.short.may{/lang}', '{lang}wcf.date.month.short.jun{/lang}', '{lang}wcf.date.month.short.jul{/lang}', '{lang}wcf.date.month.short.aug{/lang}', '{lang}wcf.date.month.short.sep{/lang}', '{lang}wcf.date.month.short.oct{/lang}', '{lang}wcf.date.month.short.nov{/lang}', '{lang}wcf.date.month.short.dec{/lang}' ],
                                'wcf.acp.search.noResults': '{lang}wcf.acp.search.noResults{/lang}',
                                'wcf.clipboard.item.unmarkAll': '{lang}wcf.clipboard.item.unmarkAll{/lang}',
-                               'wcf.date.relative.now': '{lang}wcf.date.relative.now{/lang}',
-                               'wcf.date.relative.minutes': '{capture assign=relativeMinutes}{lang}wcf.date.relative.minutes{/lang}{/capture}{@$relativeMinutes|encodeJS}',
-                               'wcf.date.relative.hours': '{capture assign=relativeHours}{lang}wcf.date.relative.hours{/lang}{/capture}{@$relativeHours|encodeJS}',
-                               'wcf.date.relative.pastDays': '{capture assign=relativePastDays}{lang}wcf.date.relative.pastDays{/lang}{/capture}{@$relativePastDays|encodeJS}',
+                               'wcf.date.relative.now': '{lang}wcf.date.relative.nowJS{/lang}',
+                               'wcf.date.relative.minutes': '{capture assign=relativeMinutes}{lang}wcf.date.relative.minutesJS{/lang}{/capture}{@$relativeMinutes|encodeJS}',
+                               'wcf.date.relative.hours': '{capture assign=relativeHours}{lang}wcf.date.relative.hoursJS{/lang}{/capture}{@$relativeHours|encodeJS}',
+                               'wcf.date.relative.pastDays': '{capture assign=relativePastDays}{lang}wcf.date.relative.pastDaysJS{/lang}{/capture}{@$relativePastDays|encodeJS}',
                                'wcf.date.dateFormat': '{lang}wcf.date.dateFormat{/lang}',
                                'wcf.date.dateTimeFormat': '{lang}wcf.date.dateTimeFormat{/lang}',
                                'wcf.date.shortDateTimeFormat': '{lang}wcf.date.shortDateTimeFormat{/lang}',
index 8bbaf4c61f94364e61d4ff4d38127843f29e9136..1c7c478ee2767f5767878a3f2417557d3b7a88a9 100644 (file)
@@ -28,8 +28,66 @@ class TimeModifierTemplatePlugin implements IModifierTemplatePlugin {
                $dateTimeObject = DateUtil::getDateTimeByTimestamp($timestamp);
                $date = DateUtil::format($dateTimeObject, DateUtil::DATE_FORMAT);
                $time = DateUtil::format($dateTimeObject, DateUtil::TIME_FORMAT);
-               $dateTime = str_replace('%time%', $time, str_replace('%date%', $date, WCF::getLanguage()->get('wcf.date.dateTimeFormat')));
+               $isFutureDate = ($timestamp > TIME_NOW);
+               $dateTime = $this->getRelativeTime($dateTimeObject, $timestamp, $date, $time, $isFutureDate);
                
-               return '<time datetime="'.DateUtil::format($dateTimeObject, 'c').'" class="datetime" data-timestamp="'.$timestamp.'" data-date="'.$date.'" data-time="'.$time.'" data-offset="'.$dateTimeObject->getOffset().'"'.($timestamp > TIME_NOW ? ' data-is-future-date="true"' : '').'>'.$dateTime.'</time>';
+               return '<time datetime="'.DateUtil::format($dateTimeObject, 'c').'" class="datetime" data-timestamp="'.$timestamp.'" data-date="'.$date.'" data-time="'.$time.'" data-offset="'.$dateTimeObject->getOffset().'"'.($isFutureDate ? ' data-is-future-date="true"' : '').'>'.$dateTime.'</time>';
+       }
+       
+       /**
+        * Returns the relative date time identical to the relative time generated
+        * through JavaScript.
+        * 
+        * @param       \DateTime       $dateTimeObject         target date object
+        * @param       integer         $timestamp              target timestamp
+        * @param       string          $date                   localized date
+        * @param       string          $time                   localized time
+        * @param       boolean         $isFutureDate           true if timestamp is in the future
+        * @return      string          relative time
+        */
+       protected function getRelativeTime(\DateTime $dateTimeObject, $timestamp, $date, $time, $isFutureDate) {
+               if ($isFutureDate) {
+                       return str_replace('%time%', $time, str_replace('%date%', $date, WCF::getLanguage()->get('wcf.date.dateTimeFormat')));
+               }
+               
+               // timestamp is less than 60 seconds ago
+               if ($timestamp >= TIME_NOW || TIME_NOW < ($timestamp + 60)) {
+                       return WCF::getLanguage()->get('wcf.date.relative.now');
+               }
+               // timestamp is less than 60 minutes ago (display 1 hour ago rather than 60 minutes ago)
+               else if (TIME_NOW < ($timestamp + 3540)) {
+                       $minutes = max(round((TIME_NOW - $timestamp) / 60), 1);
+                       
+                       return WCF::getLanguage()->getDynamicVariable('wcf.date.relative.minutes', ['minutes' => $minutes]);
+               }
+               // timestamp is less than 24 hours ago
+               else if (TIME_NOW < ($timestamp + 86400)) {
+                       $hours = round((TIME_NOW - $timestamp) / 3600);
+                       
+                       return WCF::getLanguage()->getDynamicVariable('wcf.date.relative.hours', ['hours' => $hours]);
+               }
+               // timestamp is less than 6 days ago
+               else if (TIME_NOW < ($timestamp + 518400)) {
+                       $dtoNoTime = clone $dateTimeObject;
+                       $dtoNoTime->setTime(0, 0, 0);
+                       $currentDateTimeObject = DateUtil::getDateTimeByTimestamp(TIME_NOW);
+                       $currentDateTimeObject->setTime(0, 0, 0);
+                       
+                       $days = $dtoNoTime->diff($currentDateTimeObject)->days;
+                       $day = DateUtil::format($dateTimeObject, 'l');
+                       
+                       return WCF::getLanguage()->getDynamicVariable('wcf.date.relative.pastDays', [
+                               'days' => $days,
+                               'day' => $day,
+                               'time' => $time
+                       ]);
+               }
+               
+               // timestamp is between ~700 million years BC and last week
+               $datetime = WCF::getLanguage()->get('wcf.date.shortDateTimeFormat');
+               $datetime = str_replace('%date%', $date, $datetime);
+               $datetime = str_replace('%time%', $time, $datetime);
+               
+               return $datetime;
        }
 }
index cf98c85612916c43a728019790ea66d4655a61f8..0da212645d9c1af1ac1f7ff65583ac59f66aeafd 100644 (file)
@@ -2017,11 +2017,18 @@ Fehler sind beispielsweise:
                <item name="wcf.date.period.today"><![CDATA[Heute]]></item>
                <item name="wcf.date.period.yesterday"><![CDATA[Gestern]]></item>
                
-               <!-- variables for dynamic javascript datetime -->
+               <!-- variables for relative datetime for use in PHP -->
                <item name="wcf.date.relative.now"><![CDATA[Vor einem Moment]]></item>
-               <item name="wcf.date.relative.minutes"><![CDATA[{literal}Vor {if $minutes > 1}{#$minutes} Minuten{else}einer Minute{/if}{/literal}]]></item>
-               <item name="wcf.date.relative.hours"><![CDATA[{literal}Vor {if $hours > 1}{#$hours} Stunden{else}einer Stunde{/if}{/literal}]]></item>
-               <item name="wcf.date.relative.pastDays"><![CDATA[{literal}{if $days > 1}{$day}{else}Gestern{/if}, {$time}{/literal}]]></item>
+               <item name="wcf.date.relative.minutes"><![CDATA[Vor {if $minutes > 1}{#$minutes} Minuten{else}einer Minute{/if}]]></item>
+               <item name="wcf.date.relative.hours"><![CDATA[Vor {if $hours > 1}{#$hours} Stunden{else}einer Stunde{/if}]]></item>
+               <item name="wcf.date.relative.pastDays"><![CDATA[{if $days > 1}{$day}{else}Gestern{/if}, {$time}]]></item>
+               
+               <!-- variables for relative datetime for use in JavaScript -->
+               <!-- should match the variables above but wrapped in {literal}…{/literal} -->
+               <item name="wcf.date.relative.nowJS"><![CDATA[Vor einem Moment]]></item>
+               <item name="wcf.date.relative.minutesJS"><![CDATA[{literal}Vor {if $minutes > 1}{#$minutes} Minuten{else}einer Minute{/if}{/literal}]]></item>
+               <item name="wcf.date.relative.hoursJS"><![CDATA[{literal}Vor {if $hours > 1}{#$hours} Stunden{else}einer Stunde{/if}{/literal}]]></item>
+               <item name="wcf.date.relative.pastDaysJS"><![CDATA[{literal}{if $days > 1}{$day}{else}Gestern{/if}, {$time}{/literal}]]></item>
                
                <!-- variables for localized date formats -->
                <item name="wcf.date.hour"><![CDATA[Stunde]]></item>
index cdb32b1bae342371d70ff387a3763c1c663624bf..b55633f52cbcffbc4d1e0e1ff1a86b81ca1c1fff 100644 (file)
@@ -2020,7 +2020,14 @@ Errors are:
                <item name="wcf.date.period.today"><![CDATA[Today]]></item>
                <item name="wcf.date.period.yesterday"><![CDATA[Yesterday]]></item>
                
-               <!-- variables for dynamic javascript datetime -->
+               <!-- variables for relative datetime for use in PHP -->
+               <item name="wcf.date.relative.now"><![CDATA[A moment ago]]></item>
+               <item name="wcf.date.relative.minutes"><![CDATA[{if $minutes > 1}{#$minutes} minutes{else}A minute{/if} ago]]></item>
+               <item name="wcf.date.relative.hours"><![CDATA[{if $hours > 1}{#$hours} hours{else}An hour{/if} ago]]></item>
+               <item name="wcf.date.relative.pastDays"><![CDATA[{if $days > 1}{$day}{else}Yesterday{/if}, {$time}]]></item>
+               
+               <!-- variables for relative datetime for use in JavaScript -->
+               <!-- should match the variables above but wrapped in {literal}…{/literal} -->
                <item name="wcf.date.relative.now"><![CDATA[A moment ago]]></item>
                <item name="wcf.date.relative.minutes"><![CDATA[{literal}{if $minutes > 1}{#$minutes} minutes{else}A minute{/if} ago{/literal}]]></item>
                <item name="wcf.date.relative.hours"><![CDATA[{literal}{if $hours > 1}{#$hours} hours{else}An hour{/if} ago{/literal}]]></item>