Laravel Carbon formatting error - php

I'm experiencing a weird problem.
I'm using Carbon for dates. I want to use the format Y-W (year,week) which is working correctly.
Here i store it into the DB:
$weekDate = Carbon::createFromFormat('d-m-y', "{$key}")->format('Y-W');
DB::table('backorder_voorspelling')->insert([
'artikelcode' => $articlecode,
'week' => $weekDate,
'aantal' => $value,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now()
]);
The database record is correct:
{#426 ▼
+"id": 1
+"artikelcode": "articlecode"
+"week": "2017-44"
+"aantal": "6"
+"created_at": "2018-01-18 11:46:45"
+"updated_at": "2018-01-18 11:46:45"
}
Later on i want to convert the Y-W back to a carbon time and this is telling me:
The code i use to create the carbon time:
$startOfWeek = Carbon::createFromFormat('Y-W', $row->week);
The formats are the same, when storing i use the format ('Y-W') and when creatingFromFormat i use the format ('Y-W'), yet it's not working...
I tried replacing the - for / but this returns the same error.
Any help is appreciated.

Not all date format characters can be used in DateTime::createFromFormat (which is what Carbon extends). Unfortunately for you, W is one of the ones that's missing.
From the manual:
The format that the passed in string should be in. See the formatting options below. In most cases, the same letters as for the date() can be used.
You can work round this by manually calling setISODate on a new DateTime (or Carbon) instance:
list ($year, $week) = explode('-', '2017-44');
$d = new DateTime;
$d->setISODate($year, $week);
setISODate also accepts a third $day parameter - by default it will set to the first day of the week, which I think is what you want.
See https://eval.in/937360

Related

Create a datetime by faker laravel with format dd-mm-yyyy minute hour second, for example : 26/01/2022 20:52:23

'from' => $this->faker->dateTime($max = 'now', $timezone = null),
'to' => $this->faker->dateTime($max = 'now', $timezone = null),
In my factory file, I use method dateTime for "from" and "to", but it create with format : yyyy-mm-dd. How can I create value for "from" with format dd-mm-yyyy minute hour second ?
How about the following:
'from' => \Carbon\Carbon::parse($this->faker->dateTime($max = 'now', $timezone = null))->format('d-m-Y H:i:s'),
You can replace - in the format() with / if needed. Also take a look at the Carbon docs to see what other methods are available.
I understand that Carbon is included natively in Laravel, however, if you wanted a native PHP solution, since the Faker dateTime function returns a DateTime object, you can use the format() function of the DateTime class, the documentation for which can be found here
The code for that might look like this:
'from' => $this->faker->dateTime()->format('d-m-Y H:i:s'),

Laravel format time column in blade

In Laravel I know I can use Carbon to format dates into more readable strings. Is there a way to do this for a time column like {{ $event->time->format('h i') }}? All I see in all my searches are related to datetime columns. A lot of the apps I do are for schedules so there is a "Start" time and "End" time. For these I use $table->time('starts'); in my migrations, not a timestamp. The trouble is when I use the field in Blade, I need to format it in 12 hr AM/PM format and I can never find a good way.
try
in the model make sure you have the field in the cast array
protected $casts = [
'created_at' => 'datetime:h i',
];
$event->time->format('h i')->toTimeString()
try below also
public function getformattedAttribute()
{
return \Carbon\Carbon::createFromFormat('h i', $this->attributes['time']);
}
and run it with $event->formatted
Depending on your implementation, you might have some unreliable time generated on conversion, basically because of timezone so I will post with the assumption that you're using something like below:
$table->timeTz('start'); or $table->time('start');
The Difference there is the timezone which can produce incorrect value on conversion as mentioned above.
So, for you to generate format such as 12hr AM/PM which in reality should look like 12:00 PM or 12:00pm or 12:30 PM .....
We can do something like below:
public function dateTest(){
$sampleTimeFromDb = "12:00:00"; //This is the basic sample time you're expected to get from your db ...
$sampleTimeFromDbFormated = Carbon::createFromTimeString($sampleTimeFromDb)->format('g:i a'); // am/pm, you can change a to A to get AM/PM
//Other samples which basically will generate same sample but with time stamp specified
$sampleCurrentTimeLag = Carbon::createFromTimeString("12:00:00","Africa/Lagos");
$sampleCurrentTimeReg = Carbon::createFromTimeString("01:00:00","America/Regina");
$def_format_ = Carbon::createFromTimeString($sampleCurrentTimeLag)->format('g:i A'); //Without timezone AM/PM
$lagosFormat = Carbon::createFromTimeString($sampleCurrentTimeLag, "Africa/Lagos")->format('g:i a');; //with timezone am/pm
$def_format_0 = Carbon::createFromTimeString($sampleCurrentTimeReg)->format('g:i A'); //Without timezone AM/PM
$americaFormat = Carbon::createFromTimeString($sampleCurrentTimeReg, "America/Regina")->format('g:i a');; //with timezone am/pm
$data = [
'_' => $sampleTimeFromDbFormated,
'a' => $def_format_,
'b' => $lagosFormat,
'c' => $def_format_0,
'd' => $americaFormat,
'e' => $americaFormat
];
return View("playground", $data);
}
My view playground.blade.php
<!DOCTYPE html>
<html>
<body>
<p>{{$_}}</p>
<p>{{$a}}</p>
<p>{{$b}}</p>
<p>{{$c}}</p>
<p>{{$d}}</p>
<p>{{$e}}</p>
</body>
</html>
Output:
Hopefully it does help.

Matching DateTimes in PHP

I'm struggling with the PHP DateTime & DateTimeZone combo: What i want to achieve is, if current datetime matches a value in this format - "H:i" a block of PHP code to be executed. So far, i've managed to arrive at this "solution", however i'm struggling to make it work:
$datetime = new DateTime();
$timezone = new DateTimeZone('Europe/Sofia');
$datetime->setTimezone($timezone);
if($datetime == '06:00') {
DB::table('shifts')->insert(['shift_number' => '1', 'created_at' => $datetime, 'updated_at' => $datetime]);
}
I'm fairly new to PHP and i would greatly appreciate any help on the matter, thanks!
You can format the dateTime object and then compare the formatted value.
Example:
if($datetime->format('H:i') === '06:00') {
echo 'match';
}

Getting only time from Carbon object

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.

How to extract the time from "created_at" with Carbon

I am struggling with the Carbon functionalities within Laravel framework still. I created these functions used in my model to extract the date of the "created_at" field in my tables:
public function getCreatedAtAttribute($date) {
return Carbon::createFromFormat('Y-m-d H:i:s', $date)->format('d.m.Y');
}
This works fine for the date, but how would I need to write a function in this model, that will extract only the time within the created_at field?
I feel like you're limiting yourself a lot be overriding the default behaviour for dates.
If you remove your accessor (getCreatedAtAttribute) you'll be able to call format from the property itself i.e.
$model->created_at->format('d.m.Y')
or
$model->created_at->format('H:i:s');//e.g. 15:30:00
Carbon is just a wrapper for DateTime. For a list of format characters you can look here: http://php.net/manual/en/function.date.php
e.g. todays date as 6th February 2016 would be jS F Y
try to use
public function getCreatedAtAttribute($date) {
return Carbon::createFromFormat('Y-m-d H:i:s', $date)->format('H:i:s');
}
output will be time
If you want to insert date into database manually you can do this.
"created_at" => now(),
"updated_at" => now()
debugging
dd(now());
// output
// 2022-03-16 10:24:07
$model->created_at
This will use some Eloquent magic and return the creation date as a Carbon object.
You can create an helper for it. This will allows you to call the getTimeFromCreatedAt() function anywhere in your laravel code.
//extracts time from created_at column
function getTimeFromCreatedAt($date) {
return Carbon::createFromFormat('Y-m-d H:i:s', $date)->format('H:i:s');
}

Categories