146

I have a form that passes two dates (start and finish) to a PHP script that will add those to a DB. I am having problems validating this. I keep getting the following errors

A non well formed numeric value encountered

This is when I use the following

date("d",$_GET['start_date']);

But when I use the strtotime() function as advised by many sites I get a unix timestamp date of 1/1/1970. Any ideas how I can get the correct date?

Stephan Weinhold
  • 1,596
  • 1
  • 26
  • 36
Deviland
  • 3,149
  • 7
  • 30
  • 51
  • 6
    You need to post what `$_GET['start_date']` contains. – JohnP May 26 '11 at 09:31
  • 1
    I assume your `$_GET['start_date']` is not a [timestamp](http://en.wikipedia.org/wiki/Timestamp) which is expected by `date` function as a second argument – Nemoden May 26 '11 at 09:36
  • 1
    JohnP is correct. This question is Unclear and Needs Debugging Details because the [mcve] is incomplete. As a result, this page is bloated with wild guesses regarding the correct solution. This mess is not enjoyable for researchers. It's funny how old, poor questions can gain so many UVs -- simply a matter of time and uninformed voting. – mickmackusa Aug 17 '20 at 08:28

10 Answers10

266

Because you are passing a string as the second argument to the date function, which should be an integer.

string date ( string $format [, int $timestamp = time() ] )

Try strtotime which will Parse about any English textual datetime description into a Unix timestamp (integer):

date("d", strtotime($_GET['start_date']));
AbraCadaver
  • 77,023
  • 7
  • 60
  • 83
DChaplin
  • 2,676
  • 2
  • 12
  • 2
  • 1
    I get the same error in the constructor of a class, i was debugging and the problem in that constructor is I'm receiving as a parameter and integer `public function __construct(int $someId....)` – Marcos Di Paolo Apr 23 '20 at 20:35
  • With parameter typing in PHP becoming more the 'norm', what @MarcosDiPaolo mentioned will definitely be seen more frequently. A dead giveaway is the stack trace will point to the line of the parameter declaration that's being incorrectly typed. – parttimeturtle May 05 '20 at 07:27
  • I still don't understand what is the course of action here @parttimeturtle – Marcos Di Paolo May 05 '20 at 17:56
  • @MarcosDiPaolo the Types of parameters you pass to that constructor must match the Types that are being hinted in the function definition. "4" represented by a string is different from 4 represented by an integer. So either conform to the function definition or turn off strict types, if you truly need to coalesce 'similar' values, e.g. string "4" to integer 4. – parttimeturtle May 18 '20 at 19:36
  • `PDO_Statement::bindParam()` Also throws this when the fourth argument is not an (int) – Richard Tyler Miles Aug 06 '21 at 16:29
9

This error occurs when you perform calculations with variables that use letters combined with numbers (alphanumeric), for example 24kb, 886ab ...

I had the error in the following function

function get_config_bytes($val) {
    $val = trim($val);
    $last = strtolower($val[strlen($val)-1]);       
    switch($last) {
        case 'g':
            $val *= 1024;
        case 'm':
            $val *= 1024;
        case 'k':
            $val *= 1024;
    }
    return $this->fix_integer_overflow($val);
}

The application uploads images but it didn't work, it showed the following warning:

enter image description here

Solution: The intval() function extracts the integer value of a variable with alphanumeric data and creates a new variable with the same value but converted to an integer with the intval() function. Here is the code:

function get_config_bytes($val) {
    $val = trim($val);
    $last = strtolower($val[strlen($val)-1]);
    $intval = intval(trim($val));
    switch($last) {
        case 'g':
            $intval *= 1024;
        case 'm':
            $intval *= 1024;
        case 'k':
            $intval *= 1024;
    }
    return $this->fix_integer_overflow($intval);
}

The function fix_integer_overflow

// Fix for overflowing signed 32 bit integers,
// works for sizes up to 2^32-1 bytes (4 GiB - 1):
protected function fix_integer_overflow($size) {
    if ($size < 0) {
        $size += 2.0 * (PHP_INT_MAX + 1);
    }
    return $size;
}
Vladimir Salguero
  • 5,057
  • 3
  • 40
  • 44
  • It appears that you are answering a different question -- not the one posted at the top of this page. Please only answer the question that is asked. This is why we require askers to provide a [mcve] -- so that the answers don't splinter into a thousand different directions. – mickmackusa Aug 17 '20 at 08:10
  • 1
    the function depends on external code ... what does `$ this-> fix_integer_overflow` do? – Lorenzo Magon Apr 22 '21 at 08:47
  • Hi Lorenzo Magon, I add the function `fix_integer_overflow`, so you can see its use – Vladimir Salguero Apr 22 '21 at 13:30
7

$_GET['start_date'] is not numeric is my bet, but an date format not supported by strtotime. You will need to re-format the date to a workable format for strtotime or use combination of explode/mktime.

I could add you an example if you'd be kind enough to post the format you currently receive.

Geoffrey Hale
  • 9,339
  • 5
  • 39
  • 43
Wesley van Opdorp
  • 14,720
  • 4
  • 40
  • 59
  • Casting won't fix the issue since PHP will automatically cast it when passed to the method. – JohnP May 26 '11 at 09:36
  • I like that you identified that there isn't enough detail in the question to offer an exact answer. This is because the [mcve] is incomplete; ergo this question should be closed instead of answered. It's not hard to get users to post a complete question, but they will not be motivated to do so if volunteers will start firing answers//guesses in advance. – mickmackusa Aug 17 '20 at 08:22
5

I ran into this same situation (in my case with a date value in a custom PHP field in a Drupal view), and what worked for me was using intval instead of strtotime to turn the value into an integer - because it basically was a timestamp, but in the form of a string rather than an integer. Obviously that won't be the case for everyone, but it might be worth a try.

spidersilk
  • 61
  • 1
  • 4
  • We do not know if this technique will resolve the OP's problem because the OP did not state the value of the input data. – mickmackusa Aug 17 '20 at 08:19
5

This helped me a lot -

$new_date = date_format(date_create($old_date), 'Y-m-d');

Here, date_create() provides you a date object for a given date & date_format() will set it in a given format.

for example,

<?php
    $date = date_create("13-02-2013");  // DateTime Object ( [date] => 2013-02-13 00:00:00.000000 [timezone_type] => 3 [timezone] => America/New_York )
    echo date_format($date,"Y-m-d");    // 2013-02-13
?>
Tushar Walzade
  • 3,543
  • 4
  • 31
  • 52
0

This is an old question, but there is another subtle way this message can happen. It's explained pretty well here, in the docs.

Imagine this scenerio:

try {
  // code that triggers a pdo exception
} catch (Exception $e) {
  throw new MyCustomExceptionHandler($e);
}

And MyCustomExceptionHandler is defined roughly like:

class MyCustomExceptionHandler extends Exception {
  public function __construct($e) {
    parent::__construct($e->getMessage(), $e->getCode());
  }
}

This will actually trigger a new exception in the custom exception handler because the Exception class is expecting a number for the second parameter in its constructor, but PDOException might have dynamically changed the return type of $e->getCode() to a string.

A workaround for this would be to define you custom exception handler like:

class MyCustomExceptionHandler extends Exception {
  public function __construct($e) {
    parent::__construct($e->getMessage());
    $this->code = $e->getCode();
  }
}
Parris Varney
  • 11,014
  • 12
  • 45
  • 72
  • Explaining exception handling may aid in understanding the problem, but it will not resolve the problem. This is Not An Answer because it does not attempt to resolve the question asked. – mickmackusa Aug 17 '20 at 08:18
0

If the error is at the time of any calculation, double check that the values does not contains any comma(,). Values must be only in integer/ float format.

  • There is no indication that the OP's value contains a comma. You are guessing at the problem. In this case, you should ask the OP for clarification of the [mcve] instead of posting an answer. – mickmackusa Aug 17 '20 at 08:13
0

if $_GET['start_date'] is a string then convert it in integer or double to deal numerically.

$int = (int) $_GET['start_date']; //Integer
$double = (double) $_GET['start_date']; //It takes in floating value with 2 digits
A.Aleem11
  • 1,710
  • 13
  • 12
  • You are guessing at the value of `$start_date`. If it is `08/08/2020` then casting it as an integer or a float will not help at all. Rather than answer this question, the correct action would be to leave a comment under the question to ask the OP to express the exact input data. – mickmackusa Aug 17 '20 at 08:15
  • $end_suggest_time = (int) $rowone['start_suggest_time'] + (24 * 3600); when i add (int) in the previus of $rowone i dont recieve this error "Notice: A non well formed numeric value encountered in" – God is universe programmer Feb 16 '22 at 02:29
0

in the name of the universe programmer

in my case i receive this error

"Notice: A non well formed numeric value encountered in"

my code with above error:

$end_suggest_time = $rowone['start_suggest_time'] + (24 * 3600);

when i add (int) in the previous of $rowone['start_suggest_time'] I don't receive this error

"Notice: A non well formed numeric value encountered in"

$end_suggest_time = (int) $rowone['start_suggest_time'] + (24 * 3600);

dazed-and-confused
  • 1,278
  • 2
  • 11
  • 18
-2

You need to set the time zone using date_default_timezone_set().

AlanP
  • 423
  • 8
  • 14