I have a timestamp variable column in a mysql database. Trying to convert a carbon timestamp to something that I can input there, but Carbon::now() only returns a Carbon object and when I try to use the timestamp string of the Carbon object, it does not register in mysql.
public function store(CreateArticleRequest $request){
$input = $request->all();
var_dump($input); // JUST SO YOU CAN SEE
$input['published_at'] = Carbon::now();
var_dump($input); // JUST SO YOU CAN SEE
Article::create($input);
}
My first var dump is like so:
array (size=4)
'_token' => string 'Wy67a4hWxrnfiGz61wmXfYCSjAdldv26wOJiLWNc' (length=40)
'title' => string 'ASDFasdf' (length=8)
'body' => string 'asdfasdf' (length=8)
'published_at' => string '2015-08-26' (length=10)
My second var dump is like so.
The mysql column relating to "published_at" is a timestamp variable. How an I suppose to convert this from a Carbon Object?
Thanks in advance.
The short answer is that toDateTimeString() is what you're looking for:
$input['published_at'] = Carbon::now()->toDateTimeString();
See http://carbon.nesbot.com/docs/ for more options, including toDateString() if you just want the date part and not the time.
But an even better way to handle it would be to let Laravel handle casting the date value to/from a Carbon object for you. See https://laravel.com/docs/5.4/eloquent-mutators#date-mutators.
The problem is in your date string, for example, you have this:
public function setCrbDateAttribute($value)
{
$this->attributes['crb_date'] = \Carbon\Carbon::createFromFormat('d-m-Y h:i', $value);
}
Now, if there is a date like 10-12-2014 then this error will occur because the hour and minute is missing. So you make sure that the date contains all the pars and also make sure that the date string contains - as a separator not /.
In other words, check the $value before you use Carbon and make sure your date string contains exactly the same formatted string you've used in the method.
This also happens in an accessor method, so check the date value first before you use it in Carbon::createFromFormat().
If you are getting the date from user input then validate the date before using it using date or date_format:format rule, check the validation here.
Answer ref:
Laravel/Carbon Timestamp 0000-00-00 00:00:00 or Unexpected data found. Unexpected data found. Data missing
You can also set Mutator on your model.
public function setPublishedAt($value)
{
$this->attributes['published_at'] = strtotime($value);
}
to convert to timestamp
$model -> setPublishedAt('2015-08-26'); // 1440572400
or you can just convert the date to timestamp using strtotime
strtotime — Parse about any English textual datetime description into a Unix timestamp
Hope this help.
Related
Im reading an excel file a column with values like "1:45:00. But when print_r($value["time"]) this value from my array I got a Carbon object like this:
Carbon\Carbon Object
(
[date] => 2018-10-30 01:45:00.000000
[timezone_type] => 3
[timezone] => America/US
)
Then, when I insert to a bulk array my value with:
"time"=>$value["time"]
In the database I got: 2018-10-30 01:45:00
How can I insert only 01:45:00 and not the entire timestamp?
EDIT: I thought that $value["time"]->date->format("H:i:s") would works but I got the error "Trying to get property 'date' of non-object"
EDIT 2: This is how I read the data:
The excel is like:
date time
---------- -------
30-10-2018 01:45:00
The code where I read the excel:
$data = Excel::selectSheetsByIndex(0)->load($path, function($reader) {
})->get()->toArray();
foreach ($data as $key => $value) {
$time = Carbon::createFromFormat('Y-m-d h:i:s',$value["time"])->format('h:i:s');
print_r($time);
die();
}
The output:
Call to a member function format() on null
What you need is the formatting here:
$dt = Carbon::now();
$dt->toTimeString(); //14:15:16
Carbon\Carbon is an extension to php's DateTime, so you can read at php.net to learn more.
Although America/US is not a valid timezone, so there's something going on with that.
Anyway,
In the database I got: 2018-10-30 01:45:00
If your data type is a TIMESTAMP or a DATETIME, mysql will always have a date component for data in that column.
First, let's get the time out of the $value array to make the rest of the discussion easier to understand and debug:
$time = $value["time"];
From here on out, pay no attention to the internal fields revealed by var_dump. They may or may not actually exist like that in the object. Use the mostly-well-documented interface methods documented in the link above or in the Carbon docs. The fields given by var_dump will just confuse you otherwise.
If you just want the time of day represented as a string, you use the DateTime::format() method:
$timestr = $time->format('H:i:s');
Note that if you insert that string in a database with a DATETIME column type, it won't work. Mysql will require a string that includes date information.
The code snippet that follows doesn't seem to match with the code you show above:
$data = Excel::selectSheetsByIndex(0)->load($path, function($reader) {
})->get()->toArray();
foreach ($data as $key => $value) {
$time = Carbon::createFromFormat('Y-m-d h:i:s',$value["time"])->format('h:i:s');
print_r($time);
}
You are trying to create a Carbon instance using the createFromFormat() method. The first parameter you provide tells Carbon (actually DateTime) what the format of your input string will be. The data you are supplying is H:i:s (assuming $value["time"] is read from the time column of your Excel sheet), but you're telling Carbon that you will be giving it Y-m-d h:i:s. Since the format you promise doesn't match the data you are giving the object, null is resulting.
Either (broken into to steps for clarity):
$time = Carbon::createFromFormat('H:i:s', $value["time"]);
$timestr = $time->format('h:i:s');
or
$time = Carbon::createFromFormat('d-m-Y H:i:s', $value["date"] . " " . $value["time"]);
$timestr = $time->format('h:i:s');
will work.
The second one gives you a Carbon object that is much more useful - the first one will probably default to year zero. In both cases the timezone will be the zone of the machine the code is running on. You can override that if necessary.
Note that if I'm confused and the Excel reader is actually returning Cabon objects rather than strings, you can eliminate the whole createFromFormat code altogether. No sense making a Carbon object out of a Carbon object.
I have made a mistake by storing the date as VARCHAR in the database and here it looks like 02/12/2018 and I have created a variable using carbon to get the current date +14 days.
$current_date_plus_14 = Carbon::now() -> addDay(14) -> format('d/m/Y');
Problem is
I am trying to compare this date 02/12/2018 which is in the database and stores as VARCHAR to the date that I have generated using Carbon which is 09/04/2017.
Eloquent Code
$gquery = Client::where('required_date', '>=', $current_date_plus_14) -> get();
What I get
It doesn't get any results because it compare only the day in the required_date and the day in the carbon date.
While it should return value because the there is more than 1 year difference?
Try this function that converts date as String (May work with varchar) to a real date
private function convertDateString($date)
{
if (is_string($date)) {
$date = Carbon::parse($date,new DateTimeZone('YOUR_DATE_TIME_ZONE'));
}
return $date;
}
Even if your field is a VARCHAR instead of DATETIME or DATE, you can still mark it as a date in your Eloquent model by adding the attribute name to $dates. You'll also have to change your model's $dateFormat since you have a non-Y-m-d H:i:s format.
I am using DateTime function of php. I get a date from a calendar in format d-m-Y and pass it via ajax to my function. I am getting the date right till this step.
When I try to store the date in unix format using:
$ai_ff_date=DateTime::CreateFromFormat('d-m-Y', $data['date']);
$final_date=$ai_ff_date->format('U');
The date stored is wrong. Suppose the date I passed via ajax is 26-12-2016 then in database 27-12-2016 is stored. Why its counting one more day then the input.
use this code :
$date = date('Y-m-d H:i:s', strtotime('-1 day', $stop_date));
$ai_ff_date=DateTime::CreateFromFormat('d-m-Y',$date);
$final_date=$ai_ff_date->format('U');
and please check the variable (code not tested)
You might want to convert the Date-Format to "Y-m-d" First and then call-in the DateTime() Constructor. However, since what you are trying to do is just get the TimeStamp you might also do that directly without using DateTime. The Snippet below shows what is meant here:
<?php
$data = ['date'=>"13-12-2016"]; //<== JUST AN EXAMPLE FOR TESTING!!!
// SIMPLY CONVERT THE DATE TO Y-m-d FIRST.
$dateYMD = date("Y-m-d", strtotime($data['date']));
// THEN USE DateTime CONSTRUCTOR TO CREATE A NEW DateTime INSTANCE
// AND THEN RUN THE FORMAT YOU WISH::
$final_date = (new DateTime($dateYMD))->format('U');
var_dump($final_date); //<== YIELDS: string '1481583600' (length=10)
var_dump(date("Y-m-d", $final_date)); //<== YIELDS: string '2016-12-13' (length=10)
In my model I have the following:
protected $dates = [
'start',
'end',
'created_at',
'updated_at'
];
I am using a datetime picker to insert the start and end dates, in this format:
2016-01-23 22:00
Without the seconds. When I do it like this, I get this error:
InvalidArgumentException in Carbon.php line 425:
Data missing
at Carbon::createFromFormat('Y-m-d H:i:s', '2016-01-23 22:00') in Model.php line 3015
If I do include the seconds, it works. The seconds are not important to me, and I do not want to include them in my datetime picker fields. Any way around this so I can still use those fields as date fields?
tl;dr
Your date string and your date format is different, you have to change the format string or modify the date string so they match.
Explanation
The Problem
This error arises when Carbon's createFromFormat function receieves a date string that doesn't match the passed format string. More precisely this comes from the DateTime::createFromFormat function, because Carbon just calls that:
public static function createFromFormat($format, $time, $tz = null)
{
if ($tz !== null) {
$dt = parent::createFromFormat($format, $time, static::safeCreateDateTimeZone($tz));
} else {
$dt = parent::createFromFormat($format, $time); // Where the error happens.
}
if ($dt instanceof DateTime) {
return static::instance($dt);
}
$errors = static::getLastErrors();
throw new InvalidArgumentException(implode(PHP_EOL, $errors['errors'])); // Where the exception was thrown.
}
Not enough data
If your date string is "shorter" than the format string like in this case:
Carbon::createFromFormat('Y-m-d H:i:s', '2017-01-04 00:52');
Carbon will throw:
InvalidArgumentException in Carbon.php line 425:
Data missing
Too much data
If your date string is "longer" than the format string like in this case:
Carbon::createFromFormat('Y-m-d H:i', '2017-01-02 00:27:00');
Carbon will throw:
InvalidArgumentException in Carbon.php line 425:
Trailing data
Under the hood
According to the documentation on mutators the default date format is: 'Y-m-d H:i:s'. The date processing happens in the Model's asDateTime function. In the last condition the getDateFormat function is called, thats where the custom format comes from. The default format is defined in the Database's Grammar class.
Solution
You have to make sure that the date string matches the format string.
Change the format string
You can override the default format string like this:
class Event extends Model {
protected $dateFormat = 'Y-m-d H:i';
}
There is two problem with this approach:
This will apply to every field defined in the model's $dates array.
You have to store the data in this format in the database.
Edit and format the date strings
My recommended solution is that the date format should stay the default 'Y-m-d H:i:s' and you should complete the missing parts of the date, like this:
public function store(Request $request) {
$requestData = $request->all();
$requestData['start_time'] .= ':00';
$requestData['end_time'] .= ':00';
$event = new Event($requestData);
$event->save();
}
And when you want to use the date you should format it:
public function show(Request request, $eventId) {
$event = Event::findOrFail($eventId);
$startTime = $event->start_time->format('Y-m-d H:i');
$endTime = $event->end_time->format('Y-m-d H:i');
}
Of course the fields should be mutated to dates:
class Event extends Model {
protected $dates = [
'start_time',
'end_time',
'created_at',
'updated_at',
'deleted_at',
];
}
Models
This function disabled, the emulations for carbon in Datetimes
https://laravel.com/docs/5.0/eloquent#date-mutators
public function getDates()
{
return [];
}
You can set the $dateFormat in your model as Christian says, but if you don't want to imply the updated_at and created_at fields into the operation you can use events to "correct" the datetime object before saving it into the database.
Here you have the official doc about it: https://laravel.com/docs/5.2/eloquent#events
You need to set protected $dateFormat to 'Y-m-d H:i' in your model, see https://laravel.com/docs/5.2/eloquent-mutators#date-mutators
Make sure you are not omitting the "created_at" or "updated_at" fields in some rows in your database, which are required; if that is the case delete the records where they have those empty fields or enter a value in the valid timestamp format, example '2018-09-01 15:18:53'.
This is one possibility
You need to check the column of resultant data. If your column name 'created_at' or 'updated_at' is null, then it will through this error.
How to Solve ?
First of all, you need to store the data in those two columns using Laravel carbon.
Eg:
$user = new User();
$user->created_at = Carbon::now()->setTime(0,0)->format('Y-m-d H:i:s');
$user->updated_at = Carbon::now()->setTime(0,0)->format('Y-m-d H:i:s');
$user->save();
That's All, I hope it will work
Happy Coding....
For me the problem was with SQLServerGrammar located into the vendor (vendor\laravel\framework\src\Illuminate\Database\Query\Grammars\SqlServerGrammar.php).
Default in SQLServerGramma is Y-m-d H:i:s.v.
We extended the class end removed .v.
I want to convert the string 1433669892 to 07-06-2015 (June, 7th, 2015).
For that, I'm using the code:
$date = date('d-m-Y',strtotime ($row['order_created']));
Where:
$row['order_created']= '1433669892'
Which is returning:
31-12-1969
Totally different of what I expected. I know this should be trivial, but I can't manage to get the right date.
Try this:
$date = date('d-m-Y', intval( $row['order_created'] ) );
The timestamp passed to the function date() should be an integer as you seem to have in your row.
Edit Casting to an integer