Отображение минут назад в приложении для Android

Я изо всех сил старался провести исследование и найти учебник, но все еще запутался в этом. Моя проблема в том, что я хочу отобразить что-то вроде «минут назад» на основе даты и времени создания, которые я извлек из данных json.

Когда я получил дату и время с сервера, я хочу отобразить его в текстовом представлении livestatTimeAgo, но он показывает ошибку, потому что метод getTimeAgo имеет длинный формат. Поэтому я использовал parseLong для изменения полученных данных, но все равно получил ошибку. Может ли кто-нибудь дать мне подсказку о том, как отображать длинные данные в строковое значение, подобное этому.

Это журнал ошибок:

FATAL EXCEPTION: main
Process: com.baracode.eilsan, PID: 898
                                                                 java.lang.NumberFormatException: For input string: "2017-08-25 09:20:54"
                                                                     at java.lang.Long.parseLong(Long.java:443)
                                                                     at java.lang.Long.parseLong(Long.java:485)
                                                                     at com.baracode.eilsan.livestat.adapter.LivestatAdapter.onBindViewHolder(LivestatAdapter.java:49)
                                                                     at com.baracode.eilsan.livestat.adapter.LivestatAdapter.onBindViewHolder(LivestatAdapter.java:29)
                                                                     at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6400)
                                                                     at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6433)
                                                                     at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5377)

это мой код

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.baracode.eilsan.R;
import com.baracode.eilsan.model.LiveFeed;

import java.text.DateFormat;
import java.text.Format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;

/**
 * Created by kille on 17/7/2017.
 */

public class LivestatAdapter extends RecyclerView.Adapter<LivestatAdapter.MyViewHolder> {
    private final ArrayList<LiveFeed> livestatList;
    private LiveFeed liveFeed;




    public LivestatAdapter(ArrayList<LiveFeed> livestatList) {
        this.livestatList = livestatList;
    }

    @Override
    public LivestatAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_livestat, parent, false);
        return new LivestatAdapter.MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        LiveFeed livestatModel = livestatList.get(position);
        holder.livestatTimeAgo.setText(getTimeAgo(Long.parseLong(livestatModel.createdAt)));
        holder.livestatOrganisationName.setText(livestatModel.beneficiaryName);
        holder.livestatMoneyDonated.setText(livestatModel.amount);
        holder.livestatDonorName.setText(livestatModel.donorName);
    }


    @Override
    public int getItemCount() {
        return livestatList.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        TextView livestatTimeAgo, livestatDonorName, livestatOrganisationName, livestatMoneyDonated;

        public MyViewHolder(View view) {
            super(view);
            livestatTimeAgo = view.findViewById(R.id.livestat_time_ago);
            livestatOrganisationName = view.findViewById(R.id.livestat_organisation_name);
            livestatMoneyDonated = view.findViewById(R.id.livestat_money_donated);
            livestatDonorName = view.findViewById(R.id.livestat_donor_name);

        }
    }

//    private String ConvertTime(String time) {
//
//        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        SimpleDateFormat format1 = new SimpleDateFormat("hh:mm aa MM-dd");
//        java.util.Date date = null;
//
//        try {
//            date = format.parse(time);
//        } catch (ParseException e) {
//            e.printStackTrace();
//        }
//
//        String convertedDate = format1.format(date);
//
//        return convertedDate;
//    }

    public static String getTimeAgo(long timestamp) {

        Calendar cal = Calendar.getInstance();
        TimeZone tz = cal.getTimeZone();//get your local time zone.
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh:mm ss");
        sdf.setTimeZone(tz);//set time zone.
        String localTime = sdf.format(new Date(timestamp * 1000));
        Date date = new Date();
        try {
            date = sdf.parse(localTime);//get local date
        } catch (ParseException e) {
            e.printStackTrace();
        }

        if(date == null) {
            return null;
        }

        long time = date.getTime();

        Date curDate = currentDate();
        long now = curDate.getTime();
        if (time > now || time <= 0) {
            return null;
        }

        int timeDIM = getTimeDistanceInMinutes(time);

        String timeAgo = null;

        if (timeDIM == 0) {
            timeAgo = "less than a minute";
        } else if (timeDIM == 1) {
            return "1 minute";
        } else if (timeDIM >= 2 && timeDIM <= 44) {
            timeAgo = timeDIM + " minutes";
        } else if (timeDIM >= 45 && timeDIM <= 89) {
            timeAgo = "about an hour";
        } else if (timeDIM >= 90 && timeDIM <= 1439) {
            timeAgo = "about " + (Math.round(timeDIM / 60)) + " hours";
        } else if (timeDIM >= 1440 && timeDIM <= 2519) {
            timeAgo = "1 day";
        } else if (timeDIM >= 2520 && timeDIM <= 43199) {
            timeAgo = (Math.round(timeDIM / 1440)) + " days";
        } else if (timeDIM >= 43200 && timeDIM <= 86399) {
            timeAgo = "about a month";
        } else if (timeDIM >= 86400 && timeDIM <= 525599) {
            timeAgo = (Math.round(timeDIM / 43200)) + " months";
        } else if (timeDIM >= 525600 && timeDIM <= 655199) {
            timeAgo = "about a year";
        } else if (timeDIM >= 655200 && timeDIM <= 914399) {
            timeAgo = "over a year";
        } else if (timeDIM >= 914400 && timeDIM <= 1051199) {
            timeAgo = "almost 2 years";
        } else {
            timeAgo = "about " + (Math.round(timeDIM / 525600)) + " years";
        }

        return timeAgo + " ago";
    }

    public static Date currentDate() {
        Calendar calendar = Calendar.getInstance();
        return calendar.getTime();
    }

    private static int getTimeDistanceInMinutes(long time) {
        long timeDistance = currentDate().getTime() - time;
        return Math.round((Math.abs(timeDistance) / 1000) / 60);
    }



}

вот мой класс в прямом эфире..

public class LiveFeed {

    @SerializedName("id")
    public String id = "";

    @SerializedName("ref_id")
    public String refId = "";

    @SerializedName("beneficiary_type")
    public String beneficiaryType = "";

    @SerializedName("beneficiary_name")
    public String beneficiaryName = "";

    @SerializedName("donor_name")
    public String donorName = "";

    @SerializedName("amount")
    public String amount = "";

    @SerializedName("description")
    public String description = "";

    @SerializedName("remark")
    public String remark = "";

    @SerializedName("status")
    public String status = "";

    @SerializedName("created_at")
    public String createdAt = "";


    @SerializedName("updated_at")
    public String updatedAt = "";

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getRefId() {
        return refId;
    }

    public void setRefId(String refId) {
        this.refId = refId;
    }

    public String getBeneficiaryType() {
        return beneficiaryType;
    }

    public void setBeneficiaryType(String beneficiaryType) {
        this.beneficiaryType = beneficiaryType;
    }

    public String getBeneficiaryName() {
        return beneficiaryName;
    }

    public void setBeneficiaryName(String beneficiaryName) {
        this.beneficiaryName = beneficiaryName;
    }

    public String getDonorName() {
        return donorName;
    }

    public void setDonorName(String donorName) {
        this.donorName = donorName;
    }

    public String getAmount() {
        return amount;
    }

    public void setAmount(String amount) {
        this.amount = amount;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(String createdAt) {
        this.createdAt = createdAt;
    }

    public String getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(String updatedAt) {
        this.updatedAt = updatedAt;
    }

}

Итак, это правильный ответ на мой вопрос... обновленный код о том, как получить время... для всех, кто хочет сослаться !!! Спасибо

DateFormat getDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String fromDate = getDate.format(Calendar.getInstance().getTime());
String endDate = livestatModel.updatedAt; //here my jsondataName

long diff = 0;
try {
    //Convert to Date
    Date startDate = getDate.parse(fromDate);
    Calendar c1 = Calendar.getInstance();
    //Change to Calendar Date
    c1.setTime(startDate);

    //Convert to Date
    Date endDate2 = getDate.parse(endDate);
    Calendar c2 = Calendar.getInstance();
    //Change to Calendar Date
    c2.setTime(endDate2);

    //get Time in milli seconds
    long ms1 = c1.getTimeInMillis();
    long ms2 = c2.getTimeInMillis();
    //get difference in milli seconds
    diff = ms1 - ms2;

    if (diff < 0) {
        holder.livestatTimeAgo.setText(" 0 day " + " 0 hour " + " 0 minute " + " 0 sec " + "left");
    } else {
        int diffInDays = (int) (diff / (1000 * 60 * 60 * 24));
        int diffInHours = (int) ((diff / (1000 * 60 * 60)) % 24);
        int diffInMinutes = (int) ((diff % (1000 * 60 * 60)) / (1000 * 60));
        int diffInSec = (int) ((diff / 1000) % 60);
        holder.livestatTimeAgo.setText(diffInDays + " days " + diffInHours + " hours " + diffInMinutes + " minutes " + diffInSec + " secs " + "Ago");
    }
}catch (Exception e){}

person Alhaadi Dev    schedule 27.08.2017    source источник
comment
java.lang.NumberFormatException: For input string: "2017-08-25 09:20:54" какое число должна представлять строка даты?   -  person Phantômaxx    schedule 27.08.2017
comment
я хочу, чтобы это представляло что-то вроде 1 минуты назад в текстовом представлении, сэр. Мои данные даты json в строковом формате, поэтому я использую метод getTimeAgo(), чтобы изменить его. но этот метод в длинном формате. так теперь, как отобразить его?. я хочу отобразить его в строковом формате.   -  person Alhaadi Dev    schedule 27.08.2017
comment
Я не был ясен. Ваша ошибка говорит вам, что вы пытаетесь преобразовать строку даты в число. Вы хотите получить разницу между двумя датами. Это то, что вы должны Google для.   -  person Phantômaxx    schedule 27.08.2017
comment
я хочу преобразовать мою дату в настоящее время в строковом типе данных в длинный тип данных перед отображением...   -  person Alhaadi Dev    schedule 27.08.2017
comment
Вы не можете преобразовать NOT A NUMBER в число. Это теперь ясно?   -  person Phantômaxx    schedule 27.08.2017
comment
подскажите как это исправить?..пожалуйста   -  person Alhaadi Dev    schedule 28.08.2017


Ответы (2)


Сначала преобразуйте строку в календарь:

 Calendar cal = Calendar.getInstance();
 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
 cal.setTime(sdf.parse("2017-08-25 09:20:54"));

Затем используйте

long time = cal.getTimeInMillis();

и это должно к трюку.

ИЗМЕНИТЬ

Это возможный пример того, что вы хотите сделать. Я не знаю, правильны ли расчеты, но работает.

 try{

 Calendar cal = Calendar.getInstance();
 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 cal.setTime(sdf.parse("2017-08-25 09:20:54"));

  Calendar calendar = Calendar.getInstance();
  long now = calendar.getTimeInMillis();
  long time = cal.getTimeInMillis();

  long diff = now - time;

  int seconds = (int) (diff / 1000) % 60 ;
  int minutes = (int) ((diff / (1000*60)) % 60);
  int hours   = (int) ((diff / (1000*60*60)) % 24);
  int days = (int) (diff / (1000*60*60*24));

  System.out.println(time + " " + now);
  System.out.println(hours + " hours ago");
  System.out.println(minutes + " minutes ago");
  System.out.println(seconds + " seconds ago");
  System.out.println(days + " days ago");


}catch(ParseException e){
     System.out.println(e.toString());
}
person joao86    schedule 27.08.2017
comment
я получил время из json... когда я поместил его в setTime(), это стало ошибкой.. - person Alhaadi Dev; 28.08.2017
comment
см. мою редакцию к ответу. Это просто пример, вы должны сделать расчеты самостоятельно. - person joao86; 29.08.2017

Вы получаете ошибку в следующей строке.

holder.livestatTimeAgo.setText(getTimeAgo(Long.parseLong(livestatModel.createdAt)));

И поскольку ошибка java.lang.NumberFormatException: For input string: "2017-08-25 09:20:54", это в значительной степени означает, что livestatModel.createdAt содержит 2017-08-25 09:20:54, которое является скорее строковым значением и не может быть проанализировано в Long, поскольку оно включает такие синтаксисы, как двоеточие, дефис и пробел.

Обновить

Чтобы преобразовать строку даты в длинную, вам нужно проанализировать livestatModel.createdAt с помощью SimpleDateFormat (как вы делали в методе getTimeAgo, но с другим форматом).

Вот как вы можете этого добиться.

long createdAtLong = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(livestatModel.createdAt).getTime();

holder.livestatTimeAgo.setText(getTimeAgo(createdAtLong));
person fluffyBatman    schedule 27.08.2017
comment
Итак, сэр.. как это исправить. Мне нужно получить данные без двоеточия или как?... вот мой API запроса... - person Alhaadi Dev; 27.08.2017
comment
Проверьте мой обновленный ответ. - person fluffyBatman; 27.08.2017
comment
спасибо, сэр... но где мне это реализовать... мне нужно создать другой метод или просто поместить длинное createdLong ниже метода BindViewHolder... - person Alhaadi Dev; 27.08.2017
comment
Выше этой линии должно выполняться задание. holder.livestatTimeAgo.setText(getTimeAgo(createdAtLong)); - person fluffyBatman; 27.08.2017
comment
когда я реализую это в onBindViewHolder, он сказал, что мне нужно окружить с помощью try catch. Затем, когда я запускаю приложение, оно ничего не показывает... но без ошибок - person Alhaadi Dev; 27.08.2017
comment
если я поставлю над ним ... то же самое, сэр, нужно окружить попыткой поймать ... - person Alhaadi Dev; 27.08.2017
comment
затем ошибка, подобная этой. - person Alhaadi Dev; 27.08.2017