Дружелюбный формат#

Как превратить “сухие” даты из базы данных в понятные человеку форматы: “2 минуты назад”, “вчера” или “сегодня”. Разбираем логику, алгоритмы и практическую реализацию дружелюбного отображения времени — как в соцсетях и уведомлениях на телефоне

В данном примере разбираем представление на примере типа Момент, при необходимости, вы всегда можете выполнить ВМомент() над требуемым типом, например ДатаВремя

Базовые методы для работы с типом Момент#

Для того, чтобы timestamp стал более человекочитаемым, можете скопировать и сохранить себе в проект следующие методы:

xbsl
@ВПроекте
метод ТекущийЧасовойПояс(): ЧасовойПояс
    возврат ЧасовойПояс.Текущий()
;

@ВПроекте
метод ТекущаяДатаВремя(): Момент
    возврат Момент.Сейчас()
;

@ВПроекте
метод НачалоДня(Момент: Момент): Момент
    возврат Момент.ВДатаВремя(ТекущийЧасовойПояс()).НачалоДня().ВМомент(ТекущийЧасовойПояс())
;

@ВПроекте
метод КонецДня(Момент: Момент): Момент
    возврат Момент.ВДатаВремя(ТекущийЧасовойПояс()).КонецДня().ВМомент(ТекущийЧасовойПояс())
;

@ВПроекте
метод ДобавитьГоды(Момент: Момент, Годы: Число): Момент
    возврат Момент.ВДатаВремя(ТекущийЧасовойПояс()).ДобавитьГоды(Годы).ВМомент(ТекущийЧасовойПояс())
;

@ВПроекте
метод ДобавитьДни(Момент: Момент, Дней: Число): Момент
    возврат Момент.ВДатаВремя(ТекущийЧасовойПояс()).ДобавитьДни(Дней).ВМомент(ТекущийЧасовойПояс())
;

@ВПроекте
метод ДобавитьМинуты(Момент: Момент, Минут: Число): Момент
    возврат Момент.ВДатаВремя(ТекущийЧасовойПояс()).ДобавитьМинуты(Минут).ВМомент(ТекущийЧасовойПояс())
;

@ВПроекте
метод ДобавитьСекунды(Момент: Момент, Секунд: Число): Момент
    возврат Момент.ВДатаВремя(ТекущийЧасовойПояс()).ДобавитьСекунды(Секунд).ВМомент(ТекущийЧасовойПояс())
;

Дружелюбный формат#

xbsl
@ВПроекте @НаКлиенте @НаСервере
метод ОтносительноеПредставлениеМоментаВремени(МоментВремени: Момент?, ДетализацияМинут: Булево = Ложь): Строка
    
    знч ТекущийМоментВремени = Момент.Сейчас()
    
    если МоментВремени == Неопределено
        возврат ""
    ;
    
    знч НачалоТекущегоДня: Момент = НачалоДня(ТекущийМоментВремени)
    знч НачалоМоментаВремени: Момент = НачалоДня(МоментВремени)
    
    пер ОтносительноеПредставление: Строка
    
    если ДетализацияМинут
        знч РазницаМоментов = (ТекущийМоментВремени - МоментВремени)
        если РазницаМоментов.Дни < 1
            если РазницаМоментов.Часы < 1
                если РазницаМоментов.Минуты < 1
                    ОтносительноеПредставление = "Только что"
                иначе
                    ОтносительноеПредставление = "${РазницаМоментов.Минуты} мин назад"      
                ;
            иначе 
                ОтносительноеПредставление = "${РазницаМоментов.Часы} ч назад"        
            ;
        иначе
            ОтносительноеПредставление = ОтносительноеПредставлениеМоментаБезДетализацииМинут(НачалоМоментаВремени, НачалоТекущегоДня)    
        ;    
    иначе
        ОтносительноеПредставление = ОтносительноеПредставлениеМоментаБезДетализацииМинут(НачалоМоментаВремени, НачалоТекущегоДня) 
    ;
    
    если ОтносительноеПредставление.Пусто()
        знч ТекущийЧасовойПояс = ТекущийЧасовойПояс()
        знч МоментВремениДатой = МоментВремени.ВДатаВремя(ТекущийЧасовойПояс) 
        ОтносительноеПредставление = МоментВремениДатой.Представление("дд.ММ.гггг")   
    ;
    
    возврат ОтносительноеПредставление
    
;

Вспомогательные методы#

Представление минут

xbsl
@ВПроекте @НаКлиенте @НаСервере
метод ПредставлениеДетализацииМинут(Значение: Число): Строка
    если 11 <= Значение и Значение <= 14
        возврат "минут"
    ;
    возврат "минут"
;

Представление timestamt без детализации

xbsl
@Локально @НаКлиенте @НаСервере
метод ОтносительноеПредставлениеМоментаБезДетализацииМинут(НачалоМоментаВремени: Момент, НачалоТекущегоДня: Момент): Строка
        
    пер ОтносительноеПредставление: Строка
    
    выбор
    когда НачалоМоментаВремени == НачалоТекущегоДня
        ОтносительноеПредставление = "Сегодня"
    когда ДобавитьДни(НачалоМоментаВремени, 1) == НачалоТекущегоДня
        ОтносительноеПредставление = "Вчера"
    когда ДобавитьДни(НачалоМоментаВремени, 2) == НачалоТекущегоДня
        ОтносительноеПредставление = "Позавчера"
    когда ДобавитьДни(НачалоМоментаВремени, -1) == НачалоТекущегоДня
        ОтносительноеПредставление = "Завтра"
    когда ДобавитьДни(НачалоМоментаВремени, -2) == НачалоТекущегоДня
        ОтносительноеПредставление = "Послезавтра"
    ;
    
    возврат ОтносительноеПредставление
  
;