I have a PHP script which records things based on the day. So it will have a weekly set of inputs you would enter.
I get the data correctly, but when i do $day ++; it will increment the day, going passed the end of the month without ticking the month.
example:
//12/29
//12/30
//12/31
//12/32
//12/33
Where it should look like
//12/29
//12/30
//12/31
//01/01
//01/02
My script is as follows:
$week = date ("Y-m-d", strtotime("last sunday"));
$day = $week;
$run = array(7); //this is actually defined in the data posted to the script, which is pretty much just getting the value of the array index for the query string.
foreach( $run as $key=>$value)
{
$num = $key + 1;
$items[] = "($num, $user, $value, 'run', '$day')";
echo "".$day;
$day ++;
}
Should I be manipulating the datetime differently for day incrementations?
You can use
$day = date("Y-m-d", strtotime($day . " +1 day"));
instead of
$day++;
See live demo in ideone
You refer to $day as a "datetime" but it is just a string - that is what date() returns. So when you do $day++ you are adding 1 to "2015-12-02". PHP will do everything it can to make "2015-12-02" into a number and then add 1 to it, which is not date math. Here is a simple example:
<?php
$name = "Fallenreaper1";
$name++;
echo $name
?>
This will output:
Fallenreaper2
This is how I would do it, using an appropriate data type (DateTime):
<?php
$day = new DateTime('last sunday');
$run = array(7);
foreach ($run as $key => $value) {
$num = $key + 1;
$dayStr = $day->format('Y-m-d');
$items[] = "($num, $user, $value, 'run', '$dayStr')";
echo $dayStr;
$day->modify('+1 day');
}
To increase time you should use strtotime("+1 day");
here is simple example of using it
<?php
$now_time = time();
for($i=1;$i<8;$i++) {
$now_time = strtotime("+1 day", $now_time);
echo date("Y-m-d", $now_time) . "<br>";
}
?>
I'm working on a PHP page that calculates the percentage of completion of a project. For example, if you had a start date of January 1st, 2015, and an end date of March 3rd, 2015, and today was February 2nd, 2015, the project would be estimated to be about 50% done. So far I've attempted using the DateTime class and the date_diff function, but I couldn't divide the two, so I'm back at square one. Obviously I need to take Daylight Saving and leap years into account, so that adds an additional layer of complexity to the matter. Any ideas? Here the current block.
try {
$dbh = new PDO('mysql:host=localhost; dbname=jkaufman_hartmanbaldwin', $username, $password, array(
PDO::MYSQL_ATTR_SSL_KEY => '../php_include/codekaufman_com.key',
PDO::MYSQL_ATTR_SSL_CERT => '../php_include/codekaufman_com.crt',
PDO::MYSQL_ATTR_SSL_CA => '../php_include/codekaufman_com.ca_bundle'
));
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$projectName = $_GET['project'];
$sth = $dbh->prepare('SELECT start, end FROM projects WHERE name = ?');
$sth->execute([$projectName]);
if($sth->rowCount()) {
$row = $sth->fetchAll(PDO::FETCH_ASSOC);
date_default_timezone_set('America/Los_Angeles');
$date = strtotime($row[0]['start']);
$start = date('m/d/Y', $date);
echo $start;
$date = strtotime($row[0]['end']);
$end = date('m/d/Y', $date);
echo " " . $end;
$today = date('m/d/y');
echo $end - $start;
}
} catch(PDOException $e) {
echo $e->getMessage();
}
With reference to How to Minus two dates in php:
$start = new DateTime($row[0]['start']);
$end = new DateTime($row[0]['end']);
$today = new DateTime();
$total = $start->diff($end);
$current = $start->diff($today);
$completion = $current->days / $total->days;
MySQL has some pretty easy to use functions for this sort of thing, you can just gather the info you need in your query:
SELECT start, end, DATEDIFF(end, start) as total_days, DATEDIFF(end, NOW()) as days_remaining
FROM projects WHERE name = ?
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_datediff
From there you just need to divide days_remaining by total_days to get the percentage. Datediff should take leap years and DST into account.
You can use TIMEDIFF in place of DATEDIFF if you need to be more precise, just make sure to convert the sql timestamps to integers with strtotime.
You may also need to set the timezone:
SET time_zone = 'America/Los_Angeles';
The formula is:
percentage = (date - start) / (end - start) * 100
As a PHP function:
function date_progress($start, $end, $date = null) {
$date = $date ?: time();
return (($date - $start) / ($end - $start)) * 100;
}
Example:
$start = strtotime("January 1st 2015");
$end = strtotime("March 3rd 2015");
$date = strtotime("February 2nd 2015");
$percent = date_progress($start, $end, $date);
// "You are 52.46% there!"
echo 'You are ', round($percent, 2), '% there!';
Get your SQL output in the right format (YYYY-MM-DD) and then shove it into the code below:
<?php
$startDate = date_create('2015-01-01');
$endDate = date_create('2015-01-30');
$currentDate = date_create('2015-01-08');
$totalTime = date_diff($endDate, $startDate);
$elapsedTime = date_diff($currentDate, $startDate);
$totalTimeDays = $totalTime->format("%d");
$elapsedTimeDays = $elapsedTime->format("%d");
echo "Total project time = " . $totalTimeDays . "<br/>";
echo "Elapsed project time = " . $elapsedTimeDays . "<br/>";
echo "Percent of project complete = " . ($elapsedTimeDays / $totalTimeDays) * 100.0;
?>
$start = new DateTime("<YOUR START DATE>"); // example input "2014/06/30"
$end= new DateTime("<YOUR END DATE>");
$now = new DateTime();
$intervalOBJ = $start->diff($end);
$totalDaysOfProject = $intervalOBJ->format('%a');
$intervalOBJ_2 = $now->diff($end);
$daysRemaining = $intervalOBJ_2->format('%a');
$completedPercentage = round(($daysRemaining/$totalDaysOfProject)*100);
echo $completedPercentage . "% of this project has been completed!";
Description: This calculates the percentage of days remaining. interval = $start to $end. Calculated percentage is in relation to $now.
I have the day and the month from the database, stored in seperate variables. But if today is the 7th and I minus one week, it would be 0 same case for the month. And I want to add the lo_date to lockin_period_date and minus 3 months, as I want it to send an email to me 3 months in advance. How do I set the values I have from the database to the date I want? Please help.
<?php
include"connect_mysql.php";
$reminder_dates = mysql_query("SELECT*FROM registration_form");
while($row = mysql_fetch_array($reminder_dates)){
$main_dob_day = $row['main_dob_day'];
$main_dob_month = $row['main_dob_month'];
$main_dob_year = $row['main_dob_year'];
$joint_dob_day = $row['joint_dob_day'];
$joint_dob_month = $row['joint_dob_month'];
$joint_dob_year = $row['joint_dob_year'];
$loan_lo_day = $row['loan_lo_day'];
$loan_lo_month = $row['loan_lo_month'];
$loan_lo_year = $row['loan_lo_year'];
$lockin_period_day = $row['lockin_period_day'];
$lockin_period_month = $row['lockin_period_month'];
$lockin_period_year = $row['lockin_period_year'];
$legal_fee_clawback_day = $row['legal_fee_clawback_day'];
$legal_fee_clawback_month = $row['legal_fee_clawback_month'];
$legal_fee_clawback_year = $row['legal_fee_clawback_year'];
date_default_timezone_set('UTC');
$m = date("n");
$d = date("j");
$y = date("Y");
$time = time();
$today = date('n-j-Y', $time);
//main applicant birthday - reminder 7days in advance
$main_day = $main_dob_day-7;
if($main_day == $d && $main_dob_month == $m){
echo "Mail Sent!";
}
//
}
?>
A working solution would be:
$main_day = date( 'n-j-Y', strtotime( "today -1 week"));
To apply it to your use-case:
$time = mktime( 0, 0, 0, $main_dob_month, $main_dob_day, $main_dob_year);
$main_day = date( 'n-j-Y', strtotime( "-1 week", $time)); echo $main_day;
$oneWeekAdv=$main_dob_year.'-'.$main_dob_month.'-'.$main_dob_day;
$oneWeekAdv=strtotime(date("y-m-d", strtotime($oneWeekAdv)) . " -1 week");
$oneWeekAdv=date('m-d', $oneWeekAdv);
I want to take a date and work out its week number.
So far, I have the following. It is returning 24 when it should be 42.
<?php
$ddate = "2012-10-18";
$duedt = explode("-",$ddate);
$date = mktime(0, 0, 0, $duedt[2], $duedt[1],$duedt[0]);
$week = (int)date('W', $date);
echo "Weeknummer: ".$week;
?>
Is it wrong and a coincidence that the digits are reversed? Or am I nearly there?
Today, using PHP's DateTime objects is better:
<?php
$ddate = "2012-10-18";
$date = new DateTime($ddate);
$week = $date->format("W");
echo "Weeknummer: $week";
It's because in mktime(), it goes like this:
mktime(hour, minute, second, month, day, year);
Hence, your order is wrong.
<?php
$ddate = "2012-10-18";
$duedt = explode("-", $ddate);
$date = mktime(0, 0, 0, $duedt[1], $duedt[2], $duedt[0]);
$week = (int)date('W', $date);
echo "Weeknummer: " . $week;
?>
$date_string = "2012-10-18";
echo "Weeknummer: " . date("W", strtotime($date_string));
Use PHP's date function
http://php.net/manual/en/function.date.php
date("W", $yourdate)
This get today date then tell the week number for the week
<?php
$date=date("W");
echo $date." Week Number";
?>
Just as a suggestion:
<?php echo date("W", strtotime("2012-10-18")); ?>
Might be a little simpler than all that lot.
Other things you could do:
<?php echo date("Weeknumber: W", strtotime("2012-10-18 01:00:00")); ?>
<?php echo date("Weeknumber: W", strtotime($MY_DATE)); ?>
Becomes more difficult when you need year and week.
Try to find out which week is 01.01.2017.
(It is the 52nd week of 2016, which is from Mon 26.12.2016 - Sun 01.01.2017).
After a longer search I found
strftime('%G-%V',strtotime("2017-01-01"))
Result: 2016-52
https://www.php.net/manual/de/function.strftime.php
ISO-8601:1988 week number of the given year, starting with the first week of the year with at least 4 weekdays, with Monday being the start of the week. (01 through 53)
The equivalent in mysql is DATE_FORMAT(date, '%x-%v')
https://www.w3schools.com/sql/func_mysql_date_format.asp
Week where Monday is the first day of the week (01 to 53).
Could not find a corresponding solution with DateTime.
At least not without solutions like "+1day, last monday".
Edit: since strftime is now deprecated, maybe you can also use date.
Didn't verify it though.
date('o-W',strtotime("2017-01-01"));
I have tried to solve this question for years now, I thought I found a shorter solution but had to come back again to the long story. This function gives back the right ISO week notation:
/**
* calcweek("2018-12-31") => 1901
* This function calculates the production weeknumber according to the start on
* monday and with at least 4 days in the new year. Given that the $date has
* the following format Y-m-d then the outcome is and integer.
*
* #author M.S.B. Bachus
*
* #param date-notation PHP "Y-m-d" showing the data as yyyy-mm-dd
* #return integer
**/
function calcweek($date) {
// 1. Convert input to $year, $month, $day
$dateset = strtotime($date);
$year = date("Y", $dateset);
$month = date("m", $dateset);
$day = date("d", $dateset);
$referenceday = getdate(mktime(0,0,0, $month, $day, $year));
$jan1day = getdate(mktime(0,0,0,1,1,$referenceday[year]));
// 2. check if $year is a leapyear
if ( ($year%4==0 && $year%100!=0) || $year%400==0) {
$leapyear = true;
} else {
$leapyear = false;
}
// 3. check if $year-1 is a leapyear
if ( (($year-1)%4==0 && ($year-1)%100!=0) || ($year-1)%400==0 ) {
$leapyearprev = true;
} else {
$leapyearprev = false;
}
// 4. find the dayofyearnumber for y m d
$mnth = array(0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334);
$dayofyearnumber = $day + $mnth[$month-1];
if ( $leapyear && $month > 2 ) { $dayofyearnumber++; }
// 5. find the jan1weekday for y (monday=1, sunday=7)
$yy = ($year-1)%100;
$c = ($year-1) - $yy;
$g = $yy + intval($yy/4);
$jan1weekday = 1+((((intval($c/100)%4)*5)+$g)%7);
// 6. find the weekday for y m d
$h = $dayofyearnumber + ($jan1weekday-1);
$weekday = 1+(($h-1)%7);
// 7. find if y m d falls in yearnumber y-1, weeknumber 52 or 53
$foundweeknum = false;
if ( $dayofyearnumber <= (8-$jan1weekday) && $jan1weekday > 4 ) {
$yearnumber = $year - 1;
if ( $jan1weekday = 5 || ( $jan1weekday = 6 && $leapyearprev )) {
$weeknumber = 53;
} else {
$weeknumber = 52;
}
$foundweeknum = true;
} else {
$yearnumber = $year;
}
// 8. find if y m d falls in yearnumber y+1, weeknumber 1
if ( $yearnumber == $year && !$foundweeknum) {
if ( $leapyear ) {
$i = 366;
} else {
$i = 365;
}
if ( ($i - $dayofyearnumber) < (4 - $weekday) ) {
$yearnumber = $year + 1;
$weeknumber = 1;
$foundweeknum = true;
}
}
// 9. find if y m d falls in yearnumber y, weeknumber 1 through 53
if ( $yearnumber == $year && !$foundweeknum ) {
$j = $dayofyearnumber + (7 - $weekday) + ($jan1weekday - 1);
$weeknumber = intval( $j/7 );
if ( $jan1weekday > 4 ) { $weeknumber--; }
}
// 10. output iso week number (YYWW)
return ($yearnumber-2000)*100+$weeknumber;
}
I found out that my short solution missed the 2018-12-31 as it gave back 1801 instead of 1901. So I had to put in this long version which is correct.
How about using the IntlGregorianCalendar class?
Requirements: Before you start to use IntlGregorianCalendar make sure that libicu or pecl/intl is installed on the Server.
So run on the CLI:
php -m
If you see intl in the [PHP Modules] list, then you can use IntlGregorianCalendar.
DateTime vs IntlGregorianCalendar:
IntlGregorianCalendar is not better then DateTime. But the good thing about IntlGregorianCalendar is that it will give you the week number as an int.
Example:
$dateTime = new DateTime('21-09-2020 09:00:00');
echo $dateTime->format("W"); // string '39'
$intlCalendar = IntlCalendar::fromDateTime ('21-09-2020 09:00:00');
echo $intlCalendar->get(IntlCalendar::FIELD_WEEK_OF_YEAR); // integer 39
<?php
$ddate = "2012-10-18";
$duedt = explode("-",$ddate);
$date = mktime(0, 0, 0, $duedt[1], $duedt[2],$duedt[0]);
$week = (int)date('W', $date);
echo "Weeknummer: ".$week;
?>
You had the params to mktime wrong - needs to be Month/Day/Year, not Day/Month/Year
To get the week number for a date in North America I do like this:
function week_number($n)
{
$w = date('w', $n);
return 1 + date('z', $n + (6 - $w) * 24 * 3600) / 7;
}
$n = strtotime('2022-12-27');
printf("%s: %d\n", date('D Y-m-d', $n), week_number($n));
and get:
Tue 2022-12-27: 53
for get week number in jalai calendar you can use this:
$weeknumber = date("W"); //number week in year
$dayweek = date("w"); //number day in week
if ($dayweek == "6")
{
$weeknumberint = (int)$weeknumber;
$date2int++;
$weeknumber = (string)$date2int;
}
echo $date2;
result:
15
week number change in saturday
The most of the above given examples create a problem when a year has 53 weeks (like 2020). So every fourth year you will experience a week difference. This code does not:
$thisYear = "2020";
$thisDate = "2020-04-24"; //or any other custom date
$weeknr = date("W", strtotime($thisDate)); //when you want the weeknumber of a specific week, or just enter the weeknumber yourself
$tempDatum = new DateTime();
$tempDatum->setISODate($thisYear, $weeknr);
$tempDatum_start = $tempDatum->format('Y-m-d');
$tempDatum->setISODate($thisYear, $weeknr, 7);
$tempDatum_end = $tempDatum->format('Y-m-d');
echo $tempDatum_start //will output the date of monday
echo $tempDatum_end // will output the date of sunday
Very simple
Just one line:
<?php $date=date("W"); echo "Week " . $date; ?>"
You can also, for example like I needed for a graph, subtract to get the previous week like:
<?php $date=date("W"); echo "Week " . ($date - 1); ?>
Your code will work but you need to flip the 4th and the 5th argument.
I would do it this way
$date_string = "2012-10-18";
$date_int = strtotime($date_string);
$date_date = date($date_int);
$week_number = date('W', $date_date);
echo "Weeknumber: {$week_number}.";
Also, your variable names will be confusing to you after a week of not looking at that code, you should consider reading http://net.tutsplus.com/tutorials/php/why-youre-a-bad-php-programmer/
The rule is that the first week of a year is the week that contains the first Thursday of the year.
I personally use Zend_Date for this kind of calculation and to get the week for today is this simple. They have a lot of other useful functions if you work with dates.
$now = Zend_Date::now();
$week = $now->get(Zend_Date::WEEK);
// 10
To get Correct Week Count for Date 2018-12-31 Please use below Code
$day_count = date('N',strtotime('2018-12-31'));
$week_count = date('W',strtotime('2018-12-31'));
if($week_count=='01' && date('m',strtotime('2018-12-31'))==12){
$yr_count = date('y',strtotime('2018-12-31')) + 1;
}else{
$yr_count = date('y',strtotime('2018-12-31'));
}
function last_monday($date)
{
if (!is_numeric($date))
$date = strtotime($date);
if (date('w', $date) == 1)
return $date;
else
return date('Y-m-d',strtotime('last monday',$date));
}
$date = '2021-01-04'; //Enter custom date
$year = date('Y',strtotime($date));
$date1 = new DateTime($date);
$ldate = last_monday($year."-01-01");
$date2 = new DateTime($ldate);
$diff = $date2->diff($date1)->format("%a");
$diff = $diff/7;
$week = intval($diff) + 1;
echo $week;
//Returns 2.
try this solution
date( 'W', strtotime( "2017-01-01 + 1 day" ) );
I have an events calender that displays events in the order of start date. Everything works great but there is one issue. Events that occur on today's date don't display. I believe that my "if" statement to remove events after they have passed is the issue.
<? while($row = mysql_fetch_assoc($result)) {
$id = $row['id'];
$title = $row['title'];
$text = $row['text'];
$image_url = $row['image_url'];
$start_date = date('F d, Y', strtotime($row['start_date']));
$start_hour = $row['start_hour'];
$start_minute = $row['start_minute'];
$start_am_pm = $row['start_am_pm'];
$end_date = date('F d, Y', strtotime($row['end_date']));
$end_hour = $row['end_hour'];
$end_minute = $row['end_minute'];
$end_am_pm = $row['end_am_pm'];
$tba = $row['tba'];
if(strtotime($row['end_date']) > date('U')) {
?>
First of all, I just want to point out that:
date('U') == time()
So you can use time instead of date.
Now for your problem. If the end_date of your event is set to today, it's probably at the beginning of the day (i.e.: 2010-11-18 00:00:00). That's probably why your conditional does not work, because now is past midnight, the current date/time is greater than the end_date.
Try this:
if (strtotime($row['end_date']) == strtotime('TODAY')) {
// event is today
}
I'm guessing that $row['end_date'] only returns the date not the time. So strtotime($row['end_date']) will = 12:00AM and date('U') will equal return the current time.
So if you ran this at 12:01AM on the date of $row['end_date'], you'd have the comparison of
if("12:00AM today" > "12:01AM today") {
Try
if (strtotime($row['end_date']) >= strtotime(date('Y-m-d'))) {