I need a function to validate if the content of a variable is a valid unix timestamp.
I've checked this thread: Check whether the string is a unix timestamp but the problem is that the function in the most voted answer still can cause some errors, for eg:
function is_timestamp($timestamp)
{
return ((string) (int) $timestamp === $timestamp)
&& ($timestamp <= PHP_INT_MAX)
&& ($timestamp >= ~PHP_INT_MAX);
}
// Some tests:
$timestamp = 1289216307;
var_dump(is_timestamp($timestamp));
var_dump(date('Y-m-d', $timestamp));
// result
bool(false)
string(10) "2010-11-08"
$timestamp = '20101108';
var_dump(is_timestamp($timestamp));
var_dump(date('Y-m-d', $timestamp));
// result
bool(true)
string(10) "1970-08-21"
Here, the first should be TRUE and the second should be FALSE so, what's the best way to test if a $var is a real valid unix timestamp?
Here, the first should be TRUE and the second should be FALSE
Why? 20101108 is a valid UNIX timestamp, - as you say, it's August 21, 1970. Could well be a person's birthday for example.
The only way to achieve what you want is to set a range of dates that mark a "sane" timestamp by the definition you are working with - e.g. anything after January 1st, 2000 - and do a check against that.
A workaround for this would be to check if strtotime recognises the string as a valid date string.
function is_timestamp($timestamp)
{
return ((string) (int) $timestamp === $timestamp)
&& ($timestamp <= PHP_INT_MAX)
&& ($timestamp >= ~PHP_INT_MAX)
&& (!strtotime($timestamp));
}
This will weed out strings that are probably date strings rather than timestamps. It is probably easier to code than writing your own sanity checks.
You can check unix timestamp format using regular expression when your timestamp is bigger than size of integer:
/**
* Check if timestamp is in unix format.
*
* #param string $timestamp
* Target timestamp that will be checked.
*
* #return bool
* TRUE if timestamp is in unix format. FALSE on failure.
*/
function is_unix_timestamp($timestamp) {
return preg_match('/^\d+$/', $timestamp);
}
Write your own ;)
Some things you could check:
Is the given parameter an int? if not => false
Is it negative or above max? => false
Everything else is true
This would work for your given tests.
Any number is potentially a timestamp. The only significant difference between your two examples is that the latter case is a string. In which case:
function is_timestamp($timestamp) {
return is_int($timestamp) || is_float($timestamp);
}
(is_numeric is no good as it also returns true for strings that can be parsed as numbers.)
Related
I'm trying to do a simple if echo statement.
<?php if (time("mm-dd") > strtotime("11-01") && time("mm-dd") < strtotime("02-28"))echo 'stuff' ?>
Basically I want to echo something if today is either Nov, Dec, Jan, Feb. The code works if I use time() and the full year but I'd like to just compare the month, day. I think I have some silly syntax error that I just can't figure out. This code snippet is placed in the <head> of my html if that makes a difference. Little help. Thanks.
This is what I ended up with. Thanks!
<?php if ($today > '12-16' || $today < '01-08') echo 'yes' ?>
with $today = date("m-d")
Use the date function instead of time.
Switch && to ||. No m-d date string will ever be both greater than 11-01 and less than 02-28.
You probably want to use an inclusive comparison operator with November 1 and an exclusive one against March 1 to account for leap years.
Instead of calling date() twice, why not assign the result to a variable?
Here it is all together:
$today = date('m-d');
if ($today >= '11-01' || $today < '03-01') { ... }
Consider using date checking the month only:
$month = (int) date("m");
$isMonthCorrect = $month === 11 || $month === 12 || $month === 1 || $month === 2;
Note the importance of (int). Integer comparisons are more reliable than string comparisons, even if they behave similarly.
Or if you want to check between two dates, to optimize performance, you should evaluate the dates into timestamps before putting them in code.
For example, you can use some websites for converting Unix timestamps. (Not gonna advertise any here, but you can search "Unix timestamp converter) You can also use php -r to get quick output:
php -r 'echo strtotime("2016-11-01 00:00:00");'
php -r 'echo strtotime("2017-02-01 00:00:00");'
Then you can use them like this:
$minimum = 1477958400; // from first command line
$maximum = 1485907200; // from second command line
$isInPeriod = $minimum <= time() && time() <= $maximum;
Keep in mind:
time() always returns the current Unix timestamp, i.e. number of seconds since the Unix Epoch. Use strtotime for converting a string to time, and use date() to convert a timestamp to a string in a given format.
Unix timestamp is always absolute. You can't convert a "month" into a Unix timestamp. You can only obtain the current Unix timestamp with time(), or get specific data from the timestamp using date().
References:
strtotime
time
date
this code keeps telling me that $lasUpdate is always greater than $yesterday no matter the change i make to $yesterday result is (12/31/14 is greater than 01/19/15 no update needed). i feel like i'm missing something simple thank you in advance it is greatly appreciated.
$result['MAX(Date)']='12/31/14';
$lastUpdate = date('m/d/y', strtotime($result['MAX(Date)']));
$yesterday = date('m/d/y', strtotime('-1 day'));
if($lastUpdate<$yesterday){echo $lastUpdate.'is less '.$yesterday.'<br>'.'update needed';}
if($lastUpdate>=$yesterday){echo $lastUpdate.'is greater than '.$yesterday.'<br>'.'no update needed';
You have fallen victim to PHP type juggling with strings. A date function has a return value of a string. You cannot compare dates in their string format since PHP will juggle strings into integers in the context of a comparison. The only exception is if the string is a valid number. In essence, you are doing:
if ('12/31/14' < '01/19/15') { ... }
if ('12/31/14' >= '01/19/15') { ... }
Which PHP type juggles to:
if (12 < 1) { ... }
if (12 >= 1) { ... }
And returns false on the first instance, and true on the second instance.
Your solution is to not wrap date around the strtotime functions, and just use the returned timestamps from the strtotime functions themselves to compare UNIX timestamps directly:
$lastUpdate = strtotime($result['MAX(Date)']);
$yesterday = strtotime('-1 day');
You will however want to use date when you do the echo back to the user so they have a meaningful date string to work with.
Try something like this:
$lastUpdate = strtotime($result['MAX(Date)']);
$yesterday = strtotime('-1 day');
if ($lastUpdate < $yesterday) { /* do Something */ }
12/31/14 is greater than 01/19/15
Because 1 is greater than 0. If you want to compare dates that way you will need to store them in a different format (from most to least significant digit), for example Ymd.
Or store the timestamps you are making in the different variables and compare them.
I have unix timestamp input value. I have to validate whether input is correct timestamp format or not. Currently I'm using this:
$currenttime = $_POST['unixdate']; //input unix timestamp
if( $currenttime==strtotime( date('Y-m-d H:m:s',$currenttime) ) ){
echo "Correct";
} else {
echo "incorrect format";
}
I check this with several test cases, but its fail. Is that correct or is there any other way to check input is unix timestamp format or not?
I timestamp is just an integer that represents the number of seconds passed since the epoch. So the best validation you can do is something like
$currenttime = $_POST['unixdate']; //input unix timestamp
if((int)$currenttime == $currenttime && is_numeric($currenttime)) {
If you know what date you are expecting you could check to see if the timestamp falls between two dates or something like that
$startDate = '2014-10-04';
$endDate = '2013-10-04';
if((strtotime($currentDate) > strtotime($startDate)) && (strtotime($currentDate) < strtotime($endDate))) {
//Is valid
}
Your validation is incorrect because you compare with another date where you've replaced minutes with months:
'Y-m-d H:m:s'
^ ^
Other than that, it's quite a pointless validation. A Unix timestamp is nothing but a number (an integer if you want to be strict). Something like this should be enough:
$currenttime = filter_input(INT_POST, 'unixdate', FILTER_VALIDATE_INT);
if($currenttime===false){
// Invalid
}
Your method is like validating an age by trying to calculate the date of birth ;-)
I have a date string like this: 2010-9-30 in my $date_string variable.
When I compare strings like this:
if ( date( 'Y-m-d', strtotime( "+20 days", $date_string ) ) )
{
// it returns true for all dates
}
The comparison is true for all dates, even from yesterday, which isn't 20 days ago. Any idea why that might be happening?
Thanks!
You are not making any comparisons between dates. Instead, you are testing whether you can successfully convert the date supplied as the second parameter to strtotime() into a valid date. That result is always true, because every date has a valid date 20 days in the future.
In other words, if date() returns a truthy value your condition is TRUE. It will always return a truthy value unless you pass it an invalid timestamp in its second parameter (for example, the 42nd of February)
If you want to compare the output of that date() call to another date string, you will need an additional operand inside your if():
if ('2011-09-02' == date('Y-m-d', strtotime("+20 days", $date_string))) {
}
It's returning the date in the string format of (for example) 2000-01-01, which when converted to boolean is true.
Instead, check for this:
if (time() > strtotime("+20 days", $date_string)) // Returns true if $date_string was in the last 20 days, or is in the future
Obviously, if you want dates more than 20 days old only, just flip the > to a <
I'm stuck with a problem how to check if a specific date is within allowed weekdays array in php. For example,
function dateIsAllowedWeekday($_date,$_allowed)
{
if ((isDate($_date)) && (($_allowed!="null") && ($_allowed!=null))){
$allowed_weekdays=json_decode($_allowed);
$weekdays=array();
foreach($allowed_weekdays as $wd){
$weekday=date("l",date("w",strtotime($wd)));
array_push($weekdays,$weekday);
}
if(in_array(date("l",strtotime($_date)),$weekdays)){return TRUE;}
else {return FALSE;}
}
else {return FALSE;}
}
/////////////////////////////
$date="21.05.2010"; //actually is Friday (5)
$wd="[0,1,2]"; //Sunday,Monday,Tuesday
if(dateIsAllowedWeekday($date,$wd)){echo "$date is within $wd weekday values!";}
else{echo "$date isn't within $wd weekday values!"}
I have input dates formatted as "d.m.Y" and an array returned from database with weekday numbers (formatted as 'Numeric representation of the day of the week') like [0,1,2] - (Sunday,Monday,Tuesday).
The returned string from database can be "null", so i check it too. Then, the isDate function checks whether date is a date and it is ok.
I want to check if my date, for example 21.05.2010 is an allowed weekday in this array. My function always returns TRUE and somehow weekday is always 'Thursday' and i don't know why...
Is there any other ways to check this or what can be my error in the code above? thx
I'm not sure why you feel the need to convert the numeric day of the week into a string (eg "Sunday") as you only return a boolean value in the end; anyway I've removed that part and the below code should function as expected:
function dateIsAllowedWeekday($_date,$_allowed)
{
if ((isDate($_date)) && (($_allowed!="null") && ($_allowed!=null)))
{
$allowed_weekdays = json_decode($_allowed);
if (in_array(date("w", strtotime($_date)), $allowed_weekdays))
{
return TRUE;
}
}
return FALSE;
}
Tested with 21.05.2010 (returns false), and 11.05.2010 (returns true), with your allowed_weekdays as above ([0,1,2]).
If you got PHP5.3 running already, you can also do:
function date_validWeekday($format, $date, array $weekdays) {
return in_array(
DateTime::createFromFormat($format, $date)->format('w'),
$weekdays);
}
var_dump(date_validWeekday('d.m.Y', '21.05.2010', array(0,1,2))); // FALSE
var_dump(date_validWeekday('d.m.Y', '11.05.2010', array(0,1,2))); // TRUE
The reason why it keeps returning Thursday is because you are using strtotime() on single digit integer:
$weekday=date("l",date("w",strtotime($wd)));
One of the two things is happening, thought I'm not sure which:
the function interprets the integer as an epoch timestamp, or
the function is returning false, which the date function gets as a 0.
In either case, you are within 10 seconds of the original Epoch start time:
Thu, 01 Jan 1970 00:00:00 GMT
Which is on a Thursday.
function dateIsAllowedWeekday($_date,$_allowed){
if ((isDate($_date)) && (($_allowed!="null") && ($_allowed!=null))){
return in_array(date("w",strtotime($_date)),json_decode($_allowed));
}
return false;
}