1
votes

I am new with xamarin, I am facing an issue in my xamarin forms project. I have a Label inside listview-viewcell, to show time in UI. The date is received as a number like 1510822596449(Java Timestamp). I want to show the date in strings like "n days ago".How can I achieve this?

    <StackLayout>
        <ListView>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                    <StackLayout>
                        <Label Text="{Binding createdTime}"/>
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
          </ListView>           
    </StackLayout>

Anybody please suggest a solution with working code. Thanks in advance.

2
You can do this with a value converter as well. Converting from ticks (I assume they are ticks) to date time and then formatting it is a simple google "ticks to formatted date time"Steve Chadbourne

2 Answers

0
votes

First, create a class DatetimeToStringConverter and add the following code:

   public class DatetimeToStringConverter : IValueConverter
      {
    #region IValueConverter implementation

     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null)
            return string.Empty;

       return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)
            .AddMilliseconds((long)value) // put your value here
             .ToLocalTime().ToString("g");
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException(); 
    }

    #endregion
}

Then in xaml add the following code at the root of the page:

    <ContentPage.Resources>
        <ResourceDictionary>
            <local:DatetimeToStringConverter x:Key="cnvDateTimeConverter"></local:DatetimeToStringConverter>
        </ResourceDictionary>
    </ContentPage.Resources>

Then add namespace:

      xmlns:local="clr-namespace:Myapp;assembly=Myapp"

Then change the label text like this:

Text="{Binding createdTime,  Converter={StaticResource cnvDateTimeConverter}}"

Keep the createTime type as long in model, otherwise you get invalid cast exception.

0
votes

As suggested in the comments you could do this with a ValueConverter.

Write a converter similar to this, in your shared code.

    public class TicksToDateTimeConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (!Int64.TryParse(value, out long ticks))
                return DatTime.Now;

            // TODO you can do a ToString and format it you want here but also in XAML
            return new DateTime(ticks);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            // Not needed
            throw new NotImplementedException();
        }
    }

Now in your XAML, declare te value convter like this under the root of your page, I'm assuming it's a ContentPage.

<ContentPage.Resources>
    <ResourceDictionary>
        <local:TicksToDateTimeConverter x:Key="TicksConverter" />
    </ResourceDictionary>
</ContentPage.Resources>

And don't forget to declare the local namespace in your page root like: xmlns:local="clr-namespace:YourApp.Namespace", which should be the full namespace, without the class name to your converter class.

To finally use the converter in your layout, do this:

<StackLayout>
    <ListView>
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                <StackLayout>
                    <Label Text="{Binding createdTime, Converter={StaticResource TicksConverter}}"/>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
      </ListView>           
</StackLayout>

Depending on whether or not you return a string from the converter or a DateTime, in the latter case you can also format it here in XAML, like so:

<Label Text="{Binding createdTime, Converter={StaticResource TicksConverter}, StringFormat='{0:dd-MM-yyyy}'}"/>

Or you could choose to do it differently altogether and convert the value inside the model that you bind to the ViewCell.