compering times (H:i:s) , ignoring seconds if zero - php

so i work with a system where i have to do lots of time comparing and by that i mean H:i:s
the problem is sometimes there are 00 for seconds and sometimes it isnt and since times are given to me as string
comparing to similar times with and without second zeros will fail
here we have 2 similar times but my if will fail for missing seconds in one
$db_time = '11:20';
$given_time = '11:20:00' ;
if($db_time == $given_time )
{
echo "same time";
}
else
{
echo "different time";
}
right now i use something like
if( in_array( $given_time , [$db_time , "$db_time:00"] ) )
{
echo "same time";
}
else
{
echo "different time";
}
which is not ideal !! specially since i dont know which one is missing the zeros
i do use with carbon , i prefer if i can solve this by using carbon

$db_time = '11:20';
$given_time = '11:20:00';
if(Carbon::parse($db_time)->eq($given_time)) {
echo "same time";
} else {
echo "different time";
}

You can create Date objects and compare them.
$db_time = '11:20';
$given_time = '11:20:00';
echo isSameTime($db_time, $given_time) ? 'same' : 'different';
function isSameTime(string $time1, string $time2): bool
{
return new DateTime($time1) == new DateTime($time2);
}
echoes
same

Related

Php check if time string whole hour like "8:00am"

I have series of time strings like "8:00am", "8:15am", "8:30am" I also have timestamps for these times as keys of the arrays where as times are values so array would be like this:
Note: Timestamps are dummy in this example
array(
144441415=>"8:00am",
1444784744=>8:30am
...
.....
);
I would like to know if hour is whole hour for example "8:00am", "9:00am" are whole hours but "8:45am" or "9:30am" are not whole hours. I would like to filter whole hours from array as mentioned above. Thanks.
You could do something like this:
$times = array(
144441415=>"8:00am",
1444784744=>"8:30am",
1444784745=>"8:45am",
1444784746=>"9:00am",
1444784747=>"10:00am",
);
foreach ($times as $time) {
if (date("H:00:00", strtotime($time)) == date("H:i:00", strtotime($time))) {
echo '<br>Whole Hour: '.$time;
}
else {
echo '<br>Not Whole Hour: '. $time;
}
}
Thank you Rudie I was able to get whole hour from number of seconds, thank you for your hint, so I did something like this:
//Loop through each hour of the day by getting both key and value
foreach( $hours_of_day $timestamp=>$time_string )
{
//If timestamp mod by number of seconds in hours is zero this means whole hour
if( ($timestamp%3600) == 0 )
{
echo "Whole hour = $timestring<br />";
}
}
For the ones who may encounter this question, the best way to achieve this is the following:
define("BR", "<br />");
$data = array(
144441415=>"8:00am",
1444784744=>"8:30am"
);
$tmp_dto;
$tmp_mins;
foreach($data as $hour){
$tmp_dto = DateTime::createFromFormat("H:iA", $hour);
$tmp_mins = $tmp_dto->format("i");
if($tmp_mins == "00"){
echo "ROUND".BR;
}
else{
echo "NOT ROUND".BR;
}
}
Outputs
ROUND
NOT ROUND

Is there anyway way to logically compare PHP DateTime objects?

This is part of a simple project that logs payroll hours as a datetime object in MySQL 5.5. I am trying to compare two datetime values to see if they are at least 30 minutes apart. Sounds simple enough but the value of $lastshiftend keeps being set to the same value as $mealendtime and I don't see where or how. That seems to be the only problem but there definitely could be other things I am missing. TIA.
if ($result = mysqli_query($conn, $select)) {
$row_count = mysqli_num_rows($result);
if($row_count == 1) {
// 30 Minute Meal Break
$lastshiftend = new DateTime($row[3]);
$mealendtime = new DateTime('NOW');
$mealtime = $mealendtime->diff($lastshiftend);
$mealminend = $lastshiftend->add(new DateInterval(PT30M));
// $mealminend = $lastshiftend->modify('+ 30 minute');
if($mealendtime < $mealminend) {
echo '<br>Colorado State law requires meal breaks to be at least 30 minutes in length.';
echo '<hr>Main Menu';
} else {
echo 'Log it!';
// header("Location: ./ActionClockIn.php");
}
} else {
echo 'Error! If you ended up here something broke!.';
echo '<hr>Main Menu';
}
}
Unless you use DateTimeImmutable() your DateTime objects will be modified when you call methods like DateTime::add() or DateTime::modify()
$lastshiftend = new DateTimeImmutable($row[3]);
// Now $lastshiftend is unchanged
$mealminend = $lastshiftend->add(new DateInterval(PT30M));
It looks like you will need that for both DateTime objects
$lastshiftend = new DateTimeImmutable($row[3]);
$mealendtime = new DateTimeImmutable(); //"NOW" is not necessary
$mealtime = $mealendtime->diff($lastshiftend);
$mealminend = $lastshiftend->add(new DateInterval(PT30M));

php date_parse("Feb 2010") gives day == 1

There is what I would call a bug in date_parse when there is no day. $d = date_parse("Feb 2010") will give $d["day"] == 1.
See the comment on this on the date_parse manual page.
Any nice workaround for this problem? :-)
UPDATE
The date comes from published research reports. Unfortunately this means that they could look in different ways. I want to convert them to more standard ISO format when displaying the references. To help the readers I want always to include just the given fields (years, month, date). So this should be valid (and just give me the year):
2010
This should be valid, but just give me 2010-02 so to say:
Feb 2010
UPDATE 2
So far I have seen two bugs here in date_parse. It can't parse 2010. And it gives a day though there is no day in Feb 2010.
I can of course write a fix for this, but surely someone has already done this, or???
The above bugfix routine is great, Leo, thanks. Unfortunately it still trips over January, thinking that 2014-01 is the same as 2014-01-01 --- we're eleven-twelfths of the way there.
The date formats that PHP can parse, that don't contain a day-of-month, appear to be (in php_src:date/lib/parse_date.re):
gnudateshorter = year4 "-" month;
datenoday = monthtext ([ .\t-])* year4;
datenodayrev = year4 ([ .\t-])* monthtext;
Very few, conveniently. We can run the same regexes on $dateRaw, essentially reverse-engineering what the parser had decided.
(Side observations: the above excludes formats like 5/2016, which is parsed as "20 May with some extra characters at the end"; they are also similar to day-of-year and week-of-year formats, so we'll try not to trip over those.)
function date_parse_bugfix($dateRaw) {
$dateRaw = trim($dateRaw);
// Check for just-the-year:
if (strlen($dateRaw) === 4 && preg_match("/\d{4}/", $dateRaw) === 1) {
$da = date_parse($dateRaw . "-01-01");
$da["month"] = false;
$da["day"] = false;
}
else {
$da = date_parse($dateRaw);
if ($da) {
// If we have a suspicious "day 1", check for the three formats above:
if ($da["day"] === 1) {
// Hat tip to http://regex101.com
// We're not actually matching to monthtext (which is looooong),
// just looking for alphabetic characters
if ((preg_match("/^\d{4}\-(0?[0-9]|1[0-2])$/", $dateRaw) === 1) ||
(preg_match("/^[a-zA-Z]+[ .\t-]*\d{4}$/", $dateRaw) === 1) ||
(preg_match("/^\d{4}[ .\t-]*[a-zA-Z]+$/", $dateRaw) === 1)) {
$da["day"] = false;
}
}
}
}
return $da;
}
No answers so I answer my own question. Here is a workaround the problems I saw.
// Work around for some bugs in date_parse (tested in PHP 5.5.19)
// http://php.net/manual/en/function.date-parse.php
//
// Date formats that are cannot be parsed correctly withoug this fix:
// 1) "2014" - Valid ISO 8061 date format but not recognized by date_parse.
// 2) "Feb 2010" - Parsed but gives ["day"] => 1.
function date_parse_5_5_bugfix($dateRaw) {
// Check "2014" bug:
$dateRaw = rtrim($dateRaw);
$dateRaw = ltrim($dateRaw);
if (strlen($dateRaw) === 4 && preg_match("/\d{4}/", $dateRaw) === 1) {
$da = date_parse($dateRaw . "-01-01");
$da["month"] = false;
$da["day"] = false;
} else {
$da = date_parse($dateRaw);
if ($da) {
if (array_key_exists("year", $da)
&& array_key_exists("month", $da)
&& array_key_exists("day", $da))
{
if ($da["day"] === 1) {
// Check "Feb 2010" bug:
// http://www.phpliveregex.com/
if (preg_match("/\b0?1(?:\b|T)/", $dateRaw) !== 1) {
$da["day"] = false;
}
}
}
}
}
return $da;
}
Some tests (visual ;-) )
$a = date_parse_5_5_bugfix("2014"); print_r($a);
$b = date_parse_5_5_bugfix("feb 2010"); print_r($b);
$c = date_parse_5_5_bugfix("2014-01-01"); print_r($c);
$d = date_parse_5_5_bugfix("2014-11-01T06:43:08Z"); print_r($d);
$e = date_parse_5_5_bugfix("2014-11-01x06:43:08Z"); print_r($e);
Can you try:
$dateTime = strtotime('February, 2010');
echo date('Y-m', $dateTime);

PHP if with an array SQL

I've got a problem here
$resultContLog = mysql_query("SELECT count(*) FROM dailyLogs WHERE data_log > NOW() - INTERVAL 30 MINUTE and server_id_log=".$Fid.";");
$Adata = mysql_fetch_assoc($resultContLog);
if ($Adata > 0)
{
echo 'OK';
}
else
{
echo 'NOT OK';
}
My php function returns the number of rows; i did this to include new logs if it happen later than 10 minutes. The if ($Adata > 0) statement doesn't work properly. Can you guys help me, please?
to check this , use this
Your need to check for count column you are getting from query if it is grater than zero, here it is used as alias of "total"
$resultContLog=mysql_query("SELECT count(*) as total FROM dailyLogs WHERE data_log > NOW() - INTERVAL 30 MINUTE and server_id_log=".$Fid.";");
$Adata=mysql_fetch_assoc($resultContLog);
if($Adata['total'])
{
echo 'OK';
}
else
{
echo 'NOT OK';
}
You fetch the DB result as an array, thus you can count it:
if (count($Adata)) {
echo 'ok';
} else {
echo 'not ok';
}
Your query is a bit of a mess though. Maybe you could place some logic outside of the SQL.
The date function of PHP is flexible and works good with MySql.
// instead of NOW() - INTERVAL 30 MINUTE
date("Y-m-d H:i:s", time() - 60*30);
Regards
*) edit: What #esqew said

taking the latest content from a dynamic array

A small background of myself is that I'm fairly new to php. I work as an IT assistant and have been asked to edit one of the pages our designers use for samples. I cannot point you to the page as it is an internally hosted page.
I'm honestly not even sure if the question is asked correctly but please bear with me.
The page has a 'request completion date' field within a table that outputs 6 dates in a list, the designers only want it to output the latest date from that list instead of all 6, usually these will be empty so it's no use having them printed.
The code to put them is as follows;
if ($database_data['request_confirmed_comp_date'] > "0")
{ $request_confirmed_completion_date = date("d/m/Y", $database_data['request_confirmed_comp_date']); }
else
{ $request_confirmed_completion_date = " -"; }
if $database_data['request_confirmed_comp_date2'] > "0")
{
$request_confirmed_completion_date2 = date("d/m/Y", $database_data['request_confirmed_comp_date2']);
}
else
{
$request_confirmed_completion_date2 = " -";
}
if ($database_data['request_confirmed_comp_date3'] > "0")
{
$request_confirmed_completion_date3 = date("d/m/Y", $database_data['request_confirmed_comp_date3']);
}
else
{
$request_confirmed_completion_date3 = " -";
}
if ($database_data['request_confirmed_comp_date4'] > "0")
{
$request_confirmed_completion_date4 = date("d/m/Y", $database_data['request_confirmed_comp_date4']);
}
else
{
$request_confirmed_completion_date4 = " -";
}
if ($database_data['request_confirmed_comp_date5'] > "0")
{
$request_confirmed_completion_date5 = date("d/m/Y", $database_data['request_confirmed_comp_date5']);
}
else
{
$request_confirmed_completion_date5 = " -";
}
if ($database_data['request_confirmed_comp_date6'] > "0")
{
$request_confirmed_completion_date6 = date("d/m/Y", $database_data['request_confirmed_comp_date6']);
}
else
{
$request_confirmed_completion_date6 = " -";
}
if ($database_data['request_date_required'] > "0")
{
$request_date_required = date("d/m/Y", $database_data['request_date_required']);
}
else
{
$request_date_required = "-";
}
if ($database_data['request_date'] > "0")
{
$request_date = date("d/m/Y", $database_data['request_date']);
}
else
{
$request_date = "-";
}
It is then called into play using;
echo '<td><b>1.</b>'.$request_confirmed_completion_date.'<br /><b>2.</b>'.$request_confirmed_completion_date2.'<br /><b>3.</b>'.$request_confirmed_completion_date3.'<br /><b>4.</b>'.$request_confirmed_completion_date4.'<br /><b>5.</b>'.$request_confirmed_completion_date5.'<br /><b>6.</b>'.$request_confirmed_completion_date6.'</td>';
Now I may not have much php knowledge, but I know that's a horribly long way of doing that. Is there anyway that I could pull the latest date out of an array, created by the the first block of code, and then output them into the table.
Thanks for any help or advice, even if you could just point me in the right direction as to what loop to use would be helpful.
Edit: I've uploaded the full file online here, hopefully that will clear up some confusion.
You want to use the php function asort. Since all of your values look to be numeric, you should be able to do a standard sort and pull off the last item with array_pop.
It might look something like this:
asort($database_data);
$latest = array_pop($database_data);
echo date('m/d/Y', $latest);
Create an array with the variable names, like if the variables are $A, $B and $C, then
$vars = array("A","B","C");
foreach($vars as $var_name){
if($database_data[$var_name] > "0")
$$var_name = $database_data[$var_name];
else
$$var_name = "-";
}
Note: A, B and C are dummy variable names, as the variable names are too long in your code :-)
Firstly there is a problem with your if conditions, you can't say $x > "0" because with using double-quotes you are using 0 as a string. You should use integer $x > 0.
Now here my answer :
I couldn't understand your system very well, so i'm assuming always there will be 6 dates.
for($q = 0;$q < 6; $q++)
{
if($database_data[...][$q] > 0)
$dates[] = date("d/m/Y", $database_data['...'][$q]);
else
$dates[] = " - ";
}
As you see, you have to fetch your database datas as an array $database_data['...'][].
If you can tweak the original SQL statement, which probably looks something like this:
select request_confirmed_comp_date, request_confirmed_comp_date2, request_confirmed_comp_date3, request_confirmed_comp_date4, request_confirmed_comp_date5, request_confirmed_comp_date6
from sometablename
where somefield='something'
You can tweak it to use shorter (and consistent) field names
select request_confirmed_comp_date as date1, request_confirmed_comp_date2 as date2, request_confirmed_comp_date3 as date3, request_confirmed_comp_date4 as date4, request_confirmed_comp_date5 as date5, request_confirmed_comp_date6 as date6
from sometablename
where somefield='something'
And then in PHP use an array to iterate over the field names like so:
<?php
$lastCompletionDate=""; //start by assuming there was no completion date
for($i=1;$i<=6;$i++) { //check to see if any field is after the last known completion date
if ($database_data['date'.$i] && (date("d/m/Y", $database_data['date'.$i]) > $lastCompletionDate)) {
//if so, store the new date
$lastCompletionDate=date("d/m/Y", $database_data['date'.$i]);
}
}
if($lastCompletionDate) {
echo "The last completion date was $lastCompletionDate\n";
}else {
echo "There was no completion date.\n";
}
?>
An alternative solution would be to use the SQL engine's own internal functions to find the highest date like so:
select greatest(request_confirmed_comp_date,
request_confirmed_comp_date2,
request_confirmed_comp_date3,
request_confirmed_comp_date4,
request_confirmed_comp_date5,
request_confirmed_comp_date6) as greatestcompdate
from sometablename etc...
and then refer to that in PHP like
<?php
if($database_data['greatestcompdate']) {
echo "There was a greatest completion date and it was $database_data[greatestcompdate]";
}
?>

Categories