Reputation: 7851
new \DateTime();
/*
DateTime Object
(
[date] => 2016-04-20 04:45:24.000000
[timezone_type] => 3
[timezone] => UTC
)
*/
How do I trim hours to get my DateTime object like this:
/*
DateTime Object
(
[date] => 2016-04-20 00:00:00.000000
[timezone_type] => 3
[timezone] => UTC
)
*/
The only way that I know is:
$date = new \DateTime();
$date->format('Y-m-d');
$date = new \DateTime($date->format('Y-m-d'));
But I don't like this solution.
Upvotes: 24
Views: 32043
Reputation: 4867
In case it helps anybody, I've used the following...
new DateTime("00:00");
...this has the advantage of being as short as possible, plus being easy to read. You can also just use...
new DateTime("0:0");
...but it's less easy to read. As above, if you have an object already already, just use...
$object->setTime(0,0)
Upvotes: 0
Reputation: 1060
A very clean solution is to create a Value Object called Date
that wraps a \DateTime
and set the time part to zero. Here an example:
class Date
{
private DateTimeImmutable $dateTime;
public function __construct(DateTimeInterface $dateTime)
{
$this->dateTime = DateTimeImmutable::createFromInterface($dateTime)->setTime(0, 0);
}
public function format($format = ''): string
{
return $this->dateTime->format($format);
}
}
You can also customize the format
method to only use the 'Y-m-d'
format.
Using a Value Object is much more expressive since reading the code you always know if your variable is just a date or a date with time.
Upvotes: 2
Reputation: 915
For those of you who love doing stuff in the shortest possible way, here are one-liners for getting the current date or parsing a string date into a DateTime object and simultaneously set hours, minutes and seconds to 0.
For today's date:
$dateObj = new DateTime ("today");
For a specific date:
$dateObj = new DateTime ("2019-02-12"); //time part will be 0
For parsing a specific date format:
$dateObj = DateTime::createFromFormat ('!Y-m-d', '2019-02-12'); //notice the !
Upvotes: 12
Reputation: 4103
Sadly PHP doesn't have a native class for dealing with dates without time. Since Doctrine and a lot of other libraries work with DateTime anyway, the best approach I've found is just using a helper class to create DateTime objects with time set to 0.
class DateFactory
{
public static function createOnlyDateFromFormat(string $format, string $value): \DateTime
{
$date = \DateTime::createFromFormat($format, $value);
$date->setTime(0, 0, 0);
return $date;
}
}
Upvotes: 0
Reputation: 4808
extend DateTime for comfort
class DT extends \DateTime {
static function __diff($dt1, $dt2 = NULL){
$a = gettype($dt1) === "string" ? new DateTime($dt1) :$dt1;
$b = gettype($dt2) === "string" ? new DateTime($dt2) :$dt2 ?? new DateTime();
return $a->diff($b);
}
public function __get($name) { // sql format
switch ($name) {
case "date":
return $this->format("Y-m-d");
case "time":
return $this->format("H:i:s");
case "datetime":
return $this->date." ".$this->time;
default:
return $this->$name;
}
}
public function days2($date){
$to = gettype($date) === "string" ? new \DateTime($date):$date;
return (int)$this->__diff($this->date,$to)->format('%R%a');
}
}
so
$d=new DT();
echo $d->date;
echo $d->days2('2018-10-21')
Upvotes: 0
Reputation: 26153
set argument for constructor
$d = new \DateTime("midnight");
UPD: if an object already exists with any time
$d->settime(0,0);
result
DateTime Object
(
[date] => 2016-04-20 00:00:00.000000
[timezone_type] => 3
[timezone] => UTC
)
Upvotes: 53