Insert a Date Range

Asked

Viewed 1,280 times

1

Good morning, I am making a system that I need to register the presence of users at an event, separating by period of day and date. The part of the period was simple, however the date comes to me a problem, I need to take the date of the form that inserts the Initial Date/Final Date and insert all dates in this range (besides the dates already inserted), to register the presence of the user in each of the days for example. It would look like this:

   idevento  |        datainicial     |          datafinal
       1     | $_POST["datainicial"]  | $_POST["datafinal"]
       1     |         20/02/2016     |        25/02/2016

That’s how it would look in the bank:

       |idevento|   datas  |   
       |   1    |20/02/2016|
       |   1    |21/02/2016| 
       |   1    |22/02/2016|
       |   1    |23/02/2016|
       |   1    |24/02/2016|
       |   1    |25/02/2016|

I found in some questions something similar but it was only the select, what would advance me in time to take the dates of the bank to register the presence, however I needed to have the dates inserted in the bank to be able to register the presence in each separate and generate a final report of presence, so I tried to adapt, however I did not obtain result.

EDIT 1: @Gabriel Herning I did the code this way, but I don’t know if I’m sending the bank the wrong way or something. Should I create a new column to store the value of the right dates? In addition to the start date and end date

$dataInicial = $_POST['data'];
$dataFinal = $_POST['datafinal'];
$start = new DateTime($dataInicial);
$end = new DateTime($dataFinal);

$periodArr = new DatePeriod($start , new DateInterval('P1D') , $end);

foreach($periodArr as $period) {
    $end = $period->format('d/m/Y');
    $sql = mysqli_query($conn, "INSERT INTO evento (id, datas) VALUES('$id', '$end); 
}

The table has the idevento fields, initial date, final date, and dates, I need to pass which of them in the Insert?

EDIT2: That’s the current code

function presenca($datas){ 
        include "conectar.php";    
        $dataInicial = $_POST['data'];
        $dataFinal = $_POST['datafinal'];
        $start = new DateTime($dataInicial);
        $end = new DateTime($dataFinal);
        $periodArr = new DatePeriod($start , new DateInterval('P1D') , $end);
        foreach($periodArr as $period) {
            $period->format('d/m/Y');
            $sql = mysqli_query($conn, "INSERT INTO datas (datas) VALUES('$period')"); 
        }
        $conn = null;

}

if($_POST["pagina"] == "inserirEve"){   
    presenca($_POST['data'], $_POST['datafinal']);
}

<form method="POST" action="input.php">
<input type="hidden" name="pagina" value="inserirEve"/>
Data Inicial: <input type="date" name="data">
Data Final: <input type="date" name="datafinal">
<br>
<br>
<input type="submit" name="Inserir" value="Cadastrar">
</form>

And this error occurs here:

Catchable fatal error: Object of class Datetime could not be converted to string in C: xampp htdocs semana input.php on line 53

EDIT3:

function presenca($datas){ 
            include "conectar.php";    
            $start = new DateTime($_POST['data']);
            $end = new DateTime($_POST['datafinal']);
            $periodArr = new DatePeriod($start , new DateInterval('P1D') , $end);
            foreach($periodArr as $period) {
                $period = $period->format('d/m/Y');
                $sql = mysqli_query($conn, "INSERT INTO datas (datas) VALUES('$period')"); 
            }
            $conn = null;
}

2 answers

2


Use the library Date Time for this. Date Time is a native PHP library that offers you everything you need to work with dates. In it you will find the class Dateperiod.

With Dateperiod, you can calculate all dates within a period:

$start = new \DateTime('2016-02-20');
$end = new \DateTime('2016-02-25');
$periodArr = new \DatePeriod($start , new \DateInterval('P1D') , $end);

foreach($periodArr as $period) {
    echo $period->format('d/m/Y H:i:s').'<br />';
}

//data de término
echo $end->format('d/m/Y H:i:s');

Exit:

20/02/2016 00:00:00
21/02/2016 00:00:00
22/02/2016 00:00:00
23/02/2016 00:00:00
24/02/2016 00:00:00
25/02/2016 00:00:00

One detail is about the end date, it should be consider as "cut date", ie it is not considered "within a period". Therefore, it is printed separately

If you only need to use the internal period, since it already has start and end, you can remove the start date via Dateperiod::EXCLUDE_START_DATE:

$start = new \DateTime('2016-02-20');
$end = new \DateTime('2016-02-25');
$periodArr = new \DatePeriod($start , new \DateInterval('P1D') , $end , DatePeriod::EXCLUDE_START_DATE);

foreach($periodArr as $period) {
    echo $period->format('d/m/Y H:i:s').'<br />';
}

Exit:

21/02/2016 00:00:00
22/02/2016 00:00:00
23/02/2016 00:00:00
24/02/2016 00:00:00
  • So, I need to pass the Post from the start date to start, the end date to end and within the foreach send an Insert to the bank, with the amount of periodArr? Or command on the Internet the value of both?

  • @Rabbit yes, you will spend the $_POST for the $start and the $end. Depending on the format you come from, use [Datetime::createFromFormat()] (http://php.net/manual/en/datetime.createfromformat.php) to define the format. After, foreach the result and insert line by line.

  • @Gabrielherning I did in a way, is giving some errors, I edited the question with the current code.

  • @Rabbit your code is having several problems. First, the return of Dateperiod is a Datetime array, so they should be treated as objects. That is, be used the method format. Another error is the lack of quote when closing the code 'VALUES('$id', '$end);'. And last but not least, you’re using the $end variable, where it should be $period. Another point, what do you really want to save in the dates column? I believe you have a serious modeling problem.

  • Well, the only thing I need to save are the dates in the interval between the first (initial) date and the Final date, $periodoArr = $periodoArr->format('d/m/Y'); $periodArr = new DatePeriod($start , new DateInterval('P1D') , $end); Something like that? And in the $end = $period->format('d/m/Y'); let alone $period->format('d/m/Y'); Regarding closing the code was even attention error.

  • The problem with its implementation is that it does not agree with the 1st Normal Form . In this case, you would have to have a second table (which could be called "evento_dates"), it would save, row by row, each date of the period. The problem, is that I have no idea how you want to save in the current format. If you add $period->format('Y-m-d') where the $end at Insert, you may already solve it the way you want.

  • Yes, that was the idea, in this new table I should send the Index with the dates and create two fields, one with the idevento int`` e outra com date`, and insert in these two fields?

  • Right. You should insert in the table evento. Recover the inserted id, since you are using mysqli, you can use http://php.net/manual/en/mysqli.insert-id.php. After, add to foreach by inserting period per period.

  • I haven’t been able to insert it yet, I’ll keep trying, while I keep it open here. I left the code like this at the moment in the main, but thanks for the help so far.

  • $periodArr->format('d/m/Y'); does not exist. $periodArr is an array, that’s all.

  • You must pass $period->format and not $periodArr (as stated above). Another detail is to use Prepared statements as the example on the link: http://stackoverflow.com/a/9629364/1628790

  • I still can not find solution, no error appears, but does not send to the bank. I must be sending the wrong Insert or passing the parameters in if($_POST["pagina"] == "inserirEve"){ &#xA; presenca($_POST['data'], $_POST['datafinal']);, gave a new Edit in the main.

  • Where is your $Conn variable coming from? It does not exist in the function scope. Add line or die(mysqli_error($conn)); at the end of mysqli_query as http://stackoverflow.com/a/17053489/1628790 to display any error in the Insert.

  • It comes from connect.php, which is the / function file that connects with db, and even with or die(mysqli_error($Conn));, still showing no error at all. $conn = new mysqli($servername, $username, $password, $dbname);

Show 9 more comments

1

You can use a function to return all dates between start and end before entering in the database:

function createDateRangeArray($strDateFrom,$strDateTo) {
    // formato esperado: YYYY-MM-DD
    $aryRange=array();

    $iDateFrom=mktime(1,0,0,substr($strDateFrom,5,2), substr($strDateFrom,8,2),substr($strDateFrom,0,4));
    $iDateTo=mktime(1,0,0,substr($strDateTo,5,2), substr($strDateTo,8,2),substr($strDateTo,0,4));

    if ($iDateTo>=$iDateFrom)
    {
        array_push($aryRange,date('Y-m-d',$iDateFrom));
        while ($iDateFrom<$iDateTo)
        {
            $iDateFrom+=86400;
            array_push($aryRange,date('Y-m-d',$iDateFrom));
        }
    }
    return $aryRange;
}

//chamando a função da seguinte forma
$dt_inicial = date('Y-m-d', strtotime($_POST["datainicial"]));
$dt_final = date('Y-m-d', strtotime($_POST["datafinal"]));
$array_datas = createDateRangeArray($dt_inicial , $dt_final);

foreach($array_datas as $data){
    //insere os dados no banco
}

Reference

  • foreach($array_datas as $data){ include "conectar.php"; $sql = mysqli_query($conn,"INSERT INTO datas(idevento, datas) VALUES('$idevento', '$array_datas')"); $conn = null; } The insert part in the database, I need to enter the date array_dates within my date table, or both the final and the initial?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.