2

I have an array of date ranges on input:

[
  [ 'start' => '2000-01-01 00:00:00', 'end' => '2000-01-01 06:00:00' ],
  [ 'start' => '2000-01-02 00:00:00', 'end' => '2000-01-02 12:00:00' ],
  [ 'start' => '2000-01-03 06:00:00', 'end' => '2000-01-03 12:00:00' ],
  [ 'start' => '2000-01-03 05:00:00', 'end' => '2000-01-03 10:00:00' ],
]

All of this ranges must be unique and don't cross each other. I'm trying to find a way to validate them using Laravel Validator. In my case the ranges with indexes 2 and 3 is invalid because they are crossing each other

3
  • 1
    There are not pre-build rule for that in Laravel validation system, you need to implement that manually... Commented Dec 18, 2018 at 15:14
  • Might this be of use to you? packagist.org/packages/v-matsuk/time-overlap-calculator Commented Dec 18, 2018 at 15:36
  • I've added answer have a try, let me know if it works Commented Dec 19, 2018 at 2:54

1 Answer 1

3

After looking at your requirement, you have to make custom validation rule that will return true if no date range don't collide and false otherwise.

In order to implement such thing, you have to make custom validation rule Range with following artisan command.

php artisan make:rule Range

Now, you will see Range.php at App\Rules\ folder.

Then make your code like following.

App\Rules\Range.php

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class Range implements Rule
{
    /**
     * Create a new rule instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        $intersect = true;
        for($i=0;$i<count($value); $i++){
            for($j=$i+1;$j<count($value); $j++){
                if($value[$i]['start']<=$value[$j]['end'] && $value[$i]['end']>=$value[$j]['start'])
                {
                    $intersect = false;
                }
            }
        }
        return $intersect;
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return 'The dates intersect each other.';
    }
}

Now you can use the range rule in your validation like this,

Usage

Case I

If you are validating in controller,

      $this->validate($request,[
          . . .
         'data'=>[new Range],
          . . . 
       ]);

Case II

If you have made Request class then

/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */
public function rules()
{
            return [
                . . . 
                'data' => [new Range],
                . . .
            ];
}

Here, data is the parameter in which date ranges are sent.

I hope you will understand. If any further explanation required feel free to ask.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.