The following code working well on browser:
<?php
$start = (new DateTime('2010-12-02'))->modify('first day of this month');
$end = (new DateTime('2012-05-06'))->modify('first day of next month');
$interval = DateInterval::createFromDateString('1 month');
$period = new DatePeriod($start, $interval, $end);
foreach ($period as $dt)
{
echo $dt->format("Y-m"). "<br>\n";
}
?>
and give the following result on browser:
2010-12 2011-01 2011-02 2011-03 2011-04 2011-05 2011-06 2011-07
2011-08 2011-09 2011-10 2011-11 2011-12 2012-01 2012-02 2012-03
2012-04 2012-05
In phrunner i tried to insert the above data (which is multiple data) into one row in mysql but only the first data inserted (2010-12):
...
foreach ($period as $dt)
{
$sql = "INSERT INTO table2 (payment) values ('".$data->format("Y-m")."')";
CustomQuery($sql);
}
?>
Related
I am trying to solve a problem I am looking for hours into.
My students have special courses and I am trying to find the dates.
For example:
Student 1 in Class A: every Monday from Jan 1st till April 1st
Student 2 in Class B: every Wednesday from April 1st until June...
So I programmed a function in which I can pass info like begin, end, weekday to show me the dates:
function tkcheck ($beginnfunc,$endfunc,$daycheck)
{
$begin = new DateTime($beginnfunc);
$end = new DateTime($endfunc);
$interval = new DateInterval('P1W');
$period = new DatePeriod($begin, $interval, $end);
foreach ($period as $date) {
$dayw = $date->modify($daycheck);
if ($dayw < $end) {
$daystring = $dayw->format ('d-m-Y');
$q1day1[] = $daystring;
}
}
}
tkcheck ('2022-02-20','2022-04-01','next Wednesday');
print_r($q1day1);
But print_r does not show me any information when I try to use my function tkcheck...
Maybe some here might help me, thank you!
$q1day1 is scoped within the function. It is not accessible out of the function.
To fix this return the variable.
function tkcheck ($beginnfunc,$endfunc,$daycheck)
{
$begin = new DateTime($beginnfunc);
$end = new DateTime($endfunc);
$interval = new DateInterval('P1W');
$period = new DatePeriod($begin, $interval, $end);
foreach ($period as $date) {
$dayw = $date->modify($daycheck);
if ($dayw < $end) {
$daystring = $dayw->format ('d-m-Y');
$q1day1[] = $daystring;
}
}
return $q1day1;
}
$result = tkcheck ('2022-02-20','2022-04-01','next wednesday');
print_r($result);
See Variable Scope for more info.
The special feature of this solution is simply to create a Date::Interval from 'next Monday'.
$start = date_create('Jan 1st 2022')->modify('-1 Day');
$end = date_create('Apr 1st 2022');
$interval = DateInterval::createFromDateString('next Monday');
$period = new DatePeriod($start, $interval, $end, DatePeriod::EXCLUDE_START_DATE);
$dateArray = iterator_to_array ($period);
echo '<pre>'.var_export($dateArray,true).'</pre>';
The modification with "-1 Day" is necessary to record a Monday that falls exactly on the start date.
two dates 13-10-2017 and 13-02-2018. I want to separate this period in months like 13-10-2017 to 31-10-2-17, 01-11-2017 to 30-11-2017, 01-12-2017 to 31-12-2017, 01-01-2018 to 31-01-2018 and 01-02-2018 to 13-02-2018. What I did I can get the month names in the date period but not in the format I want.
Here is my code:
$start_date = new DateTime('13-10-2017');
$end_date = new DateTime('13-02-2018');
$date_interval = new DateInterval('P1M');
$date_period = new DatePeriod($start_date, $date_interval, $end_date);
# calculating number of days in the interval
$interval = $start_date->diff( $end_date );
$days = $interval->days;
# getting names of the months in the interval
$month_count = 0;
$month_names = array();
foreach ($date_period as $date) {
$month_names[] = $date->format('F');
$month_count++;
}
$month_name_string = implode(',', $month_names);
echo $start_date->format('d-m-Y').' to '.$end_date->format('d-m-Y'). ' is ' .$days.' days and month names are: '.$month_name_string;
The output I get :
13-10-2017 to 13-02-2018 is 123 days and month names are: October,November,December,January
You can, while iterating, do the following checks:
If the current month is in $start_date, use its day for the start date
If the current month is in $end_date, use its day for the last day
Else, use the 1 and maximum day of each month (using the t format character)
Also, you need to set the time to 00:00:01 in the final day in order to have it considered in the DateInterval:
<?php
$start_date = new DateTime('13-10-2017');
$end_date = new DateTime('13-02-2018');
$end_date->setTime(0, 0, 1); // important, to consider the last day!
$date_interval = new DateInterval('P1M');
$date_period = new DatePeriod($start_date, $date_interval, $end_date);
# calculating number of days in the interval
$interval = $start_date->diff( $end_date );
$days = $interval->days;
# getting names of the months in the interval
$dates = [];
foreach ($date_period as $date) {
$dateArr = [];
if ($date->format("Y-m") === $start_date->format("Y-m")) {
$dateArr["start"] = $start_date->format("d-m-Y");
}
else {
$dateArr["start"] = $date->format("01-m-Y");
}
if ($date->format("Y-m") === $end_date->format("Y-m")) {
$dateArr["end"] = $end_date->format("d-m-Y");
}
else {
$dateArr["end"] = $date->format("t-m-Y"); // last day of the month
}
$dates[] = $dateArr;
}
foreach ($dates as $date) {
echo $date["start"]." to ".$date["end"].PHP_EOL;
}
Demo
You can employ DateTime::modify function. E.g.:
$month_intervals = [];
foreach ($date_period as $date) {
$start = $date == $start_date ? $start_date : $date->modify('first day of this month');
$month_intervals[] = join([
$start->format('d-m-Y'),
$date->modify('last day of this month')->format('d-m-Y')
], ' to ');
}
$month_intervals[] = join([
(clone $end_date)->modify('first day of this month')->format('d-m-Y'),
$end_date->format('d-m-Y')
], ' to ');
echo implode(',', $month_intervals);
It's already working but the holidays only.I already connected the database inside foreach loop and minus the holiday in fines the table in my database and table in my website already count it as holiday table in website but after I add another holiday in database like September 6 and the result is like this "imgur.com/a/l8Deq" not counted as holiday and don't know why my fines and days are increasing. What should I do? Thank you for helping me
$borrowdate = new Datetime($row['date_return'],new DateTimeZone('Asia/Manila'));
$returndate = new Datetime($row['due_date'],new DateTimeZone('Asia/Manila'));
$currentdate = new Datetime('Asia/Manila');
$returndate->setTime(0,0);
$currentdate->setTime(0,0);
$borrowdate->setTime(0,0);
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($returndate, $interval, $borrowdate);
$borrowdate->format("D");
$weekendDays = 0;
$totalDays = 0;
$holiDays = 0;
$query_holiday =mysqli_query($dbcon,"SELECT * FROM holiday_tbl");
while($row=mysqli_fetch_array($query_holiday)){
$holi = $row ['holiday'];
foreach ($period as $p )
{
$totalDays++;
if($p->format( "w" )== 0 or $p->format( "w" )==6 ) $weekendDays++;
if($p->format('Y-m-d') == $holi) $holiDays++;
}
}
echo "<p>Total days: $totalDays</p><p>Weekend days: $weekendDays </p> <p> Holidays: $holiDays </p>";
$fines = ($totalDays - $weekendDays - $holiDays) * 5;
echo "₱ ". $fines;
$fi = $row['borrow_details_id'];
mysqli_query($dbcon,"update borrowdetails set fines='$fines' where borrow_details_id = '$fi'");
I have a range of date that I wich to add a row in my table foreach slected day of the week, so i needed a trigger to do that because this must be done after an insert on another table , and i'm facing some errors, so here is my code hoping that you can tell me what i have done wrong !
$begin = $this->input->post('debut_semestre');
$end = $this->input->post('fin_semestre');
$end = $end->modify( '+1 day' );
$array_jour = array();
$interval = new DateInterval('P7D');
$daterange = new DatePeriod($begin, $interval ,$end);
foreach ($daterange as $key ) {
$array_jour[] = $key->format("Y-m-d");
}
$this->db->query("create or replace trigger 'insert_seance'
after insert on 'emploi'
foreach row begin".
foreach ($array_jour as $key) {."
INSERT INTO seance(id, Date, jour, id_salle, id_groupe, id_ens, id_mat, de, a, etat, id_semestre) VALUES (null,".$key.",".$jour.",".$id_salle.",".$id_groupe.",".$id_ens.",".$id_mat.",".$date_debut.",".$date_fin."'active',".$id_semestre." )
".}."
)";
I am trying to get the difference between 2 dates, and get the last day of each month to insert data do the database. So if there is 3 months on this data range, it will insert 3 row to the database (one for each month).
What I have now is:
$jj = '2007-12-31';
$kk = '2009-12-31';
$begin = new DateTime($jj);
$end = new DateTime($kk);
$interval = DateInterval::createFromDateString('last thursday of next month');
$period = new DatePeriod($begin, $interval, $end, DatePeriod::EXCLUDE_START_DATE);
foreach ( $period as $dt ) {
echo $dt->format( "Y-m-t\n" );
}
This will output the last day of each month of this date range, but now I need to add a new row on a mysql table for each month.
If it helps to understand better my question, this is to save monthly payments, but there will be payments for 3 months, 6 months, 1 year, .... and all the payments will be stored in a monthly basis.
Thank you in advance!
If I understand correctly ... would you not do something like:
$insertSQL = "INSERT INTO <table> (%d, '%s', ...);";
foreach ( $period as $dt ) {
$payDate = $dt->format( "Y-m-t\n" );
mysql_query(sprintf($insertSQL, $custID, $payDate, ...);
}