Is there an easy way to change timezone only on view laravel? - php

So I already save any date on my database with UTC, and I can get it just like $data->created_at or $data->blocked_at. So in my config, I set timezone to UTC, then i want to convert when on view from UTC to UTC+7 or another timezone.
Is there an easy way to convert timezone i want when on view for all dates?
I'm still using Laravel 5.8
Edit:
I'm using the answer but implement that on my base model, like this:
public function getDateConverter($key){
if(strtotime($this->{$key})){
$date = Carbon::createFromFormat('Y-m-d H:i:s', $this->{$key});
$date->setTimezone(env("APP_TIMEZONE_VIEW"));
return $date->toDateTimeString();
} else {
return null;
}
}
And I will call the column name like this $data->getDateConverter("created_at");

You can use Carbon which is included in the core
$timestamp = '2014-02-06 16:34:00';
$date = Carbon::createFromFormat('Y-m-d H:i:s', $timestamp, 'Europe/Stockholm');
$date->setTimezone('UTC');
Europe/Stockholm is your default timezone and UTC is what you want to set
If you want to convert it from a model when displaying, try Accessors
public function getCreatedAtAttribute($value)
{
$date = Carbon::createFromFormat('Y-m-d H:i:s', $value, 'Europe/Stockholm');
$date->setTimezone('UTC');
return $date->toDateTimeString();
}

well in case if you want to chnage your timezone when inserting the time then
Use 'timezone' => 'Asia/Kolkata'. in your config/app.php
By this you can set your applications default timezone..

you can use add this function to your model
public function setViewDateFormat( $date ) {
return Carbon::parse( $date ,'Africa/Cairo')->format( 'j F Y' );
}
Then call it on any date attribute
public function getFormattedCreatedAtAttribute() {
return ( $this->created_at ) ? $this->setViewDateFormat( $this->created_at ) : null;
}
This way you can set all dates timezone and format.

Related

PHP Wrong time after setting timezone

I stumbled onto a really weird problem:
For my task I wrote a method that would give me the current date in a specific format,
another method would then extract the date so I could compare it with dates in the database.
public static function getCurrentDate()
{
return date("Y-m-d H:i:s a");
}
public static function extractDate($date)
{
return date("Y-m-d", strtotime($date));
}
Because I've noticed that the time wasn't right, I've set the default timezone at the beginning of the script like this:
date_default_timezone_set('Europe/Berlin');
Running this script, I've noticed that it gives the wrong output, maybe you could already help me here.
$currentDate = getCurrentDate();
echo $currentDate."\n";
$extractedDate = extractDate($currentDate );
echo $extractedDate."\n";
Output:
2020-08-25 21:58:13 pm
1970-01-01
Then I tried it in another way with DateTime, where it still produced the wrong output
public static function extractDate($date)
{
$timezone = new DateTimeZone('Europe/Berlin');
$dt = DateTime::createFromFormat("Y-m-d H:i:s a", $date, $timezone);
return $dt->format("Y-m-d");
}
Output:
2020-08-25 21:58:13 pm
2020-08-26
I would understand if there was an error so it would lead to the Unix epoch again, but this time it somehow added a day.
It would be nice if you knew where my error at the first approach was and I'm also really interested to hear why PHP behaves like that in the second approach
Change:
public static function getCurrentDate()
{
return date("Y-m-d H:i:s a");
}
to
public static function getCurrentDate()
{
return date("Y-m-d H:i:s");
}
and you are all set.
In 24h time you do not need the a or am/pm, which makes the datetime unrecognizable via strtotime, it cannot convert it , and it returns false, thus the invalid date 1970-01-01which is qeuivalent tounixtime = 0`

analysis this datetime result and export just date in laravel

this is a function to convert date
private function convertShamseToMiladi($request){
$startdate = \Morilog\Jalali\CalendarUtils::convertNumbers($request, true);
$sdate = \Morilog\Jalali\CalendarUtils::createDatetimeFromFormat('Y-m-d' , $startdate);
return $sdate;
}
when i use this function
$this->convertShamseToMiladi($request->startdate);
the result i see is same as this part:
DateTime #1577133000 {#273 ▼
date: 2019-12-24 00:00:00.0 asia/tehran (+03:30)
}
and i need just this part : 2019-12-24
and i want to know when i dd() the date request why show me this kind of result?
Your convertShamseToMiladi() method is returning php \DateTime, so you can use format to get desired result:
$this->convertShamseToMiladi($request->startdate)->format('Y-m-d');
Or if you want your method to always return formatted date you may change it like this:
private function convertShamseToMiladi($request){
$startdate = \Morilog\Jalali\CalendarUtils::convertNumbers($request, true);
$sdate = \Morilog\Jalali\CalendarUtils::createDatetimeFromFormat('Y-m-d' , $startdate);
return $sdate->format('Y-m-d');
}
I suggest You can use carbon https://carbon.nesbot.com/docs/ instead of morilog/jalali
You can change format of date in any other format using carbon
$date = '12-12-2017 23:23:34';
echo Carbon::parse($date)->format('Y/m/d');
You can change the format as you want. https://carbon.nesbot.com/docs/#api-formatting

how to enter time-stamps in mysql from an input

I need to insert Timestamp in MySQL from input in Laravel application
data coming from my input is in this format 12/27/2017 MM/DD/YYYY how can I convert it into this format Y-m-d H:i:s
any alternatives are highly appreciated like pass data from the input which input we use so, I can get data in timestamp format.
and at the end, I need to sort data order by date
If you want to do it in Laravel way you can use mutator and Carbon. This is an example of model:
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model
class Post extends Model {
protected $dates = ['date'];
public function setDateAttribute($value)
{
$this->attributes['date'] = Carbon::createFromFormat('d/m/Y', $value);
}
}
Now when you update or create post date attribute will be automatically converted. So you can save it like this:
$post = new Post();
$post->date = '16/12/2017';
$post->save();
You can use DateTime:
$inputDate = \DateTime::createFromFormat('m/d/Y', '12/27/2017');
$formatedDate = $inputDate->format('Y-m-d H:i:s');
As for me I done date conversion in this way, for example to making invoices. I hope this can be done by PHP.
$input_date = "12/15/2017"; // input in MM/DD/YYYY
$output_date = date('Y-m-d H:i:s',strtotime($input_date)); //set output to 2017-12-15 00:00:00
echo $output_date; //produce output
It generates the following result
2017-12-15 00:00:00
I hope this will work. If you want only date, you can omit H:i:s based on your purpose. Thank you.
$date=date_create("12/27/2017");
$rawDate = date_format($date,"Y/m/d");// Produced - 2017/12/27
echo str_replace('/','-',$rawDate ); // Output - 2017-12-27
to add H:i:s, if there is no time just add 00:00:00 at the end of date begins with space.
If you're dealing with created_at or updated_at which Laravel create for every table, you must add 00:00:00 to end of date to get all data begins with that respective date
This solution worked for me if we want the format of date from input is different from the format the timestamp accepts
Laravel way of doing is
protected $fillable = ['organization_name', 'job_apply_link', 'job_description', 'city_id', 'province_id', 'sector_id', 'image_file', 'test_id', 'newspaper_id', 'catagory_id', 'slug', 'meta_keywords', 'meta_description', 'job_title', 'created_at'];
public function setCreatedAtAttribute($value)
{
$inputDate = \DateTime::createFromFormat('m/d/Y', $value);
$formatedDate = $inputDate->format('Y-m-d H:i:s');
$this->attributes['created_at'] = $formatedDate;
}

Carbon timezone get timestamp

I want to get a real timestamp of given time in specified timezone for using in frontend.
Currently i can set a timezone, and get the time for it. But i can't get a new one timestamp.
Carbon::setToStringFormat('U'); // Set __toString format
$instance = Carbon::createFromTimestamp('1460014482', "Europe/Kiev"); // Set global server timezone (or pickup from default PHP setting)
$instance->setTimezone("Indian/Maldives"); // Set user timezone
var_dump($instance->format('d M Y H:i:s')); // Shows the correct time +2 hours from Europe/Kiev
var_dump((string)$instance); // Shows the same timestamp specified in createFromTimestamp
var_dump(date('d M Y H:i:s', (string)$instance)) // So it won't show the timezone datetime
Explain how i can get a timestamp of time for a given timezone.
Thanks!
You need to use the function createFromFormat to use setTimezone. Here is an example for your code:
$originalDate = date("Y-m-d H:i:s", '1460014482');
$instance = Carbon::createFromFormat('Y-m-d H:i:s', $originalDate, 'Europe/Kiev');
$instance->setTimezone("Indian/Maldives");
Hope it helps.
I know its not a complete solution. But it works for my requirements.
Currently need to override __toString method of Carbon class, which i use to display date timestamp.
public function __toString()
{
return static::$toStringFormat == 'U' ? (string)strtotime($this->format('Y-m-d H:i:s')) : $this->format(static::$toStringFormat);
}

Laravel Carbon Data Missing

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.

Categories