将Unix时间转换为日期&没有使用任何库或预定义助手的时间

时间:2016-08-18 04:23:50

标签: php datetime unix

我在面试问题中询问过如何将Unix日期时间整数转换为日期和时间。时间。我被震惊了,因为我一直在使用图书馆而且我只能转换到一年。据我所知,我在这里寻求专家帮助我解决我无法解决的难题。我使用PHP编码机制来解决它:

for i in ${!array[@]}; 
do
array1+=( "${array[$i]}|" )
done

然而,当我迷路时,我无法一个月一天地解决。我在这里寻求专家建议如何解决月份和年份。我无法继续下去。这令人失望。

我不能使用编程语言提供的strtotime或任何预定义的日期时间类。这是给我的限制。听起来很奇怪,但面试的难度很大。

2 个答案:

答案 0 :(得分:0)

例如(通过查找整个单位,这将得到一个近似值),使用下一组中的余数来查找整个单位。每次减少剩余时间的秒数。

$time = 1471488076; //08/18/2016 @ 2:41am (UTC)

$SECONDS_IN_YEAR = 365 * 24 * 60 * 60;
$SECONDS_IN_MONTH = $SECONDS_IN_YEAR / 12;
$SECONDS_IN_DAY = 24 * 60 * 60;
$SECONDS_IN_HOUR = 60 * 60;

$num = floor($time / $SECONDS_IN_YEAR);
echo "\nYears: ".$num . "\n";
$remainingSeconds = $time - ($num * $SECONDS_IN_YEAR);
echo "\nremainder: ".$remainingSeconds . "\n";

$year = 1970 + $num;

$num = floor( $remainingSeconds / $SECONDS_IN_MONTH);
echo "\nMonth: ".$num . "\n";
$remainingSeconds = $remainingSeconds - ($num * $SECONDS_IN_MONTH);
echo "\nremainder: ".$remainingSeconds . "\n";

$month = $num;

$num = floor( $remainingSeconds / $SECONDS_IN_DAY);
echo "\nDay: ".$num . "\n";
$remainingSeconds = $remainingSeconds - ($num * $SECONDS_IN_DAY);
echo "\nremainder: ".$remainingSeconds . "\n";

$day = $num;

$num = floor( $remainingSeconds / $SECONDS_IN_HOUR);
echo "\nHour: ".$num . "\n";
$remainingSeconds = $remainingSeconds - ($num * $SECONDS_IN_HOUR);
echo "\nremainder: ".$remainingSeconds . "\n";

$hour = $num;

$num = floor( $remainingSeconds / 60);
echo "\nMinute: ".$num . "\n";
$remainingSeconds = $remainingSeconds - ($num * 60);
 echo "\nremainder: ".$remainingSeconds . "\n";

 $min = $num;

 $sec = floor($remainingSeconds);

 echo $month."/".$day."/".$year." ".$hour.":".$min.":".$sec;

输出

Years: 46
remainder: 20832076

Month: 7
remainder: 2436076

Day: 28
remainder: 16876

Hour: 4
remainder: 2476

Minute: 41
remainder: 16

7/28/2016 4:41:16

但正如我所描述的那样,每月的平均秒数永远不会是正确的,你需要类似于数组的数据,每个月的秒数你可以循环减去数组直到你消极,然后它那一个月前一个月。然后你将那些秒数加起来,剩下的就是小时分钟和秒。

一旦你越过偶数单位,基本上减少每一个..

如果没有它,它只是一个近似值。即使考虑到它不会占闰年。

可能有更好的方法可以做到这一点,但这只是跳出来获得粗略数字的最简单方法。

答案 1 :(得分:0)

要考虑每月/每年的可变天数,还有一些工作要做,但并不是那么糟糕。基本思想是迭代,直到时间戳上没有剩余的时间。

处理负时间戳是留给读者的练习。

示例:

const SECONDS_PER_MINUTE = 60;
const SECONDS_PER_HOUR = 60 * SECONDS_PER_MINUTE;
const SECONDS_PER_DAY = 24 * SECONDS_PER_HOUR;

const DAYS_PER_YEAR = 365;
const DAYS_PER_LEAP_YEAR = DAYS_PER_YEAR + 1;

const EPOCH_MONTH = 1;
const EPOCH_YEAR = 1970;

function getDateTime(int $timestamp) : array
{
    $days = intdiv($timestamp, SECONDS_PER_DAY);

    $year = EPOCH_YEAR;
    while ($days >= getDaysForYear($year)) {
        $days -= getDaysForYear($year);
        $year++;
    }

    $daysPerMonth = getDaysPerMonth($year);
    $month = EPOCH_MONTH;
    while ($days >= $daysPerMonth[$month]) {
        $days -= $daysPerMonth[$month];
        $month++;
    }

    $day = $days + 1;

    $secondsRemaining = $timestamp % SECONDS_PER_DAY;
    $hour = intdiv($secondsRemaining, SECONDS_PER_HOUR);
    $minute = intdiv($secondsRemaining, SECONDS_PER_MINUTE) % SECONDS_PER_MINUTE;
    $second = $secondsRemaining % SECONDS_PER_MINUTE;

    return [
        'year' => $year,
        'month' => $month,
        'day' => $day,
        'hour' => $hour,
        'minute' => $minute,
        'second' => $second
    ];
}

function isLeapYear(int $year) : bool
{
    return $year % 400 === 0 || ($year % 4 === 0 && $year % 100 !== 0);
}

function getDaysForYear(int $year) : int {
    return isLeapYear($year) ? DAYS_PER_LEAP_YEAR : DAYS_PER_YEAR;
}

function getDaysPerMonth(int $year) : array
{
    return [0, 31, isLeapYear($year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
}


$time = 1471488076; //08/18/2016 @ 2:41am (UTC)
print_r(getDateTime($time));

<强>输出:

Array
(
    [year] => 2016
    [month] => 8
    [day] => 18
    [hour] => 2
    [minute] => 41
    [second] => 16
)

您可以随意拍摄和格式化。

Online demo.