Why does mysql ceil datetime strings? - php

I'm having a problem when searching a datetime column with a string.
I'm using codeigniters insert_batch, but I'm sure it's the same if I use insert. This is an example of the data I'm inserting:
$valor_log_proceso = array(
'id_interno' => 21656,
'proceso_id' => 1,
'fecha_inicio' => '2015-12-02T09:04:59.884',
'fecha_fin' => '2015-12-02T09:20:10.884',
'equipo' => "EQUIPOPC",
'usuario_id' => 2,
'log_envio_id' => 10
);
In the mysql db 'fecha_inicio' and 'fecha_fin' are datetime colmuns.
'fecha_inicio' and 'fecha_fin' values in every single $valor_log_proceso array are strings retrieved from a request.
When I try to look for that data with a get_where
$valor_log_proceso = array(
'id_interno' => 21656,
'proceso_id' => 1,
'fecha_inicio' => '2015-12-02T09:04:59.884',
'fecha_fin' => '2015-12-02T09:20:10.884',
'equipo' => "EQUIPOPC",
'usuario_id' => 2
);
$result = $this->db->get_where($table_name, $valor_log_proceso)->result_array();
$result is an empty array.
Then I check the database and see that the dates where truncated/ceiled to:
fecha_inicio: 2015-12-02 09:05:00
fecha_fin: 2015-12-02 09:20:11
So the question is why does that happen?
How can I search correctly for rows in the table?

The reason this is happening is that a DATETIME column can only have this pattern of data. As you see, it is stripping out the 'T' as well.
See https://dev.mysql.com/doc/refman/5.6/en/datetime.html
The DATETIME type is used for values that contain both date and time parts. MySQL retrieves and displays DATETIME values in 'YYYY-MM-DD HH:MM:SS' format. The supported range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'
In order to create the query correctly, you will have to change your array to match the same pattern...
'fecha_inicio' => '2015-12-02 09:04:59',
'fecha_fin' => '2015-12-02 09:20:10',
ADDITION
Here is a function to manipulate the current format to the needed format
function format($x){
$x = preg_replace('/[T]/', ' ', $x);
$y = explode(".", $x);
return $y[0];
}
$x = format('2015-12-02T09:04:59.884');
echo $x; // Prints 2015-12-02 09:04:59

Related

Select a SubArray if today date is between 2 keys value

I have a multidimensional array like this:
$array = array(
0 => array(
'name' => 'first element',
'start' => '30/04/2015',
'end' => '30/06/2015'
),
1 => array(
'name' => 'second element',
'start' => '01/07/2015',
'end' => '30/09/2015'
),
2 => array(
'name' => 'fourth element',
'start' => '01/10/2015',
'end' => '15/12/2015'
)
);
I need to select one array subarray (item) based on the today date.
today date must be between start date and end date keys.
In the end I would like to have this:
$selected_subarray = array (
'name' => 'first element',
'start' => '30/04/2015',
'end' => '30/06/2015'
)
I use to check between two dates like this:
function check_if_in_range($start_date, $end_date, $today_date)
{
$start_d = strtotime($start_date);
$end_d = strtotime($end_date);
$today_d = strtotime($today_date);
return (($today_d >= $start_d) && ($today_d <= $end_d));
}
I tryed to follow suggestions from this question How to search by key=>value in a multidimensional array in PHP
but if I'm able to filter for a key = value, I'm not able to do the same using the "check_if_in_range" function.
You do know that 30/06/2015 is invalid date, and strtotime() will return false? See here. Format mm/dd/yyyy is an American month, day and year. So your format is non-standard.
Best way is to convert it to standard format, and then use strtotime()example or just use DateTime::createFromFormat()example.
After you learn how formating and converting dates works, then you can just do simple foreach loop, and break on first found result. Here is a little demo.
Try something like the following
foreach($array as $key => $value) {
if(check_in_range($value['start'], $value['end'], $today_date)) {
$selected_subarray = $value;
}
}

Convert a PHP date format to a jQueryUI Datepicker date format

[EDIT] : I guess people had problem to understand exactly what I mean, so I completely rewrote my explanations.
I work on a project where users can define a date format used in the whole site. It uses PHP date format standard. For example : "year-month-day" is set by "Y-m-d".
PHP standard uses single-character symbols like Y, m, d, F, j to describe the date format. As seen in the documentation : http://www.php.net/manual/en/function.date.php
Sometimes users can select a date thanks to a jQueryUI Datepicker. This component describes its date format with code-words like yy, y, mm, dd, D, ...
http://api.jqueryui.com/datepicker/#utility-formatDate
I would like to display the dates in the same format for both PHP and the Datepicker.
I mean that PHP should output the date as in the format set by user, AND the Datepicker should show the selected date in the same format.
Given that:
The date format is necessarily described "PHP style"
I can't know a priori which format was set by users
/!\ This not a problem of how to read/parse/display a date from a known format.
Unfortunately, Javascript date format description is not the same as in PHP.
For instance, these 2 date formats are equivalent but described differently in PHP and Javascript:
PHP : Y-m-d (set by users)
Javascript : yy-mm-dd
As you can see, I cannot just configure the datepicker with the PHP date format, because it will be misunderstood, or not recognized at all.
Someone (in answers below) adviced to create my own "date format standard converter", matching each PHP symbol with its equivalent in JS date format description. Just like:
Y => yy
m => mm
d => dd
y => y
z => o
...
And then replace each PHP symbol with the JS one. And so "d/m/Y" will be translated into "dd/mm/yy", magically.
But maybe somebody knows another proper way to make jQueryUI Datepicker understand PHP date format standard?
EDIT: I wrote a tutorial that explains both the problem and the solution. For further reading : http://tristan-jahier.fr/blog/2013/08/convertir-un-format-de-date-php-en-format-de-date-jqueryui-datepicker
I chose the brutal method : converting symbol-by-symbol the date format.
I made a 'not-so-dummy' code snippet.
/*
 * Matches each symbol of PHP date format standard
 * with jQuery equivalent codeword
* #author Tristan Jahier
 */
function dateformat_PHP_to_jQueryUI($php_format)
{
    $SYMBOLS_MATCHING = array(
        // Day
        'd' => 'dd',
        'D' => 'D',
        'j' => 'd',
        'l' => 'DD',
        'N' => '',
        'S' => '',
        'w' => '',
        'z' => 'o',
        // Week
        'W' => '',
        // Month
        'F' => 'MM',
        'm' => 'mm',
        'M' => 'M',
        'n' => 'm',
        't' => '',
        // Year
        'L' => '',
        'o' => '',
        'Y' => 'yy',
        'y' => 'y',
        // Time
        'a' => '',
        'A' => '',
        'B' => '',
        'g' => '',
        'G' => '',
        'h' => '',
        'H' => '',
        'i' => '',
        's' => '',
        'u' => ''
    );
    $jqueryui_format = "";
    $escaping = false;
    for($i = 0; $i < strlen($php_format); $i++)
    {
        $char = $php_format[$i];
        if($char === '\\') // PHP date format escaping character
        {
            $i++;
            if($escaping) $jqueryui_format .= $php_format[$i];
            else $jqueryui_format .= '\'' . $php_format[$i];
            $escaping = true;
        }
        else
        {
            if($escaping) { $jqueryui_format .= "'"; $escaping = false; }
            if(isset($SYMBOLS_MATCHING[$char]))
                $jqueryui_format .= $SYMBOLS_MATCHING[$char];
            else
                $jqueryui_format .= $char;
        }
    }
    return $jqueryui_format;
}
This function handles all the common codewords between PHP and Datepicker date format standards.
Plus, I added support for character escaping :
d m \o\f Y becomes dd mm 'of' yy
You may still have problems with symbols like 'W', 'L' that have no equivalent handled by Datepicker.
You cannot use the same format with datepicker that you're using with PHP.
Since PHP's date format only uses single letter codes, you're better off just taking the PHP date format and replacing each code to the corresponding value in the jQuery datepicker format, e.g.:
$PHPFormatOptions = array('y', 'Y', 'm', 'd');
$JSFormatOptions = array('yy', 'yyyy', 'mm', 'dd'); // and so on
$JSFormat = str_replace($PHPFormatOptions, $JSFormatOptions, $PHPFormat);
Not sure I'm quite with you, but this really shouldn't be an issue. You could either parse the front-end input: using DateTime::createFromFormat cf. php documentation for this, or use JSON.
Since JSON has an accepted standard way of formatting date strings, you can pass a JSON-stringified version of the input date to PHP, and json_decode it server-side. Both of these solutions are open to you, though I believe the first one to be easier to implement in your case.
If you want to be able to choose the format on both sides, the DateTime object is definitely what you need:
$date = new DateTime();
echo $date->format('Y-m-d').' <==> '.$date->format('y-M-j');
$postDate = $date->createFromFormat('y-m-d',$_POST['submitDate']);
echo $postDate->format('Y-m-d');
The format is explained on the page I've linked to.
Here is the solution:
function datepicker_format($format) {
static $assoc = array(
'Y' => 'yyyy',
'y' => 'yy',
'F' => 'MM',
'm' => 'mm',
'l' => 'DD',
'd' => 'dd',
'D' => 'D',
'j' => 'd',
'M' => 'M',
'n' => 'm',
'z' => 'o',
'N' => '',
'S' => '',
'w' => '',
'W' => '',
't' => '',
'L' => '',
'o' => '',
'a' => '',
'A' => '',
'B' => '',
'g' => '',
'G' => '',
'h' => '',
'H' => '',
'i' => '',
's' => '',
'u' => ''
);
$keys = array_keys($assoc);
$indeces = array_map(function($index) {
return '{{' . $index . '}}';
}, array_keys($keys));
$format = str_replace($keys, $indeces, $format);
return str_replace($indeces, $assoc, $format);
}
The magic double str_replace call caused by duplicating in needles and its replacement values, so that's why the string
m/d/Y
becomes
{{3}}/{{5}}/{{1}}
and after that this nests replacing with actual replacement values:
mm/dd/yy
Ok so the best solution for you would be to store everything in your website using time();
As far as I know datepicker can be set to work with dates for PHP timestamp
dateFormat : 'yy-mm-dd',
Edit :
Why would you store a date like : Y-m-d ?
It should be stored as timestamp or int

MySQL query for dates with CakePHP

I'm trying to select the values that fall between 2 dates, so I'll have to use <= and >=, however, my query is seemingly behaving as just less than or greater than and not considering values equal to the date.
I'm using CakePHP which saves dates in "Y-m-d h:i:a" format. I wanted to find dates on given week intervals (starting on Sundays), so I used the following.
$start_date = date('Y/m/d', strtotime('last Sunday', strtotime($timestamp)));
$formatted_start_date = str_replace("/","-",$start_date);
I tried to do find $start_date formatted as "Y-m-d" but then it wouldn't find the correct date, so I switched it to the way it is and used str_replace to format it to using "-" instead of "/".
$date_query = $this->Order->query("select * from orders where id = '$id' and created => '$formatted_start_date' and created <= '$current_timestamp' ");
Considering the time values in my database are in "Y-m-d h:i:a" format, can I use "Y-m-d" for date comparison? Is it possible to do a MySQL query that involves both LIKE and <= ?
No need to do a str_replace() - just get the Y-m-d:
$start_date = date('Y-m-d', strtotime('last Sunday', strtotime($timestamp)));
Then, instead of manually creating a query, use the CakePHP conventions (yes, you can use Y-m-d for date comparison even though the datetimes stored in the database are Y-m-d H:i:s)
$this->Order->find('all', array(
'conditions' => array(
'id' => $id,
'created >=' => $start_date,
'created <=' => $end_date . ' 23:59:59',
'my_field LIKE' => '%whatever%'
));
Though - this seems kind of strange - usually you're either looking for something by 'id' OR by a date range - not both. But - maybe you have a reason :)
And as you can see above, yes, you can add a 'LIKE' also if you need.
Above answer is totally correct, but you can take easier approach using cakePHP time helper, which has function daysAsSql, it transcribes and time-readable strings into database range.
http://book.cakephp.org/2.0/en/core-libraries/helpers/time.html#TimeHelper::daysAsSql
Just add condition's array like this.
$resl = $this->DBNAME->find('all',array(conditions=>array('date1>date','date1<date')));
Replace 'date' with your date.
This is worked for me.
Try this in your controller
$searchTutorQuery = $this->Tutordetails->find('all', array(
'conditions' => array(
"User.zip" => $zipcode1,
"Tutordetails.user_id"=>$uid,
"Tutordetails.subject_id" => $subjectName,
"Tutordetails.hourly_rate >=" => $hourly_rate
),
//"User.id =" => $userid,
'fields' => array('user_id', 'Tutordetails.subject_id', 'Tutordetails.hourly_rate',
'User.zip', 'Tutordetails.zip'),
'order' => array('Tutordetails.id DESC')
));

MongoDB & PHP - How do I exclude results from a date range delimited query?

Long time peruser, first time question asker ...
Using PHP to query our MongoDB page visit log, I would like to get a set of records between two time periods, but exclude results that have a certain userAgent. I've figured out the time range but cannot find anywhere that explains the exclude.
Here's what I have for the query so far:
$dateRange = $collection->find(array("timeStamp" => array('$gt' => $start,
'$lt' => $end)));
Looking for code to complete the find function to exclude the records with a "userAgent" starting with "ELB"
What you're looking for is $ne or $nin, depending on whether the value you want to exclude is a single value or array of values. eg:
$dateRange = $collection->find(array("timeStamp" => array('$gt' => $start, '$lt' => end), 'userAgent' => array('$ne' => new MongoRegex('/^ELB/'))));
Documentation here:
http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24ne
http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24nin
You could append {$not: /^ELB/} to the mongo query.
Not really sure about the equivalent PHP but try something like this:
$dateRange = $collection->find(array(
'timeStamp' => array(
'$gt' => $start,
'$lt' => $end
),
'userAgent' => array(
'$not' => new MongoRegex('/^ELB/')
)
));

PHP date() function inserting zeros into database

I have an array like so which has the column names of the table on the left and the associating values on the right.
$proceduredata = array
(
'patient_id' => $patientfk,
'name_id' => $procedurenamefk,
'department_id' => $departmentfk,
'dosage_id' => $dosagefk,
'edocument' => NULL, //not implemented yet
'user_id' => $this->session->userdata('userID'),
'duration' => NULL, //not implemented yet
'submitted' => date('d-m-Y H:i:s', now()),
'comment' => NULL, //to be implemented
);
This array is then passed into a SQL insert function. The insert works fine but my "Submitted" column is getting values of this only:
0000-00-00 00:00:00
I made sure the time formats are matching? Is there something I have missed thanks.
change the date format
submitted' => date('Y-m-d H:i:s', now())
I believe that the "now()" function is a sql function and you are using PHP with the "date()" funciton. Try changing "now()" to "time()" which will give you a proper unix timestamp that the "date()" function can use to create a properly formatted date.
EDIT: I just realized I am not familiar with codeignighter, so please excuse me if the "now()" function is part of that framework.
now() is not a function, change now() to time(). Alternatively, date()'s second paramater is optional if you omit it date automatically uses the current date/time:
echo date('d-m-Y H:i:s');
will echo the current date/time in the format requested.

Categories