How can I verify a year in $_GET["year"] in PHP? - php

I have a PHP calendar that generates a calendar based on the month and year. I use $_GET["year"]. So, it appears in the URL of the page. Therefore, the user can input any year. How can I verify that the year they entered is a year (like 2010) and not a random input (like 2t8e7sjj2)?
I figured out how to verify month like this:
$m = $_GET["month"];
if($m!=1 && $m!=2 && $m!=3 && $m!=4 && $m!=5 && $m!=6 && $m!=7 && $m!=8 && $m!=9 && $m!=10 && $m!=11 && $m!=12)
{
$m = date("m");
}
But I can't do this with year (since the year could be any number).
Also, is there a better way to verify the month other than above?
Thanks.

try http://php.net/manual/en/function.checkdate.php
if (checkdate($_GET['month'], 1, $_GET['year'])) ... okay

What are your restrictions on year other than it must be a positive integer number?
Regarding your month validation (and most probably your year one as well), you should be checking against a numeric range, eg
$m = ctype_digit($_GET['month']) ? (int) $_GET['month'] : 0;
if ($m >= 1 && $m <= 12) {
// month is valid
}

Yes, you can verify the month like this:
$month = intval($_GET['month']);
if ($month >= 1 && $month <= 12) {
// ...
}
You don't even need to verify the year; just clean it with intval()
http://php.net/intval

if (is_numeric($_GET['year']) && in_array($_GET['year'], range(1900,2100)))
also
if (is_numeric($_GET['month']) && in_array($_GET['month'], range(1,12)))

I'd do something like:
$m = intval($_GET['month']);
$y = intval($_GET['year']);
if($m < 1 || $m > 12 || $y < 1900 || $y > 2100) echo "bad input!";

2 things.
1st: you can use the pasre_url() method in php to ensure that there is no invalid formatting.
2nd: to match a year/month (since a year must be 4 numeric digits) they can be verified easily using regular expressions. Since I don't like to take credit for the sources I learned something ... look here to validate dates.
http://www.regular-expressions.info/dates.html
If you need I can write the .php for you, but it should be pretty easy from this point.

You can use this to check both ( month , year )
<?
// define vars
$months = array();
$years = array();
// create new array with months values
for($i=1;$i<=12;$i++)
array_push($months,$i);
// create new array with years values ex: begin with year 1930 to 2011
for($i=1930;$i<=2011;$i++)
array_push($years,$i);
// Check Values
if(in_array($_GET['m'],$months))
{ $m = $_GET['m']; }
else
{ $m = date("m"); }
if(in_array($_GET['y'],$years))
{ $y = $_GET['y']; }
else
{ $y = date("Y"); }
?>

Related

check whether a date falls in between date range concat with TO operator

I have following format 2016-06-06 TO 2016-06-12
I want to know that whether my date i.e 2016-06-11 lies in between or not. How can I do this?
You can use PHP if condition for checking date range:
$compareDate = "2016-06-06 TO 2016-06-12";
$dateArr = explode(" TO ",$compareDate);
$starting_date = $dateArr[0];
$final_date = $dateArr[1];
$date = "2016-06-11";
if($date >= $starting_date && $date <= $final_date) {
...
}
if($date >= $fome_date && $date <= $to_date)
{
echo "yes";
}
else
{
echo "no";
}
https://3v4l.org/UdIgq
i hope it will be helpful
Dates can be compared just as numbers can be
So using
date > starting_date && date < final_date
Will be just fine for an if clause. Also if you have I would recommend you do this in the database part as dbs have built in queries for such occasions.

Simple PHP If Statement Not Acting As Expected

This is a simple year validation that should check if the year is between 1900 and the current year. If the year is valid it should be displayed as the input's value.
if(!empty($year) && $year >= 1900 || !empty($year) && $year <= date('Y')){
$yearHolder = 'value="'.$year.'"';
}else{
$yearHolder = 'placeholder="Year"';
}
The problem I'm having is that the statement does not work, and passes any numbers through.
You can try this.
if(!empty($year) && $year >= 1900 && $year <= date('Y')){
$yearHolder = 'value="'.$year.'"';
}else{
$yearHolder = 'placeholder="Year"';
}
To be sure about conditions, place it separately.
if(!empty($year))
{
if ($year >= 1900 && $year <= date('Y'))
{
$yearHolder = 'value="'.$year.'"';
}else{
$yearHolder = 'placeholder="Year"';
}
} else {
echo "Year is empty";
}
You have to change your middle || OR condition to and AND condition, to get your logic, which you want. Right now in other words your condition is:
IF $year is NOT empty AND $year is either bigger than 1900 OR less than 2015
But what you want is:
IF $year is NOT empty AND $year is either bigger than 1900 AND less than 2015
So your if statement should look something like this:
if(!empty($year) && $year >= 1900 && $year <= date("Y"))
Also note, that the function call date() is at the end, which makes it only execute, if the other two pieces in the condition are TRUE. That is because PHP has short circuit evaluation.
Consolidating other suggestions, you could try something like this:
if (!empty($year) && $year >= 1900 && $year <= date('Y')) {
$yearHolder = 'value="' . $year . '"';
} else {
$yearHolder = 'placeholder="Year"';
}
This removes the redundant check for empty values, corrects your || to an &&
Try:
if(!empty($year) && $year >= 1900 && $year <= date('Y')){
No need to check if $year is empty twice and make them all ANDs.

PHP: How to fill an array with dates (Y-m-d) as keys [duplicate]

This question already has answers here:
I have 2 dates in PHP, how can I run a foreach loop to go through all of those days?
(13 answers)
Closed 1 year ago.
I want to fill an array with values. The keys of this array should be readable dates in the format 'YEAR-MONTH-DAY'. Starting point is '2010-5-25'.
The process should abort on the current date. Obviously, all dates should be valid dates.
I thought about doing this loop. But it seems that PHP is not able to check the condition of more than one in a 'for' loop. It does not give me any warnings or errors, though.
for ($d = 25, $m = 5, $y = 2010,
$this_day = date('j'),
$this_month = date('n'),
$this_year = date('Y');
($y <= $this_year) && ($m <= $this_month) && ($d <= $this_day);
$d++)
{
$values[$y.'-'.$m.'-'.$d] = 0; //fill array
$d++;
if(!checkdate($m, $d, $y)){
$d = 1;
$m++;
if($m > 12) { $m = 1; $y++; }
}
}
Doing this with nested loops would be rather painful.
One solution would be to use integer times as keys and then convert them later in another loop into the readable dates.
Is there a more efficient way?
Here is code that does some error checking, for example, valid dates provided and start date cannot be bigger than end date:
function arrayKeyDates($start, $end='now') {
// can use DateTime::createFromFormat() instead
$startDate = new DateTime($start);
$endDate = new DateTime($end);
if ($startDate === false) {
// invalid start date.
return;
}
if ($endDate === false) {
// invalid end date.
return;
}
if ($startDate > $endDate) {
// start date cannot be greater than end date.
return;
}
$dates = array();
while($startDate <= $endDate) {
$dates[$startDate->format('Y-n-j')] = 0;
$startDate->modify('+1 day');
}
return $dates;
}
print_r(arrayKeyDate('2014-11-30'));
I get the following output:
Array
(
[2014-11-30] => 0
[2014-12-1] => 0
[2014-12-2] => 0
[2014-12-3] => 0
[2014-12-4] => 0
[2014-12-5] => 0
[2014-12-6] => 0
[2014-12-7] => 0
)
Error handling code is left to you.
UPDATE (DateTime::createFromFormat)
If you want to create the DateTime objects using a custom format you can, in my function, you can do something like this:
$startDate = DateTime::createFromFormat('Y-n-j', $start);
Where $start would have the value 2010-5-25.
For more information, see: http://php.net/manual/en/datetime.createfromformat.php
$startDate = new \DateTime('2010-05-25');
$endDate = new \DateTime();
$interval = new \DateInterval('P1D');
$period = new \DatePeriod ($startDate, $interval, $endDate);
$dates = array();
foreach ($period as $key => $date) {
$dates[$date->format('Y-m-d')] = null;
}
var_dump($dates);
Simply you can try using strtotime(). Example:
$values = array();
$oldDate = strtotime('2010-05-25');
while($oldDate <= time()){
$values[date('Y-m-d', $oldDate)] = 'Your value';
$oldDate += 86400;
//Other codes
}
I know this is an old question, but might be helpful for new viewers a shorter version
$dummyArray = array_fill(1, 7, 0);
$dates = array_flip(array_map(function($val, $idx) {
return date_create('2010-5-25')->modify('-' . $idx . ' days')->format('Y-m-d');
}, $dummyArray, array_keys($dummyArray)));
I'm basically generating a dummy array which is going to have the numbers of days I want to extract as index, and then converting those to dates with array_map, after which I just flip the array to have the dates as keys instead of values
I took the liberty to clean up your code a little to make it readable:
<?php
$this_day = date('j');
$this_month = date('n');
$this_year = date('Y');
echo sprintf("Today: d-m-y: %s-%s-%s\n", $this_day, $this_month, $this_year);
for ($d = 25, $m = 5, $y = 2010;
($y <= $this_year) && ($m <= $this_month) && ($d <= $this_day);
$d++) {
echo sprintf("Date: d-m-y: %s-%s-%s\n", $d, $m, $y);
$values[$y.'-'.$m.'-'.$d] = 0; //fill array
$d++;
if(!checkdate($m, $d, $y)){
$d = 1;
$m++;
if($m > 12) { $m = 1; $y++; }
}
}
This shows that the code works perfectly well. That is if you chose the correct condition!
Today is the 07th, but your initial values start with the 25th which falsifies the condition. To verify chose a start day of '02' and see the output...
I guess you want to re-check your condition. Most likely it is something else you want to express...
First of all; the loop doesn't execute because you are checking separately if year number is lower then current year number, etc. But today is the 7th, and you start at the 25th of may 2010:
$d = 25;
$this_day = date('j'); // today: 7
$loop = $d <= $this_day; // evaluates to false
Because the 'day-check' evaluates to false, the whole expression evaluates to false. So the loop will only start to run on december the 25th.
You can better use the DateTime object to construct the dates and perform modifications on the created object. This will also safe you a lot of sweat with stuff like leap years etc. Example:
for (
$start = new DateTime('2010-05-25'),
$today = new DateTime('now') ;
$start->diff($today)->format('%a') >= 0 ;
$start->modify('+1 day')
) {
$values[$start->format('Y-m-d')] = 0;
}
easy does it!

How do I stop my IF statements from conflicting and how do I choose which one has priority?

I'm quite new to PHP and I've been asked to write a script that displays an image based on time. I've deducted that I need to use PHP's native 'date' function for this and up until I was asked to implement bank holidays and Christmas into it, all went well.
I tried to add the Christmas and bank holidays in as a separate if statement but that was when disaster struck and I haven't been able to figure out why it's come to a halt. I've tried using an online PHP validator to no avail.
Please don't be afraid to throw details and jargon at me as I really wish to expand my knowledge of PHP and rely less on the support of web forums in the future!
Here is the code:
<?php
// Date-time (day of month, month)
$d = date('j'); // Day of month: Numeric without leading zeroes
$m = date('n'); // Month: As above
$D = date('w'); // Day of week
$H = date('G'); // Hour of day
// REGULAR OPENING TIMES
// Closed before 9am on weekdays
if ($H < 9 && $D <= 5) :
$showroom_img = '/media/gbu0/pagehead/showroom_closed.jpg';
// Open before 5pm (but after 9, as first if statement overrides this) on weekdays
elseif ($H < 17 && $D <= 5) :
$showroom_img = = '/media/gbu0/pagehead/showroom_open.jpg';
// Closed before 10am on Saturdays
elseif ($H < 10 && $D == 6) :
$showroom_img = = '/media/gbu0/pagehead/showroom_closed.jpg';
// Open between 10am and 2pm on Saturdays
elseif ($H < 14 && $H > 10 && $D == 6) :
$showroom_img = = '/media/gbu0/pagehead/showroom_open.jpg';
// Any other time, display closed image :)
else :
$showroom_img = = '/media/gbu0/pagehead/showroom_closed.jpg';
endif;
// Holidays 2014
$xmas_starts = ($d == 23 && $m == 12 && $d > 17);
$xmas_ends = ($d == 26 && $m == 12);
$nyd = ($d == 1 && $m = 1);
// Easter Friday: April 18
// Easter Monday: April 21
// Early Spring B/H: May 5
// Late Spring B/H: May 26
// Summer B/H: August 25
// All bank holidays: 10am - 2pm
if( date >= $xmas_starts && $day <= $xmas_ends ) :
$xmas = true;
elseif( date = $nyd ) :
$nyd = true;
else :
$bankhol = false;
endif;
if( $xmas = true ) :
$showroom_img = "/media/gbu0/pagehead/showroom_xmas.jpg";
elseif( $bankhol = true && date('F', 'j') = strpos('April 18' || 'April 21' || 'May 5' || 'May 26' || 'August 25') || date('w') = 6 ) :
$showroom_img = "/media/gbu0/pagehead/showroom_bhol.jpg";
elseif( date('w') = 7 ) :
$showroom_img = "/media/gbu0/pagehead/showroom_closed.jpg";
else :
$showroom_img = "/media/gbu0/pagehead/showroom_open.jpg";
endif;
?>
First of all. I noticed a couple of bugs :
elseif( date = $nyd ) :
$nyd = true;
and
if( $xmas = true ) :
$showroom_img = "/media/gbu0/pagehead/showroom_xmas.jpg";
In PHP, '=' is the assignment operator, used to assign value to a variable. What you need here is the comparison operator, '=='. For example :
if( $xmas == true ) :
Or you could also do (it's pointed out in a comment already) :
if( $xmas ) :
Rgarding priority, the if statements are going to be checked in the order you write them in your code. TO ensure that a condition gets the highest priority, that has to be checked first.
Have you considered using the switch case function instead of elseif?
Switch case method:
switch ($i) {
case 0:
echo "i equals 0";
break;
case 1:
echo "i equals 1";
break;
case 2:
echo "i equals 2";
break;
}
Read more here: http://www.php.net/manual/en/control-structures.switch.php
if statements cannot conflict, and have no concept of priority. Each one is evaluated and executed in the order it appears, unless it gets skipped by code branching (e.g. an elseif would get skipped if a previous if or elseif in the same chain evaluated to true).
The cause of your problems is most likely your confusion of assignment and equality operators (= and ==).
In all situations, x = y is an assignment; i.e. it assigns the value of y to the variable x. This is the case even if you put it in an if statement, so it's usually something you want to avoid (although there are situations where it's useful).
In all situations, x == y is an equality comparison; i.e. it checks if the value of x is (or can be converted to) the same as the value of y. This is the one you usually want in an if condition.
To put it another way, you want to change this:
if( $xmas = true )
To this:
if( $xmas == true )
You'll need to do the same thing in a couple of other places as well.

How do I find date prior to another date in php

I need to find date x such that it is n working days prior to date y.
I could use something like date("Y-m-d",$def_date." -5 days");, but in that case it wont take into consideration the weekend or off-date. Let's assume my working days would be Monday to Saturday, any idea how I can accomplish this?
Try this
<?php
function businessdays($begin, $end) {
$rbegin = is_string($begin) ? strtotime(strval($begin)) : $begin;
$rend = is_string($end) ? strtotime(strval($end)) : $end;
if ($rbegin < 0 || $rend < 0)
return 0;
$begin = workday($rbegin, TRUE);
$end = workday($rend, FALSE);
if ($end < $begin) {
$end = $begin;
$begin = $end;
}
$difftime = $end - $begin;
$diffdays = floor($difftime / (24 * 60 * 60)) + 1;
if ($diffdays < 7) {
$abegin = getdate($rbegin);
$aend = getdate($rend);
if ($diffdays == 1 && ($astart['wday'] == 0 || $astart['wday'] == 6) && ($aend['wday'] == 0 || $aend['wday'] == 6))
return 0;
$abegin = getdate($begin);
$aend = getdate($end);
$weekends = ($aend['wday'] < $abegin['wday']) ? 1 : 0;
} else
$weekends = floor($diffdays / 7);
return $diffdays - ($weekends * 2);
}
function workday($date, $begindate = TRUE) {
$adate = getdate($date);
$day = 24 * 60 * 60;
if ($adate['wday'] == 0) // Sunday
$date += $begindate ? $day : -($day * 2);
return $date;
}
$def_date="";//define your date here
$preDay='5 days';//no of previous days
date_sub($date, date_interval_create_from_date_string($preDay));
echo businessdays($date, $def_date); //date prior to another date
?>
Modified from PHP.net
Thanks for the help guys, but to solve this particular problem I wrote a simple code:
$sh_padding = 5; //No of working days to count backwards
$temp_sh_padding = 1; //A temporary holder
$end_stamp = strtotime(date("Y-m-d", strtotime($date_format)) . " -1 day"); //The date(timestamp) from which to count backwards
$start_stamp = $end_stamp; //start from same as end day
while($temp_sh_padding<$sh_padding)
{
$sh_day = date('w',$start_stamp);
if($sh_day==0){ //Skip if sunday
}
else
{
$temp_sh_padding++;
}
$start_stamp = strtotime(date("Y-m-d",$start_stamp)." -1 day");
}
$sh_st_dte = date("Y-m-d",$start_stamp); //The required start day
A quick bit of googling got me to this page, which includes a function for calculating the number of working days between two dates.
It should be fairly trivial to adjust that concept to suit your needs.
Your problem, however, is that the concept of "working days" being monday to friday is not universal. If your software is only ever being used in-house, then it's okay to make some assumptions, but if it's intended for use by third parties, then you can't assume that they'll have the same working week as you.
In addition, public holidays will throw a big spanner in the works, by removing arbitrary dates from various working weeks throughout the year.
If you want to cater for these, then the only sensible way of doing it is to store the dates of the year in a calendar (ie a big array), and mark them individually as working or non-working days. And if you're going to do that, then you may as well use the same mechanism for weekends too.
The down-side, of course, is that this would need to be kept up-to-date. But for weekends, at least, that would be trivial (loop through the calendar in advance and mark weekend days where date('w')==0 or date('w')==6).

Categories