【问题标题】:Laravel Carbon - Calculate time between database entriesLaravel Carbon - 计算数据库条目之间的时间
【发布时间】:2017-11-24 11:03:14
【问题描述】:

我正在尝试计算两个日期时间之间的差异。

我有两个模型,taskstask_interactions,它们之间的关系是这样的:tasks 有很多 task_interactionstask_interactions 属于 tasks

用户可以将任务的状态更改为以下状态之一:“进行中”、“暂停”和已完成。用户在“进行中”和“暂停”之间多次更改状态,但一旦完成,用户就无法再更改任务状态。

所有交互都保存在task_interactions 表中,created_by 作为 user_id,created_at 作为日期时间。该表有这些列:id ; task_id ; status ; comments ; created_by ; created_at

这是任务 id = 1 的示例:

# id, task_id, status, comments, created_by, created_at
144, 1, In Progress, , 1, 2017-11-14 09:42:20
145, 1, Paused, , 1, 2017-11-14 09:45:53
146, 1, In Progress, , 1, 2017-11-14 09:46:57
147, 1, Paused, , 1, 2017-11-14 09:49:57
148, 1, In Progress, , 1, 2017-11-14 10:00:10
149, 1, Paused, , 1, 2017-11-14 10:06:25
150, 1, In Progress, , 1, 2017-11-14 10:07:26
151, 1, Paused, , 1, 2017-11-14 10:08:11
153, 1, Paused, , 1, 2017-11-14 11:27:04
154, 1, In Progress, , 1, 2017-11-14 11:27:21
155, 1, Paused, , 1, 2017-11-14 11:57:38

问题是,对于我来说,要获得一项任务所花费的总时间,我必须确定 In ProgressPaused 之间的时间。 PausedIn Progress 之间的时间不相关。

我正在为此苦苦挣扎。有没有人可以帮助我?

提前致谢。

还有一件事,我不是很有经验,所以如果我的问题听起来有点愚蠢,请原谅,我相信我应该在 task_id = X 的所有 task_interactions 中做一个@foreach 循环,这就是我所知道的。

按照要求,这是我为视图传递的数据:

public function mytasks()
    {
        $users = User::all();
        $mytasks = Task::where('assigned_to','=', Auth::id())->where('status','!=','Finished')->get(); 
        $mytaskscount = Task::where('assigned_to','=', Auth::id())->count();
        $tasksinprogress = Task::where('status','=','In Progress')->where('assigned_to','=', Auth::id())->get();
        $tasksinprogresscount = Task::where('status','=','In Progress')->where('assigned_to','=', Auth::id())->count();
        $taskspaused = Task::where('status','=','Paused')->where('assigned_to','=', Auth::id())->get();
        $taskspausedcount = Task::where('status','=','Paused')->where('assigned_to','=', Auth::id())->count();
        $tasksfinished = Task::where('status','=','Finished')->where('assigned_to','=', Auth::id())->get();
        $tasksfinishedcount = Task::where('status','=','Finished')->where('assigned_to','=', Auth::id())->count();
        $tasktypes = Tasktype::all();
        $chapters = Chapter::all();

        return view('pages.tasks_my', compact('mytasks','tasktypes','chapters','tasksinprogress','taskspaused','tasksfinished','mytaskscount','tasksinprogresscount','taskspausedcount','tasksfinishedcount'));
    }

还有一件事,我目前所知道的

@foreach ($tasks as $task)
    @foreach ($task->interactions as $interactions)
{{ In here, every time my loop returns a status = "In progress" i should mark that time, and if that the next loop returns a "Paused", i should count the difference between these two. And sum all other equal cases in the loop. }}
    @endforeach
@endforeach

我真的不知道该怎么做

【问题讨论】:

  • 你能推动你的控制器吗?
  • 我也想知道这个问题的答案
  • 您是否亲自负责让 db 查询来处理这个问题?想到的是通过 php 迭代结果。

标签: laravel php-carbon


【解决方案1】:

我会推荐大卫的答案。如果您不习惯使用 MySQL。您可能必须这样做:

计算任务首次启动与暂停时间之间的差异:

$start = Carbon::parse($startTask->created_at);
$pause = Carbon::parse($endTask->created_at);

$diffInSeconds = $pause->diffInSeconds($start)

这应该以秒为单位为您提供任务开始和暂停时间的总差异。现在,您必须重复这种方法,以便再次启动和暂停任务。

【讨论】:

  • 这听起来可能有点奇怪,我理解你的方法,但我不知道如何将它放在 foreach 循环中。我不是很有经验,通常我所做的是在控制器中过滤我需要的数据,然后在我的视图中处理该信息。我知道错了
  • 这很容易,因为您需要将任务的所有暂停和开始条目作为数组获取。然后,您只需解析任务的开始条目。
  • 我试试看。非常感谢
【解决方案2】:

这是严格的 Mysql,但应该可以解决问题。 您可以在 laravel 中直接使用原始 sql 指令调用它,或者您应该将其重新编写成 Laravel 代码。

select SEC_TO_TIME(
    sum( 
        timediff(
            if(task_end.created_at is null, 
               NOW(), 
               task_end.created_at), 
            task_start.created_at)))
from task_interactions task_start
left join task_interactions task_end
    ON task_end.task_id = task_start.task_id
    AND task_end.status IN ('Pause', 'Finished')
    AND task_end.created_at = (
        SELECT min(created_at)
        FROM task_interactions
        WHERE status = task_end.status
        AND created_at >= task_start.created_at
    )
WHERE task_start.task_id = 1
AND task_start.status = 'In Progress'

【讨论】:

  • 这是我喜欢 Laravel 的主要原因...... PHP 和 SQL 的原始代码是如此丑陋且难以阅读......如果你能花点时间翻译一下就好了到 Laravel Eloquent
  • 那有什么难读的呢?这是基本的 SQL...您将所有的 task_interactions 都设置为“进行中”;我称他们为 task_start;然后我对具有相同 task_id 的其他任务进行左连接(并且我为该 task_end 设置别名);对于那个加入,我只想要暂停或完成的任务。此外 - 我想要第一个任务...... Laravel 很好,但如果你想要使用 Eloquent 的话,它仍然会这么复杂。 Laravel 是一个很棒的工具,但你仍然需要知道你在做什么......
  • 代码太多了,我知道可以用laravel和更少的代码来完成!
  • 好吧 - 如果你想把这个负载放在数据库上,你的 laravel 逻辑将同样“困难”。另一种方法是你在 laravel 中循环记录你的记录,然后从那里开始......
  • 非常感谢,它有效,只需要更改 status_id 的状态。我正在寻找更雄辩的东西。现在我只需要弄清楚如何在模型中实现它。
猜你喜欢
  • 1970-01-01
  • 2020-02-14
  • 2018-10-16
  • 1970-01-01
  • 2017-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-25
相关资源
最近更新 更多