Skip to content

Instantly share code, notes, and snippets.

@Frago9876543210
Last active April 30, 2019 13:50
Show Gist options
  • Save Frago9876543210/a6d8adaae7bf6db8433841bdd8213ec3 to your computer and use it in GitHub Desktop.
Save Frago9876543210/a6d8adaae7bf6db8433841bdd8213ec3 to your computer and use it in GitHub Desktop.
<?php
declare(strict_types=1);
namespace converter;
use function intdiv;
use function min;
class TimeUtils{
//@formatter:off
public const YEAR = 31536000;
public const MONTH = 2592000;
public const WEEK = 604800;
public const DAY = 86400;
public const HOUR = 3600;
public const MIN = 60;
public const SEC = 1;
private const UNITS_OF_TIME = [self::YEAR, self::MONTH, self::WEEK, self::DAY, self::HOUR, self::MIN, self::SEC];
private const NOMINATIVE_CASE = [
self::YEAR => ['год', 'года', 'лет'],
self::MONTH => ['месяц', 'месяца', 'месяцев'],
self::WEEK => ['неделя', 'недели', 'недель'],
self::DAY => ['день', 'дня', 'дней'],
self::HOUR => ['час', 'часа', 'часов'],
self::MIN => ['минута', 'минуты', 'минут'],
self::SEC => ['секунда', 'секунды', 'секунд']
];
private const ACCUSATIVE_CASE = [
self::YEAR => self::NOMINATIVE_CASE[self::YEAR],
self::MONTH => self::NOMINATIVE_CASE[self::MONTH],
self::WEEK => ['неделю', 'недели', 'недель'],
self::DAY => self::NOMINATIVE_CASE[self::DAY],
self::HOUR => self::NOMINATIVE_CASE[self::HOUR],
self::MIN => ['минуту', 'минуты', 'минут'],
self::SEC => ['секунду', 'секунды', 'секунд']
];
//@formatter:on
/**
* @param int $number
* @param array $format [1, 2, 5]
*
* @return string
*/
public static function correctForm(int $number, array $format) : string{
return $number . ' ' . $format[($number % 100 > 4 && $number % 100 < 20) ? 2 : [2, 0, 1, 1, 1, 2][min($number % 10, 5)]];
}
/**
* @param int $time
* @param bool $accusative (винительный падеж, используйте перед словом "через")
*
* @return string
*/
public static function timestamp2word(int $time, bool $accusative = true) : string{
$result = '';
$case = $accusative ? self::ACCUSATIVE_CASE : self::NOMINATIVE_CASE;
$it = 0;
foreach(self::UNITS_OF_TIME as $unit){
if(($perUnit = intdiv($time, $unit)) > 0){
$time -= $perUnit * $unit;
if(($lastUnit = $time === 0) && $it > 0){
$result .= 'и ';
}
$result .= self::correctForm($perUnit, $case[$unit]) . ($lastUnit ? '' : ' ');
$it++;
}
}
return $result;
}
}
/**
* Examples
*/
echo 'Вытащите пирог из духовки через ' . TimeUtils::timestamp2word(61) . PHP_EOL;
$newYear = (mktime(0, 0, 0, 1, 1, date('Y') + 1) - time());
echo 'До нового года осталось: ' . TimeUtils::timestamp2word($newYear, false) . PHP_EOL;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment