Cannot get exact Hour using Laravel's Carbon - php

I'm inserting date and time data in the database, my datatype is timestamp, I am inserting data using carbon but I always get this output from it '2014-11-25 00:53:48' I always get 00 on the hours, been stuck here for three hours... here is my code
$mydate=Carbon::now();
DB::table('attendances')
->where('user_id', Input::get('empid'))
->update(array('logon' =>$mydate));

try using $mydate->format("H:i")
Carbon defaults to outputting in DateTime format.
Also this looks like a simple use case: You could use DB::raw('NOW()') in place of $mydate if you are using MySQL
DB::table('attendances')
->where('user_id', Input::get('empid'))
->update(array('logon' =>DB::raw('NOW()')));
EDIT:
Also worth noting that Carbon extends php's DateTime. That means all DateTime functionality is still there. It also means your problem could be stemming from a problem with your PHP installation/configuration.

Related

Laravel saving data with Carbon::now() is formatted differently to created_at

I'm working with a Laravel project and time zones (I know time zones are a pain), and what's occurred to be is that one of my custom columns in my table, the column called last_checked which is stored as a timestamp appears to be formatted differently from the created_at, and it means that my time zone parsing isn't parsing the date at all for the user's time zone.
Here's what I mean...
When storing a record, I set the date and time:
$uptimeMonitor = Monitors::where('id', $monitor['id'])
->get()
->first();
$uptimeMonitor->last_checked = Carbon::now();
$uptimeMonitor->save();
But when I retrieve the result, looking in my network request, I'm seeing this format:
2021-04-05 11:46:54
But when I look at both the created_at and updated_at columns, they're in this format:
2021-04-05T10:01:16.000000Z
So the question here is, what am I doing wrong with saving my data? Both formats seem to be visually shown the same in the database, but for some strange reason, the first example isn't parsing correctly.
Carbon uses the default DateTime PHP object, so use the date_default_timezone_set() function, for example: date_default_timezone_set('UTC');
or you define it AppServiceProvider App/Providers/AppServiceProvider.php
public function boot()
{
date_default_timezone_set('UTC');
}
Or you can use setTimezone of carbon method
echo Carbon::now()->setTimezone('UTC')->format('H:i');
Try this
$uptimeMonitor = Monitors::where('id', $monitor['id'])
->get()
->first();
$uptimeMonitor->last_checked = Carbon::now()->setTimezone('UTC')->format('Y-m-d H:i:s');
$uptimeMonitor->save();
Note my default app timezone is UTC just find your default timezone
and set it in `setTimezone('UTC');
You need to add all the datetime properties in your $casts model protected member:
https://laravel.com/docs/8.x/eloquent-mutators#date-casting
All is OK in your DB, it's just Laravel model has to know it's a date to format with the full ISO-8601 string in your JSON.
Side note, you still should have "UTC" as your default in config/app.php, it does not prevent from having any timezone handling for particular cases, or to handle users timezone, on the contrary.
If your dates output string as GMT+1 by default, it's very likely a configuration mistake.

Laravel automatically adding time to date

I seem to have a problem with my Laravel application, and I can't for the life of me figure out whats going on.
I have a simple date field in my MySQL database, its data type is just date, and for this example the value is 2020-08-13, but for some reason, when I try to access the date, it adds a timestamp on the end, minuses 1 day and throws a Carbon trailing data error.
It is definitely this date, because when I soft delete it, the error disappears.
As an example, the error for this date is
Carbon\\Carbon::rawCreateFromFormat('Y-m-d', '2020-08-12T23:0...', NULL)
So as you can see, it's removing a day and trying to format at 11pm the night before?
I have had similar issues to this before where Laravel was adding 0000-00-00 to the date, so I had to remove it in my accessor, but now that its throwing 11pm, my string replace doesn't work anymore. I can obviously just change the string replacer to look for 11pm, but I don't want to have to fix this every time the format changes.
My accessor code is as follows
public function getDateAttribute($value){
//String replace and remove the time from the value if it exists
$value = str_replace(' 00:00:00', '', $value);
return Carbon::CreateFromFormat('Y-m-d', $value)->format('d/m/Y');
}
Has anyone had an error like this before, or have any idea whats going on?
Before Laravel 7, dates would be serialized to a format like the following :
2019-12-02 20:01:00
But, Laravel 7 uses a new date serialization format when using the toArray or toJson method on Eloquent models, with ISO-8601 date format. This ISO-8601 dates are always expressed in UTC, like this :
2019-12-02T20:01:00.283041Z
If you would like to keep using the previous behavior you can override the serializeDate() method on your model, add this into your model :
use DateTimeInterface;
protected function serializeDate(DateTimeInterface $date)
{
return $date->format('Y-m-d H:i:s');
}
first define you column to $dates property on your model :
$dates=['date']
then specify your date format by accessor :
public function getDateAttribute($value){
return $val->format('d/m/Y');
}
public function getDateAttribute($value){
// return 2020-08-17
$date = date('Y-m-d',strtotime($value));
return $date;
}
Make sure of the config file. You will find there a function of local time that can change its value from UTC to the local time of your country
config / app.php
'timezone' => 'Asia/Riyadh',
it's removing a day and trying to format at 11pm the night before
That's clearly a timezone shift (you're likely in GMT+1) and this is a shift to GMT+0 (UTC).
You should not trim the time to force "00:00:00" because this will only work in 1 timezone (there is no worldwide-midnight-moment, there is a different midnight moment in each timezone for each day), while your app now or later may handle multiple timezones. You should rather save the timezone ("Europe/London" for instance) in an other DB column and so you'll keep the complete information and when retrieving your date, you can calculate on the fly the midnight from (before) this date-time according to the user timezone.

Date from API call not being accepted in Laravel as a dateTime field

I am getting dates from an API call. The date is formatted in this way
2017-10-19T15:30:00
I want to store this date in my MYSQL database using Laravel Database Migration, currently I am using
$table->dateTime('datetime');
When I store it using a dateTime field as above, all I get is
0000-00-00 00:00:00
When I use a timestamp format, I don't get accurate dates, I just get the current time and date.
How can I solve this? Any help would be appreciated, and please let me know if you want further information.
Luckily, Laravel uses the Carbon class, which makes things a lot easier to modify dates. In your case, you want to do this:
Carbon::createFromFormat('Y-m-d\TH:i:s', $date);
There are two ways you can implement it: you can modify it before you save it to your database, or you can add a mutator on your model.
public function setDatetimeAttribute($value)
{
$this->attributes['datetime'] = Carbon::createFromFormat('Y-m-d\TH:i:s', $value);
}
You may want to build in some validation to see which format the date/time is in before you try to convert it.
in the model you should put:
protected $dates = ['datetime'];
Use Carbon
$dt = Carbon::parse('1975-05-21 22:23:00.123456');
to save:
$model = new Model;
$model->date = $dt; // you can use the carbon object directly
$model->save();

PHP using Laravel 4 and Carbon will not print out a DateTime field from my Database

I am building a PHP application with Laravel 4.
I am getting errors when I try to print out a DateTime record from the Database though.
{{ $user->created_at }}
Gives me this error
InvalidArgumentException
Trailing data
open: E:\Server\htdocs\projects\timeclock\www\vendor\nesbot\carbon\src\Carbon\Carbon.php
Very frustrating!
An example value from that Database field is: 2013-08-31 20:50:25.
You are missing the milisecond data on the time stamp, you need to use:
Carbon::createFromFormat('Y-m-d H:i:s.u', $value)->format('d/m/Y H:i:s');
You have to format it:
{{ $user->created_at->format('h:i:s') }}
The PHP docs has a list of all the codes available to use as a format.
I have the same issue.
And I found that this is caused by my timestamp data in database.
2013-12-13 22:40:50.561709 <- this one will cause the issue.
2013-12-13 22:40:50 <- this one will not.
Timestamp value with millisecond causes this issue.
Column which is converted to Carbon object can not have millisecond timestamp.(default: created_at, updated_at).
http://readouble.com/laravel/4/2/0/en/eloquent.html#date-mutators
If Carbon Object is not necessary, you can disallow auto-converting.
class SomeModel extends Eloquent {
public function getDates()
{
return array();
}
}
But it also make Carbon methods(ex:->format()) unavailable. You have to format timestamps in other way.

How to create DateTime object from string in symfony2/php

In a DB table I have several fields with datetime as field type. So I need to persist data only as date time object.
From a form I get date time as string like
2012-10-05 17:45:54
Now when ever I persist my entity I get following error:
Fatal error: Call to a member function format() on a non-object in
..\DateTimeType.php on line 44
I tried with
$protocol->setStartedAt(strtotime($post['started_at']));
or
$from = \DateTime::createFromFormat('yy-mm-dd hh:mm:ss', $post['started_at']);
$protocol->setStartedAt($from);
or just
$from = new \DateTime($post['started_at']);
$protocol->setStartedAt($from);
The last code works but it does not uses the timestamp passed as arguement but just gets the current time.
Any ideas?
I always create a DateTime object with its constructor, in your case it would be:
$protocol->setStartedAt(new \DateTime($post['started_at']));
if this works but does not use the timestamp posted you probably do not have the value in $post['started_at']. Try debugging it or just do the dirty trick:
die($post['started_at']);
For the sake of future readers who surely will someday encounter this problem (this is the first post if you google "symfony 2 datetime from string"), keep in mind that in Symfony 2 the DateTime object does NOT accept a string with that format : "d/m/Y H:i:s", and probably doesn't support many others either.
For the sake of not becoming mad at that, I've actually found out that the easiest and safest solution to avoid such errors is this one:
First, get your date string from whatever kind of request you are doing (In my case a generic AJAX request) and convert it to a DateTime Object, this example assumes that we need to create a dateTime object for 25/04/2015 15:00, which is the format of the jQuery UI italian DateTimePicker (that's just an example):
$literalTime = \DateTime::createFromFormat("d/m/Y H:i","25/04/2015 15:00");
(note: use \ to use php's DateTime object, else you will be using Symfony's datetime object that will throw you an exception)
Then, once you did it, create a date string using the comfort format function, by giving to the first parameter the output format expected (Y-m-d H:i:s):
$expire_date = $literalTime->format("Y-m-d H:i:s");
In this way you are 100% sure that whatever kind of format you are passing or receiving this will properly be converted and you won't get any kind of exception from the DateTime symfony object, as long as you provide what you are expecting as an input.
Knowing that this post is actually quite old, I've just decided to post that because I didn't find any other valuable source but this one to understand where the problem could have been.
Please note that the best solution is still to send the datetime string in the correct format already, but if you literally have no ways to do that the safest way to convert such a string is the one above.
How about createFromFormat?
http://uk.php.net/manual/en/datetime.createfromformat.php
$from = DateTime::createFromFormat($post['started_at'], 'Y-m-d H:i:s');

Categories