Laravel : display personal format of timestamps fields - datetime

In my project I used this code to format timestamps fields
date('D m Y H:i', strtotime($post->created_at))
But as I have many places and fields to display it's a bit boring, and if I need to change the format it won"t be easy to maintain.
I'd like to know if there is a way to decalre the output format

You can create an accessor function in your Post model.
public function getCreatedAtAttribute($value)
{
return date('D m Y H:i', strtotime($value));
}
This way, each time you'll call $post->created_at it will display the date returned by your accessor instead of the default value.
More info here : http://laravel.com/docs/eloquent#accessors-and-mutators
If you don't want this function in all your models your can create a BaseModel class and make your models extend this BaseModel class.
I also found an other solution:
\Carbon\Carbon::setToStringFormat('D m Y H:i');
You can use this line (in global.php for exemple) but it will change the date format in all the application.

Related

Provide a Converter for data-binding by defining a pair of SerializableFunction objects

In Vaadin 8 Framework, and Vaadin 10 Flow, the data-binding capability lets us provide a Converter to mediate between the widget’s expected data type (such as String for a TextField) and the data type of the backing bean property (such as Integer number).
In this example, the built-in Converter implementation StringToIntegerConverter is used.
binder
.forField( this.phaseField )
.withConverter(
new StringToIntegerConverter( "Must enter an integer number" )
)
.bind( Panel::getPhase , Panel::setPhase ) ;
But what about defining a Converter for other types? How can I easily define a short-and-sweet Converter? For example, a String-to-UUID converter. I want to show the canonical 36-character hex string in a TextField, and going the other direction, parse that string back into a UUID.
// String to UUID
UUID uuid = UUID.fromString( myString ) ;
// UUID to String
String myString = uuid.toString() ;
I see that Binder.BindingBuilder offers the pair of methods withConverter that both take a pair of SerializableFunction objects.
Binder.BindingBuilder::withConverter(SerializableFunction<TARGET,NEWTARGET> toModel, SerializableFunction<NEWTARGET,TARGET> toPresentation)
Binder.BindingBuilder::withConverter(SerializableFunction<TARGET,NEWTARGET> toModel, SerializableFunction<NEWTARGET,TARGET> toPresentation, String errorMessage)
➥ So how do I define the pair of SerializableFunction objects/classes?
I noticed that this interface lists a known subinterface ValueProvider<SOURCE,TARGET>. That looks familiar, and I have a hunch it is the key to easily defining a short simple converter. But I do not quite comprehend the syntax with lambdas and all that is going on here.
I am not asking how to write a class implementing Converter. I am asking how to write the pair of SerializableFunction arguments to pass to the Binder.BindingBuilder::withConverter methods listed above as bullet items.
Quoting that JavaDoc:
Interface Binder.BindingBuilder<BEAN,TARGET>
…
withConverter
default <NEWTARGET> Binder.BindingBuilder<BEAN,NEWTARGET> withConverter(SerializableFunction<TARGET,NEWTARGET> toModel, SerializableFunction<NEWTARGET,TARGET> toPresentation)
Maps the binding to another data type using the mapping functions and a possible exception as the error message.
The mapping functions are used to convert between a presentation type, which must match the current target data type of the binding, and a model type, which can be any data type and becomes the new target type of the binding. When invoking bind(ValueProvider, Setter), the target type of the binding must match the getter/setter types.
For instance, a TextField can be bound to an integer-typed property using appropriate functions such as: withConverter(Integer::valueOf, String::valueOf);
Type Parameters:
NEWTARGET - the type to convert to
Parameters:
toModel - the function which can convert from the old target type to the new target type
toPresentation - the function which can convert from the new target type to the old target type
Returns:
a new binding with the appropriate type
Throws:
IllegalStateException - if bind has already been called
You can do it by passing two lambda expressions to withConverter, so something like this:
binder.forField(textField)
.withConverter(text -> UUID.fromString(text), uuid -> uuid.toString())
.bind(/* ... */);
If you need a more complicated conversion, then the right-hand side of the lambda can be surrounded with brackets, e.g.
binder.forField(textField).withConverter( text -> {
if ( text == null ) {
return something;
} else {
return somethingElse;
}
}, uuid -> { return uuid.toString(); } )
.bind(/* ... */);
If you need your converter multiple times, I recommend creating a separate class implementing interface com.vaadin.data.Converter. However, using lambdas is possible, too, as you already know (see answer of #ollitietavainen). But this is not Vaadin specific, it's a Java 8+ feature you can read about e.g. here. Basically, you can use lambdas whereever an object implementing an interface with only one method is required.

Get time difference in eloquent. Laravel

There's a table 'comment' with column time-stamp. I want the time difference from the date comment has been created to current date and time like created '5 Days ago' somewhat. I have no idea how to do that from eloquent.
My controller is:
public function show($id)
{
$vehicles=vehicles::findorfail($id);
$user=users::where('id',$vehicles->Users_id)->get()->first();
//adding view count
$viewad=ads::where('Vehicleid',$id)->get()->first();
$viewcount=$viewad->views;
$ad = ads::find($viewad->id);
$ad->views=$viewcount+1;
$ad->save();
$comments=comment::where('vehicles_id',$id)->get();
return view('Bike.show',compact('vehicles','user','viewcount','comments'));
}
How can i accomplish this task? Can anyone tell me how to do it?
If you want it available in the view the easiest way is to make an attribute accessor in the model.
First import Carbon at the start of the file use Carbon\Carbon;.
Then create the attribute accessor in your Comment model:
public function getTimeDifferenceAttribute()
{
return $this->time_stamp->diffForHumans(Carbon::now);
}
(I've used snake_case for the timestamp attribute name because the kebab-case version you used isn't valid in PHP variable names.)
Then it's available from a comment as $comment->time_difference.
EDIT:
This answer assumed that the model was treating time_stamp as a date. If this is not the case you should also add protected $dates = ['time_stamp']; to the model.
Use Carbon. See Carbon for the details.
$comments=comment::where('vehicles_id',$id)->get();
$today=Carbon::now();
and the view:
#foreach($comments as $comment)
{{$comment->name}} Created {{$today->diffForHumans($comment->time_stamp)}}
#endforeach
You have to import the namespace to use Carbon:
use Carbon\Carbon;

foreach statement cannot operate on variables of type 'Diary_Entry'

Passing in a list of dates 'DiaryEntry' through the foreach loop. every date that it records will be highlighted on the calendar....
foreach (DateTime d in DiaryEntry)
{
Calendar1.SelectedDates.Add(d);//CALENDAR1 being the ID of the calendar on the aspx page
}
ERROR: foreach statement cannot operate on variables of type 'Diary_Entry' because 'Diary_Entry' does not contain a public defination for 'GetEnumerator'
Anyone have any idea how I can resolve this?
Thanks
Is Diary_Entry meant to be a list of some kind? Is it based on a collection class, something that implements System.Collections.IEnumerable or System.Collections.Generic.IEnumerable? If not, if it just has a couple of properties that represent dates, you can't use foreach with it. You'd have to process each property separately.
Calendar1.SelectedDates.Add(Diary_Entry.Date1);
Calendar1.SelectedDates.Add(Diary_Entry.Date2);
// etc.
If it has two dates, representing a start and end date, and you want to iterate through the range, you wouldn't be able to use foreach with it, but you could still use for:
for(DateTime d = Diary_Entry.StartDate;d<=Diary_Entry.EndDate;d=d.AddDays(1))
{
Calendar1.SelectedDates.Add(d);
}
Your DiaryEntry object needs to implement IEnumerable or IEnumerable<T>.
From msdn:
The foreach statement repeats a group of embedded statements for each
element in an array or an object collection that implements the
System.Collections.IEnumerable or
System.Collections.Generic.IEnumerable<T> interface.
I suspect you mean to have an array or some other collection of those objects. In that case you could iterate over the collection with a foreach. Another possibility is that DiaryEntry has a collection property on it, and you mean to iterate over that... like the following maybe?
foreach(DateTime date in DiaryEntry.Dates)
{
...
}

Does Grails have a built-in way to bind a string to a date for a single bean property?

I know that it's possible to register a custom property editor, as demonstrated here. It is my understanding that this will cause all properties for the registered type to be bound using that custom editor.
(Perhaps that's a misunderstanding on my part? If so, enlighten me!)
However, what if I only want to register a custom editor for a single property on a given domain?
Example:
class MyCommand {
Date foo // bind this using a custom format, e.g. 'yyyy-MM-dd'
Date bar // bind this using the normal 'struct' date picker fields
}
class MyController {
def myAction = { MyCommand command ->
// params has [foo: '2011-01-01', bar: 'struct', ...]
// which get bound to command as above
}
}
Does Grails have a built-in way to do this?
I know that it's possible to register a custom property editor, as demonstrated here. It is my understanding that this will cause all properties for the registered type to be bound using that custom editor.
AFAIK, this is correct
However, what if I only want to register a custom editor for a single property on a given domain?
If you're using Grails 2.3.0 or later, you can do this like so:
class MyCommand {
#BindingFormat('yyyy-MM-dd')
Date foo // bind this using a custom format, e.g. 'yyyy-MM-dd'
Date bar // bind this using the normal 'struct' date picker fields
}
You could write getter and setters that take the format you want and return the format you want. The DateFormatter or SimpleDateFormatter classes would be useful in your get/set methods.
You can still use the neat trick for dates in grails:
<g:form>
<g:hiddenField name="myDomainInstance.bar_year" value="2011"/>
<g:hiddenField name="myDomainInstance.bar_month" value="07"/>
<g:hiddenField name="myDomainInstance.bar_day" value="01"/>
<g:textField name="myDomainInstance.bar_hour" value=""/>
<g:textField name="myDomainInstance.bar_minute" value=""/>
</g:form>
In controller:
myDomainInstance.properties = params.myDomainInstance
Will result in the desired date for bar.

How to render a DateTime in a specific format in ASP.NET MVC 3?

If I have in my model class a property of type DateTime how can I render it in a specific format - for example in the format which ToLongDateString() returns?
I have tried this...
#Html.DisplayFor(modelItem => item.MyDateTime.ToLongDateString())
...which throws an exception because the expression must point to a property or field. And this...
#{var val = item.MyDateTime.ToLongDateString();
Html.DisplayFor(modelItem => val);
}
...which doesn't throw an exception, but the rendered output is empty (although val contains the expected value, as I could see in the debugger).
Thanks for tips in advance!
Edit
ToLongDateString is only an example. What I actually want to use instead of ToLongDateString is a custom extension method of DateTime and DateTime?:
public static string FormatDateTimeHideMidNight(this DateTime dateTime)
{
if (dateTime.TimeOfDay == TimeSpan.Zero)
return dateTime.ToString("d");
else
return dateTime.ToString("g");
}
public static string FormatDateTimeHideMidNight(this DateTime? dateTime)
{
if (dateTime.HasValue)
return dateTime.Value.FormatDateTimeHideMidNight();
else
return "";
}
So, I think I cannot use the DisplayFormat attribute and DataFormatString parameter on the ViewModel properties.
You could decorate your view model property with the [DisplayFormat] attribute:
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}",
ApplyFormatInEditMode = true)]
public DateTime MyDateTime { get; set; }
and in your view:
#Html.EditorFor(x => x.MyDate)
or, for displaying the value,
#Html.DisplayFor(x => x.MyDate)
Another possibility, which I don't recommend, is to use a weakly typed helper:
#Html.TextBox("MyDate", Model.MyDate.ToLongDateString())
If all you want to do is display the date with a specific format, just call:
#String.Format(myFormat, Model.MyDateTime)
Using #Html.DisplayFor(...) is just extra work unless you are specifying a template, or need to use something that is built on templates, like iterating an IEnumerable<T>. Creating a template is simple enough, and can provide a lot of flexibility too. Create a folder in your views folder for the current controller (or shared views folder) called DisplayTemplates. Inside that folder, add a partial view with the model type you want to build the template for. In this case I added /Views/Shared/DisplayTemplates and added a partial view called ShortDateTime.cshtml.
#model System.DateTime
#Model.ToShortDateString()
And now you can call that template with the following line:
#Html.DisplayFor(m => m.MyDateTime, "ShortDateTime")
Simple formatted output inside of the model
#String.Format("{0:d}", model.CreatedOn)
or in the foreach loop
#String.Format("{0:d}", item.CreatedOn)
I use the following approach to inline format and display a date property from the model.
#Html.ValueFor(model => model.MyDateTime, "{0:dd/MM/yyyy}")
Otherwise when populating a TextBox or Editor you could do like #Darin suggested, decorated the attribute with a [DisplayFormat] attribute.
If all your DateTime types are rendered the same way you can use a custom DateTime display template.
In your Views folder create a folder named "DisplayTemplates" either under your controller specific views folder, or under "Shared" folder (these work similar to partials).
Inside create a file named DateTime.cshtml that takes DateTime as the #model and code how you want to render your date:
#model System.DateTime
#Model.ToLongDateString()
Now you can just use this in your views and it should work:
#Html.DisplayFor(mod => mod.MyDateTime)
As long as you follow the convention of adding it to the "DisplayTemplates" folder and naming the file to match the type your are displaying, MVC will automatically use that to display your values. This also works for editing scenarios using "EditorTemplates".
Here's some more information on templates.
My preference is to keep the formatting details with the view and not the viewmodel. So in MVC4/Razor:
#Html.TextBoxFor(model => model.DateTime, "{0:d}");
datetime format reference:
http://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.71).aspx
Then I have a JQuery datepicker bound to it, and that put's the date in as a different format...doh!
Looks like I need to set the datepicker's format to the same formatting.
So I'm storing the System.Globalization formatting in a data-* attribute and collecting it when setting up the
#Html.TextBoxFor(
model => model.DateTime.Date,
"{0:d}",
new
{
#class = "datePicker",
#data_date_format=System.Globalization.CultureInfo
.CurrentUICulture.DateTimeFormat.ShortDatePattern
}));
And here's the sucky part: the formats of .net and datepicker do not match, so hackery is needed:
$('.datePicker').each(function(){
$(this).datepicker({
dateFormat:$(this).data("dateFormat").toLowerCase().replace("yyyy","yy")
});
});
that's kind of weak, but should cover a lot of cases.
works for me
<%=Model.MyDateTime.ToString("dd-MMM-yyyy")%>
Had the same problem recently.
I discovered that simply defining DataType as Date in the model works as well (using Code First approach)
[DataType(DataType.Date)]
public DateTime Added { get; set; }
In MVC5 I'd use, if your model is the datetime
string dt = Model.ToString("dd/MM/yyy");
Or if your model contains the property of the datetime
string dt = Model.dateinModel.ToString("dd/MM/yyy");
Here's the official meaning of the Formats:
https://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx
you can do like this #item.Date.Value.Tostring("dd-MMM-yy");
if I just want to display the date in short format I just use
#Model.date.ToShortDateString() and it prints the date in
If all you want to do is display the date with a specific format, just call:
#Model.LeadDate.ToString("dd-MMM-yyyy")
#Model.LeadDate.ToString("MM/dd/yy")
It will result in following format,
26-Apr-2013
04/26/13
this will display in dd/MM/yyyy format in your View
In View:
instead of DisplayFor use this code
<td>
#(item.Startdate.HasValue ? item.Startdate.Value.ToString("dd/MM/yyyy") : "Date is Empty")
</td
it also checks if the value is null in date column, if true then it will display Date is Empty or the actual formatted date from the column.
Hope helps someone.
#{
string datein = Convert.ToDateTime(item.InDate).ToString("dd/MM/yyyy");
#datein
}
Only View File Adjust like this. You may try this.
#Html.FormatValue( (object)Convert.ChangeType(item.transdate, typeof(object)),
"{0: yyyy-MM-dd}")
item.transdate it is your DateTime type data.

Resources