This question already has answers here:
How to put a borrowdate into my calculation fines
(1 answer)
PHP day of week numeric to day of week text
(8 answers)
Closed 5 years ago.
I want to prevent calculation in fines when the day is Saturday and Sunday or Only Sunday not include in fines. I think it's better if we use the borrowdate,currentdate, and returndate to fully functions from my database Thank you!
$borrowdate = new Datetime($row['date_return']);
$returndate = new Datetime($row['due_date']);
$currentdate = new Datetime();
$fines = 0;
if($currentdate > $returndate){
$days = $borrowdate->diff($returndate ?? $currentdate, true)->days;
echo "₱ ". $fines = $days > 0 ? intval(floor($days)) * 15 : 0;
$fi = $row['borrow_details_id'];
mysqli_query($dbcon,"update borrowdetails set fines='$fines' where borrow_details_id = '$fi'");
}
You should count the number of working days, and than calculate your fine.
$returnDate= new DateTime( '2017-08-17' );
$today= new DateTime( '2017-08-21 00:23:44' );
$returnDate->setTime(0,0);
$today->setTime(0,0);
$interval = DateInterval::createFromDateString('1 day');
$period = new DatePeriod($returnDate, $interval, $today);
$weekendDays = 0;
$totalDays = 0;
foreach ( $period as $p ) {
$totalDays++;
if($p->format( "w" )==0 or $p->format( "w" )==6) $weekendDays++; //6 - saturday, 0 - sunday
}
echo "<p>Total days: $totalDays</p><p>Weekend days: $weekendDays </p>";
$fines = ($totalDays - $weekendDays) * 15;
echo "₱ ". $fines;
$fi = $row['borrow_details_id'];
mysqli_query($dbcon,"update borrowdetails set fines='$fines' where borrow_details_id = '$fi'");
do like this first find out the dayofweek of current date and check if its sunday or saturday. The value returned form day of week will be in number. 0 means Sunday and through 6 for saturday.
$borrowdate = new Datetime($row['date_return']);
$returndate = new Datetime($row['due_date']);
$currentdate = new Datetime();
$dayofweek = date('w', $currentdate->getTimestamp());
$fines = 0;
if($currentdate > $returndate){
if($dayofweek != 0){
$days = $borrowdate->diff($returndate ?? $currentdate, true)->days;
echo "₱ ". $fines = $days > 0 ? intval(floor($days)) * 15 : 0;
$fi = $row['borrow_details_id'];
mysqli_query($dbcon,"update borrowdetails set fines='$fines' where borrow_details_id = '$fi'");
}
}
$newquery = mysqli_query($dbcon,"select fines from borrowdetails where borrow_details_id = '$fi'");
$row = mysqli_fetch_assoc($newquery);
echo $row['fines'];
Related
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'");
This is my code of library fines calculation
$currentdate= date('Y/m/d');
$start = new DateTime($returndate=$row['due_date']); <-- from database
$end = new DateTime($currentdate);
$days= $start->diff($end, true)->days;
$fines = $days > 0 ? intval(floor($days)) * ₱10 : 0;
I want to calculate borrowing books every day after due date cost ₱10 but it just counted the day and display like this sorry I'm beginner in php coding thank you
$end is currentday and because of that it will calculate a fine even if currentdate is less than duedate.
What you need is a if currentday is more than duedate, then calculate the fine.
$currentdate = date('Y/m/d');
$start = new DateTime($returndate=$row['due_date']); <-- from database
$end = new DateTime($currentdate);
if(strtotime($currentdate) > strtotime($returndate)){
$days= $start->diff($end, true)->days;
$fines = $days > 0 ? intval(floor($days)) * 10 : 0;
}
strtotime() will convert a date in string format to UNIX time (integer).
You can test the code here: https://3v4l.org/fl3IM
Edit:
Method 1.
$currentdate = date('Y/m/d');
$start = new DateTime($returndate=$row['due_date']); <-- from database
$end = new DateTime($currentdate);
$fines = 0;
if(strtotime($currentdate) > strtotime($returndate)){
$days= $start->diff($end, true)->days;
$fines = $days > 0 ? intval(floor($days)) * 10 : 0;
}
Now it will show a fine of 0 until someone has passed due date. (may look cluttered in the page)
Method 2.
$currentdate = date('Y/m/d');
$start = new DateTime($returndate=$row['due_date']); <-- from database
$end = new DateTime($currentdate);
if(strtotime($currentdate) > strtotime($returndate)){
$days= $start->diff($end, true)->days;
$fines = $days > 0 ? intval(floor($days)) * 10 : 0;
}
//some other code I guess...
if(isset($fines)) echo $fines;
Here $fines is not set and will not be echoed unless someone is passed due date. This method probably will look the best on the page.
But I don't know exactly how your page is set up.
I'm trying to calculate the number of months and weeks since a particular date instead of from the beginning of the year.
It shouldn't follow calendar months but should instead count a month as every 4 weeks, and begin from a specified date. I need to be able to display the number of months, and also what week it is (1, 2, 3 or 4).
I want to put in a start date, and have it then count what month and week is it from that start date e.g if the start date is set to Mon 1st August it should show Month 1, Week 1 and so on.
My code is below. I tested it with some different start dates. Here's a list of what the code below generates and what it should display
Jun-20: Should be Week 2 - Shows as Week 0
Jun-27: Should be Week 1 - Shows as Week 3
Jul-04: Should be Week 4 - Shows as Week 2
Jul-11: Should be Week 3 - Shows as Week 1
Jul-18: Should be Week 2 - Shows as Week 0
$monthNumber = 5;
$monthStartDate = '2016-06-13';
$currentStartWeekDate = date('l') != 'Monday' ? date("Y-m-d", strtotime("last monday")) : date("Y-m-d"); // get the current week's Monday's date
$weekDateCounter = $monthStartDate;
$currentWeekNumber = 0;
while ($weekDateCounter != $currentStartWeekDate){
$currentWeekNumber += 1;
$weekDateCounter = date("Y-m-d", strtotime($weekDateCounter . "+7 days"));
//
if ($currentWeekNumber == 4){
$currentWeekNumber = 0; // reset week number
$monthNumber += 1; // increment month number
}
}
I am really at a loss with this and could use any help!
Your approach seems overly complicated:
function weekCounter($startDate,$endDate=null){
//use today as endDate if no date was supplied
$endDate = $endDate? : date('Y-m-d');
//calculate # of full weeks between dates
$secsPerWeek = 60 * 60 * 24 * 7;
$fullWeeks =
floor((strtotime($endDate) - strtotime($startDate))/$secsPerWeek);
$fullMonths = floor($fullWeeks/4);
$weeksRemainder = $fullWeeks % 4; // weeks that don't fit in a month
//increment from 0-base to 1-base, so first week is Week 1. Same with months
$fullMonths++; $weeksRemainder++;
//return months and weeks in an array
return [$fullMonths,$weeksRemainder];
}
You can call the function this way, and capture months and weeks:
//list() will assign the array members from weekCounter to the vars in list
list($months,$weeks) = weekCounter('2016-06-07'); //no end date, so today is used
//now $months and $weeks can be used as you wish
echo "Month: $months, Week: $weeks"; //outputs Month: 2, Week: 2
Live demo
The DateTime classes could make this much simpler for you. Documentation for them is here: http://php.net/manual/en/book.datetime.php
Try this out:
$date1 = new DateTime('2016-04-01');
$date2 = new DateTime('2016-07-24');
$diff = $date1->diff($date2);
$daysInbetween = $diff->days;
$weeksInbetween = floor($diff->days / 7);
$monthsInbetween = floor($weeksInbetween / 4);
print "Days inbetween = $daysInbetween" . PHP_EOL;
print "Weeks inbetween = $weeksInbetween" . PHP_EOL;
print "Months inbetween = $monthsInbetween" . PHP_EOL;
print "Total difference = $monthsInbetween months and "
. ($weeksInbetween - ($monthsInbetween * 4)) . " weeks" . PHP_EOL;
<?php
/**
* AUTHOR : VEDAVITH RAVULA
* DATE : 13122019
*/
function get_weeks($startDate = NULL,$endDate = NULL)
{
if(is_null($startDate) && is_null($endDate))
{
$startDate = date('Y-m-01');
$endDate = date('Y-m-t');
}
$date1 = new DateTime($startDate);
$date2 = new DateTime($endDate);
$interval = $date1->diff($date2);
$weeks = floor(($interval->days) / 7);
if(($date1->format("N") > 1) && ($date1->format("D") != "Sun"))
{
$diffrence = "-".( $date1->format("N"))." Days";
$date1 = $date1->modify($diffrence);
}
for($i = 0; $i <= $weeks; $i++)
{
if($i == 0)
{
$start_date = $date1->format('Y-m-d');
$date1->add(new DateInterval('P6D'));
}
else
{
$date1->add(new DateInterval('P6D'));
}
echo $start_date." - ".$date1->format('Y-m-d')."\n";
$date1->add(new DateInterval('P1D'));
$start_date = $date1->format('Y-m-d');
}
}
//function call
get_weeks("2021-11-01", "2021-11-14");
This question already has answers here:
Check if something is between two values?
(5 answers)
Closed 5 months ago.
I am trying to check if todays date is between START and STOP date of a period, Winter, summer, spring etc..
and if the todays date is between, lets say.. the winter period, it will set the $season variable to which period it is.
But for the moment it just gives me "01/01", i don't understand why..
Thanks for help! :)
$season = date("d-m");
$season = date("d-m", strtotime($season));
$startSummer = date("01-06");
$endSummer = date("31-08");
$startAutum = date("01-09");
$endAutum = date("30-11");
$startSpring = date("01-03");
$endSpring = date("31-05");
$startWinter = date("01-12");
$endWinter = date("28-02");
// start and stop, periods
// $startYear = date("d-m", strtotime($startYear)); $endYear = date("d-m", strtotime($endYear));
$startSummer = date("d-m", strtotime($startSummer)); $endSummer = date("d-m", strtotime($endSummer));
$startAutum = date("d-m", strtotime($startAutum)); $endAutum = date("d-m", strtotime($endAutum));
$startSpring = date("d-m", strtotime($startSpring)); $endSpring = date("d-m", strtotime($endSpring));
$startWinter = date("d-m", strtotime($startWinter)); $endWinter = date("d-m", strtotime($endWinter));
if(($season > $startSummer) && ($season < $endSummer)){
$season = "Sommar";
}else if(($season > $startAutum) && ($season < $endAutum)){
$season = "Höst";
}else if(($season > $startSpring) && ($season < $endSpring)){
$season = "Vår";
}else if(($season > $startWinter) && ($season < $endWinter)){
$season = "Vinter";
}
You can stick with timestamps. Don't convert back to dates. You are making invalid comparisons such as the assumption that 30-01 is less than 28-02. The computer will compare the very first 3 to the 2 and tell you that 30-01 is CORRECTLY greater than 28-02. So...
$startSummer = mktime(0,0,0, 6, 1, 2000); // The year doesn't matter according to your code
$endSummer = mktime(0,0,0, 8, 31, 2000);
Now, is some date between those? Assume I am checking $month and $day...
$myday = mktime(0,0,0, $month, $day, 2000);
if($myday>=$startSummer && $myday<=$endSummer) $season = "Summer";
If you use DateTime object—which is by far the best approach—you are able to compare these with the regular comparators, e.g.:
$date1 = new DateTime('today');
$date2 = new DateTime('2014-04-04');
if ($date1 < $date2) echo 'Past';
else if ($date1 == $date2) echo 'Present';
else echo 'Future';
See documentation: http://php.net/manual/en/datetime.diff.php#example-2368
Remember that a variable can be overwritten - just as the year progresses through the seasons, your variable can as well - as long as we do it in order we'll end up on the correct one. This means we only have to test if our date is after the date that a season changes.
// Since we're testing today's date
// we use the current year timestamps
$year = date('Y');
$startSpring = strtotime("$year-03-01");
$startSummer = strtotime("$year-06-01");
$startAutum = strtotime("$year-09-01");
$startWinter = strtotime("$year-12-01");
$today = time();
// The year starts with Winter
$season = 'Winter';
if($today > $startSpring) $season = 'Spring'; // Past the 1st day of spring?
if($today > $startSummer) $season = 'Summer'; // Etc...
if($today > $startAutumn) $season = 'Autumn';
if($today > $startWinter) $season = 'Winter';
echo 'It is currently '.$season;
Here's the same logic cleaned up in a pretty function that will check any date for you and return the season:
// Accepts an optional unix timestamp
// Uses the current date by default
function getSeason($test_date=FALSE){
$test_date = $test_date ? $test_date : time();
// Use the year of the date we're testing
$year = date('Y', $test_date);
// The year starts with Winter
$season = 'Winter';
if($test_date > strtotime("$year-03-01")) $season = 'Spring'; // Past the 1st day of spring?
if($test_date > strtotime("$year-06-01")) $season = 'Summer'; // Etc...
if($test_date > strtotime("$year-09-01")) $season = 'Autumn';
if($test_date > strtotime("$year-12-01")) $season = 'Winter';
return $season;
}