When we pass a date value like this 2019-01-01 without the time 10:00:00, the time defaults to 00:00:00. So finally the db compatible value gets transformed into this: 2019-01-01 00:00:00. How can I force default it to 23:59:00 instead?
Example: I need to set an expiry_date attribute, but if I only take the date input 2019-01-08 from user, the user is going to assume that they will have the entire day as expiry date, when in reality it will expire at the very first second of 2019-01-08 because of the implicit default time 00:00:00.
How do I overcome this? How can I set a mutator for expiry_date that would turn this 2019-01-01 00:00:00 into this 2019-01-01 23:59:00?
Just use the following:
$expiryDate = Carbon::createFromFormat('Y-m-d', $date)->endOfDay()->toDateTimeString();
This will take the date (update date format if needed), switch to the end of the day and convert the resulting object into a date time string.
Or, use it as an attribute setter:
/**
* #param $value
*/
public function setExpiryDateAttribute($value)
{
$this->attributes['expiry_date'] = Carbon::createFromFormat('Y-m-d', $value)
->endOfDay()
->toDateTimeString();
}
You may use something like the strtotime() function to add something to the current timestamp. $expiry_date = date("Y-m-d H:i:s", strtotime('+5 hours')).
If you need variables in the function, you must use double quotes then like strtotime("+{$hours} hours"), however better you use strtotime(sprintf("+%d hours", $hours)) then.
I used an DateTime property method like below:
date_create($your_date)->modify('+1 day -1 microsecond'),
It works on Laravel because datetime is PHP native.
-> Source <-
Related
I'm using Carbon to manipulate dates I retrieved from my MySQL database. I have dates like the following:
2017-07-19 00:00:00
2017-06-26 15:27:57
As you can see, the first is the start of a day. When displaying dates like that, I would like to omit the time part. I know I can use a different format for each one. For example:
F d Y for dates without time.
F d Y g:ia for dates with time.
What I couldn't accomplish is a simple way to check if a date has a time part to apply one format or the other. Must I use individual getters to check the hour, minute and second?
If you just want to check if it's the start of the day, then it's fairly easy to check with Carbon's startOfDay() modifier and a comparison:
$date = Carbon::now(); // or whatever you're using to set it
$start = $date->copy()->startOfDay();
if($date->eq($start)) {
// do your formatting here
}
In the meanwhile its even easier. Use the is....() methods (see carbon comparison) like this:
$date = Carbon::now();
if($date->isStartOfDay()) { // check if hour is 00:00:00
// whatever
}
You can use the timestamp of the Carbon object minus the timestamp of "today" (which is yyyy-mm-dd 0000:00:00) and it will give you the number of seconds that passed from 00:00 to that date:
$secondsPassed = $carbonObject->timestamp - $carbonObject->copy()->startOfDay()->timestamp;
if ($secondsPassed > 8 * 60 * 60) {
// time is passed 08:00 am
}
I have this PHP code:
$from_date = new DateTime('April-22-2016');
$from_date->format( 'Y-m-d 00:00:00' );
$from_date->setTime(0,0,0);
print ' / '. $from_date_unix = $from_date->getTimestamp();
The above code prints a Unix timestamp of 1461356160, which means
GMT: Fri, 22 Apr 2016 20:16:00 GMT
The hours are 20:16:00 - which is strange, since I already set the time to 00:00:00 via
$from_date->setTime(0,0,0);
Is my code wrong? Do I need to check something in php.ini?
The date you provided as first argument to DateTime::__construct() does not use any of the standard date and time formats understood by PHP. Therefore, it tries to identify the date and time components in the string you provided.
A print_r($from_date) immediately after it was created reveals what PHP (mis-)understood from your date:
DateTime Object
(
[date] => 2016-04-22 00:00:00.000000
[timezone_type] => 1
[timezone] => -20:16
)
Before anything else, when it starts parsing a string for date & time, PHP initialize the new DateTime object with the current date, time and timezone. Then it overwrites the components it identifies in your string as follows:
April was correctly identified as the month name;
22 is the day of the month;
for some reason I don't know now, it set the time of the new object to 00:00:00;
the rest of the string (-2016) was used as timezone offset; i.e. -20:16 hours.
Maybe the way it works sounds silly to you but since you provided it a random string, this is the best it could get out of it.
The next line of your code ($from_date->format( 'Y-m-d 00:00:00' );) produces a string and doesn't modify the DateTime object. Because you don't do anything with the string returned by DateTime::format(), the entire line is a no-op.
The next line ($from_date->setTime(0,0,0);) also doesn't have any effect on $from_date because it's time already is 00:00:00.
Now it's clear why $from_date->getTimestamp() returns the time 20:16 GMT: when it's 00:00 at the timezone with offset -20:16, on the GMT timezone there already is 20:16.
In order to get what you want you need to use the DateTime::createFromFormat() static function:
$from_date = DateTime::createFromFormat(
'!F-d-Y',
'April-22-2016',
new DateTimeZone('GMT')
);
print ' / '. $from_date_unix = $from_date->getTimestamp();
Remark the exclamation mark (!) at the start of the format specifier. It tells PHP to reset all the date and time components to the Unix Epoch. This way the generated date already has the time 00:00:00 and there is no need to set it.
Its output is:
1461283200
You can parse the DateTime object with the right format with DateTime::createFromFormat
Use it like this:
$from_date = DateTime::createFromFormat('!F-d-Y', 'April-22-2016');
$from_date->format( 'Y-m-d 00:00:00' );
print ' / '. $from_date_unix = $from_date->getTimestamp();
I'm implementing the following in PHP with stores this string in the DB for the "created_at" column: Wed, 17 Dec 2014 14:53:02 +1100.
$created_at = date('r', $insta['created_time']);
Now I'd only like to do the insert if $created_at is more than a certain date, for example:
if ($created_at > "Wed, 15 Dec 2014 00:00:00 +1100") { //insert in to db }
That doesn't work though. I'd usually use strtotime() but unsure how to go about it when the data is set in that format. Also, the column type is varchar(255).
Aside from your question, you need to store datetime data in a datetime column. Mysql has specific functions and formatting for this reason. But, in order to store it will need to be in Y-m-d H:i:s format. Doing this will save you big hassles down the road.
In regards to your question, you can use PHP's DateTime class if you are using PHP version 5.2+.
$compareTime = new DateTime('2014-12-15 00:00:00'); //new datetime object//
$createdTime = new DateTime($created_at); //converts db into datetime object//
if ($createdTime > $comparedTime) { ..insert into DB.. }; //compare them//
Why are you storing WED in database..just store date with the php function date("Y-m-d H:i:s") and the table field type will be date..
This way mysql automatically give u facility to compare two dates. You can simply use if else statement to compare two dates.
for PHP version >= 5.3
Use date_create_from_format or DateTime::createFromFormat
Although I think strtotime would also work but to be sure pass date time format and value to above function. For detail of format see documentation.
Use strtotime().
$created_at = strtotime($insta['created_time']);
$checkdate = strtotime(date('Y-m-d H:i:s')); //here we have to insert check date
if($created_at > $checkdate){
}
In my PHP script I've got a function handling birthdays like so:
$dateTime = \DateTime::createFromFormat('U', $time);
The problem is that this returns false with negative $time numbers (i.e. dates before 1-1-1970). In the PHP docs there's a comment saying that indeed
Note that the U option does not support negative timestamps (before
1970). You have to use date for that.
I'm unsure of how to use Date to get the same result as DateTime::createFromFormat() gives though. Does anybody have a tip on how to do this?
If you just need to format a UNIX timestamp as a readable date, date is simple to use:
// make sure to date_default_timezome_set() the timezone you want to format it in
echo date('Y-m-d H:i:s', -12345);
If you want to create a DateTime instance from a negative UNIX timestamp, you can use this form of the regular constructor:
$datetime = new DateTime('#-12345');
I'm aware of two ways to get a timestamp from a relative date/time string in PHP:
strtotime: Allows user to specify their own $now value
DateTime object: Allows user to specify their own $timezone value
Is there a way to get a timestamp from a date/time string that allows one to specify both the timezone AND the $now value? It seems like the only way would be to use strtotime while temporarily overriding the default timezone for the entire php application and then setting it back immediately afterwards. That just seems like a hacky solution, and it would be nice if there were a cleaner way.
Edit: there seems to be some misunderstanding about what I'm trying to do. Here's a more concrete example:
"I want to find the timestamp corresponding to the string 'next tuesday at 3:00pm' within the America/Los_Angeles timezone AND specifying an arbitrary value for $now, such as March 14th, 2014 at 8:05am."
I've prepared an example. This may be want you want:
<?php
// Including the timezone int the time strings (thanks #Mike B!!!)
// will make it very easy. just strtotime() is required
// create a timestamp for March 14th PDT
$now = strtotime('14 March 2014 8:05am America/Los_Angeles');
// get the requested timestamp.
$nexTuesday = strtotime('next tuesday 3:00 pm America/Los_Angeles', $now);