Carbon: displaying hours and minutes? - php

I have recently been using Carbon to display humanized time strings, but for some reason I can only get it to show the main factor, for example, I have a date that it needs to show how long until that date is. So for example, if its 6 days, 4 hours and 32 minutes away from now, it currently only displays '6 days'.
How would I go about getting it to display the hours too, and possibly the minutes? It's kind of horrible looking when it only gives you the days, and many people may want to know more like the hours and seconds?
I can't find anything on the Carbon documentation for this. I am using it inside a laravel 5.3 view if that's even relevant.
Heres my code:
{{ \Carbon\Carbon::createFromTimeStamp(strtotime($item->created_at))->diffForHumans() }}

You shouldn't use diffForHumans()in this case, because it returns only a string on which one can no longer work. This is an end result.
It is better to work with a Carbon object, like this :
$created = \Carbon\Carbon::createFromTimeStamp(strtotime($item->created_at));
And then, add this in the view :
{{ $created ->diff(\Carbon\Carbon::now())->format('%d days, %h hours and %i minutes'); }}
You can extend for a larger period :
$created ->diff(\Carbon\Carbon::now())->format('%y year, %m months, %d days, %h hours and %i minutes');
EDIT (according to the comments) :
If you do :
$diff = $created->diff(Carbon::now());
var_dump($diff);
You get this result :
object(DateInterval)[113]
public 'y' => int 0
public 'm' => int 0
public 'd' => int 6
public 'h' => int 4
public 'i' => int 32
public 's' => int 29
public 'f' => float 0.397424
public 'weekday' => int 0
public 'weekday_behavior' => int 0
public 'first_last_day_of' => int 0
public 'invert' => int 0
public 'days' => int 6
public 'special_type' => int 0
public 'special_amount' => int 0
public 'have_weekday_relative' => int 0
public 'have_special_relative' => int 0
// results depend of the current time
From there, you browse the elements to create the best answer to your needs.

Show only Hours:Minutes (11:11)
To display only Hours:Minutes you can use:
$curr = \Carbon\Carbon::now()->format('H:i');
echo $curr; // 11:11
If you have to set a timezone you have to use the timezone function. You can pass to these function your timezone timezone('Your/Zone')
$curr = `\Carbon\Carbon::now()->timezone('Europe/Amsterdam')->format('H:i');
echo $curr; // 12:11

Related

PHP Bug day of year [duplicate]

This question already has answers here:
Convert day of the year to datetime in php
(2 answers)
Closed 2 years ago.
I'm trying to convert day of year into date.
So no problem i use DateTime::createFromFormat with z and Y.
DateTime::createFromFormat('z Y', '199 2020');
/*RESULT*/
object(DateTime)[3]
public 'date' => string '2020-07-19 12:45:24.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/Paris' (length=12)
But when i test the result i get the wrong day of year...
date('z Y', strtotime('2020-07-19'));
/*RESULT*/
'198 2020' (length=8)
So i trying this
DateTime::createFromFormat('z Y', date('z Y', strtotime('2020-07-19')));
/*RESULT*/
object(DateTime)[3]
public 'date' => string '2020-07-20 12:52:10.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/Paris' (length=12)
if i check day of year 199 of 2020 on this website: https://www.calendrier.best/numero-de-jour-2020.html
I get 2020-07-17
What i'm doing wrong ??
If you know the year, you can use something like this. Outputs:
string(10) "2020-07-17"
Code:
<?php
$dayOfYearNumber = 199;
$year = 2020;
// Add day of year number to the first day of the year, substracting 1 because Jan 1st will be the first day.
$date = (new DateTime("$year-1-1"))->add(new DateInterval('P' . $dayOfYearNumber - 1 . 'D'));
var_dump($date->format('Y-m-d')); // string(10) "2020-07-17"
PHP only detects some standards like you can see here https://www.php.net/manual/de/datetime.formats.date.php
In Your first example you defined your format but strtotime() has no such parameter
If you have these values as variable you could use mktime() instead https://www.php.net/manual/de/function.mktime
But I recommend to always give PHP a month e.x. January

Carbon createFromFormat unexpected result

::createFromFormat() results in being one month ahead:
var_dump($_GET['archive']);
var_dump(Carbon::createFromFormat('m/Y', $_GET['archive']));
Result:
string '11/2015' (length=7)
object(Carbon\Carbon)[160]
public 'date' => string '2015-12-01 10:38:41.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/London' (length=13)
Seems that you just got unlucky because you were testing on the 31st of the month.
However, this is (apparently) a documented feature. See: http://php.net/manual/en/datetime.createfromformat.php
If you set your format mask "correctly", it works as you'd expect.
$x = Carbon::createFromFormat ('m/Y', '04/2009');
$y = DateTime::createFromFormat ('m/Y|', '04/2009');
dd ($x, $y);
To avoid ambiguity, the Carbon function is just a wrapper for the underlying DateTime function of PHP; I'm just aiming to prove that this is not a Carbon feature that's causing our headache.
If you test on the 31st of the month, $x above will be read as 31 April 2009 which will be displayed as 1st May.
With the pipe symbol in the mask though, all the non-declared time variables (H, i, s) are set to zero, and date variables (d, m) set to 1, so $y will always respond as you expect regardless of the day of the week.
For me testing at 17:46 in the evening of the 4th day of the month, the above code produces the following:
Carbon #1233769590 {#219 ▼
date: 2009-02-04 17:46:30.0 Europe/London (+00:00)
}
DateTime #1233446400 {#217 ▼
date: 2009-02-01 00:00:00.0 Europe/London (+00:00)
}
This is a really weird implementation of date/time function in my opinion. The only real-world situation that you'd want to use this function in, is if you're reading data from an external source (such as an XML "date" field).
Which programmer on earth would want their program to assume that the missing time (or in your case, day) component of the incoming data, should be taken from the runtime execution time? It's absolutely crazy bonkers.
It seems that Carbon uses the current day if not provided. Hence
var_dump(Carbon::createFromFormat('m/Y', '10/2015'));
var_dump(Carbon::createFromFormat('m/Y', '11/2015'));
results e.g. on July 31st in
object(Carbon\Carbon)[156]
public 'date' => string '2015-10-31 11:03:10.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/London' (length=13)
object(Carbon\Carbon)[138]
public 'date' => string '2015-12-01 11:03:10.000000' (length=26)
public 'timezone_type' => int 3
public 'timezone' => string 'Europe/London' (length=13)
as October has 31st but "November 31st is actually December 1st".

php count month quantity with difference less than 30 days

I need to get difference between months, independently of days.
if i do this:
$todaStart = new DateTime("2015-06-30");
$dateEnd = new DateTime("2015-07-01");
$diff = $todaStart->diff($dateEnd);
var_dump($diff);
object(DateInterval)[3]
public 'y' => int 0
public 'm' => int 0
public 'd' => int 1
public 'h' => int 0
public 'i' => int 0
public 's' => int 0
[...]
the "m" parameter is 0, but the month changed, so for the counts that i need to do, i need that the result be 1
The same happens if i change the month to "08", it should count 2 month difference, but the response come as 1 month.
Digging on the web i found on this site this solution, hope it help others.
$d1= new DateTime("2015-06-01");
$d2= new DateTime("2015-07-30");
$y1 = $d1->format('Y');
$m1 = $d1->format('m');
$y2 = $d2->format('Y');
$m2 = $d2->format('m');
$diff = (($y2 - $y1) * 12) + ($m2 - $m1);
// var_dump($diff) output 1

Zend_Date::sub() and ISO_8601 calculating hour difference wrong

I want to calculate time difference between two Zend_Date objects (for countdown calculator):
$now = new Zend_Date($now_datetime, Zend_Date::ISO_8601);
$end= new Zend_Date($end_datetime, Zend_Date::ISO_8601);
echo $now->getIso();
echo $end->getIso();
$expires=array();
$expires['expired']=false;
if($end->isEarlier($now)){
$expires['expired']=true;
return $expires;
}
$dif=$end->sub($now);
$expires['days']=($dif->getDay()->toValue()/(60*60*24));
$expires['hours']=($dif->getHour()->toValue()/(60*60));
$expires['minutes'] = $dif->getMinute()->toValue()/60;
$expires['seconds'] = $dif->getSecond()->toValue();
var_dump($expires);
For $now_datetime ='2012-06-30 01:01:01' and $end_datetime='2012-06-30 23:59:59', the result is
2012-06-30T01:01:01+02:00
2012-06-30T23:59:59+02:00
//array
'expired' => boolean false
'days' => int 0
'hours' => int 22
'minutes' => int 58
'seconds' => int 58
and it is OK.
But for For $now_datetime ='2012-06-30 00:01:01' and $end_datetime='2012-06-30 23:59:59', the result is
2012-06-30T00:01:01+02:00
2012-06-30T23:59:59+02:00
//array
'expired' => boolean false
'days' => int 1
'hours' => int -1
'minutes' => int 58
'seconds' => int 58
and it is NOT OK. I expect 'hours' to be 23, not -1 ?!
I am running MAMP with php 5.3, Zend_Framework 1.10.
What is wrong with that? ISO_8601 is used for MySQL 'datetime' data and I don't wanto to change to mktime()...
try to set
date_default_timezone_set('UTC');
in your index.php.. it will work fine..

Code loops optimization in PHP

Is there any way to optimize this piece of code to work faster? I'd appreciate any suggestions!
This piece of code processes the transferring of edges during graph creation.
foreach($times_arrival as $city_id => $time_points) {
// if city is not prohibited for transfers and there is and exists any departure times for this city
if (isset($times_departure[$city_id]) && isset($cities[$city_id]))
{
foreach($times_arrival[$city_id] as $t1_info)
{
foreach($times_departure[$city_id] as $t2_info)
{
if ($t1_info[0] != $t2_info[0]) //transfers are allowed only for different passages
{
$t1 = $t1_info[1];
$t2 = $t2_info[1];
$vertex_key = new Vertex($city_id, $t1, 1);
$vertex_key = $vertex_key->toString();
//minimum transfer time is 10 min.
if (date('H:i', strtotime($t2)) > date('H:i', strtotime('+ 10 minutes', strtotime($t1))))
{
$this->graph[$vertex_key][] = new Edge(
NULL,
$vertex_key,
new Vertex($city_id, $t2, 0),
(float) 0,
$f((strtotime($t2) - strtotime($t1)) / 60, 0, 1) //edge weight
);
}
//if transfer is on the bound of the twenty-four hours
else if (date('H:i', strtotime('+ 24 hours', strtotime($t2))) > date('H:i', strtotime('+ 10 minutes', strtotime($t1))))
{
$this->graph[$vertex_key][] = new Edge(
NULL,
$vertex_key,
new Vertex($city_id, $t2, 0),
(float) 0,
$f(strtotime('+ 24 hours', strtotime($t2)) - strtotime($t1) / 60, 0, 1) //edge weight
);
}
}
}
}
}
}
example of variables:
var_dump($times_arrival); //$times_departure have the same structure
array
3 =>
array
0 =>
array
0 => string '1' (length=1)
1 => string '08:12' (length=5)
1 =>
array
0 => string '2' (length=1)
1 => string '08:40' (length=5)
41 =>
array
0 =>
array
0 => string '21' (length=2)
1 => string '12:40' (length=5)
Thank you all!
The reason of slow speed was coz of using functions strtotime() and date().
In that case only you can say whether you chose a good or bad algorithm. In my point of view your code not has no extra computations.
Only one recommendation - use Xdebug to profile your code and find out where the bottleneck is, if possible.

Categories