Home » Android » string – Best way to format a date relative to now on Android

string – Best way to format a date relative to now on Android

Posted by: admin April 23, 2020 Leave a comment

Questions:

I am creating a feature in an Android app to get an arbitrary date (past, present or future) and find the difference relative to now.

Both my now and due variables are longs, and this is my code:

long now = System.currentTimeMillis();
long due = now + 864000;

Log.d("Time in 1 day", DateUtils.getRelativeTimeSpanString(due,now, DateUtils.DAY_IN_MILLIS));

I want the output to be something like yesterday, today, in 4 days or 19/12/2012. However, the current output returns in 0 days

I don’t want the time to appear on these date strings.

What am I doing wrong and is the best method for formatting dates on Android?

How to&Answers:

What I have in mind is changing:

DateUtils.getRelativeTimeSpanString(due, now, 0L, DateUtils.FORMAT_ABBREV_ALL);

Since the documentation says it returns the time relative to now.

If that fails use some of the brilliant libraries:

Joda Time

PrettyTime

TimeAgo

Answer:

Finally I have implemented what you wanted..!

First you need to download Joda Time from here

Extract it to any folder and put joda-time-2.2.jar into androidProject/libs folder.

MainActivity

import org.joda.time.DateTime;
import org.joda.time.Days;
import org.joda.time.Months;
import org.joda.time.MutableDateTime;
import org.joda.time.Weeks;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;


public class MainActivity extends Activity
{
  private int day ;
  private int month ;
  private int year ;
  private int hour ;
  private int minute ;
  private long selectedTimeInMillis;
  private long currentTimeInMillis;
  private String strDay ="";

 @Override
 protected void onCreate(Bundle savedInstanceState) 
 {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    year = 2013;
    month = 8;
    day = 10;
    hour = 15;
    minute = 28;

    DateTime selectedTime = new DateTime(year,month,day,hour,minute);
    selectedTimeInMillis = selectedTime.getMillis();

    MutableDateTime epoch = new MutableDateTime();
    epoch.setDate(selectedTimeInMillis); //Set to Epoch time

    DateTime now = new DateTime();

    currentTimeInMillis = now.getMillis();

    int days = Days.daysBetween(epoch, now).getDays();
    int weeks = Weeks.weeksBetween(epoch, now).getWeeks();
    int months = Months.monthsBetween(epoch, now).getMonths();

    Log.v("days since epoch: ",""+days);
    Log.v("weeks since epoch: ",""+weeks);
    Log.v("months since epoch: ",""+months);


    if(selectedTimeInMillis < currentTimeInMillis) //Past 
    {       
        long yesterdayTimeInMillis = currentTimeInMillis - 86400000;

        DateTime today = new DateTime(currentTimeInMillis);
        int year = today.getDayOfYear();
        int intToday = today.getDayOfMonth();
        DateTime yesterday = new DateTime(yesterdayTimeInMillis);
        int intYesterday = yesterday.getDayOfMonth();
        DateTime selectedDay = new DateTime(selectedTimeInMillis);
        int intselectedDay = selectedDay.getDayOfMonth();
        int intselectedYear = selectedDay.getDayOfYear();

        if(intToday == intselectedDay & year == intselectedYear)
        {
            strDay = "today";
        }
        else if(intYesterday == intselectedDay)
        {
            strDay = "yesterday";
        }
        else
        {
            strDay = "before "+ days +" days from today";
        }


    }
    else if(selectedTimeInMillis > currentTimeInMillis) //Future
    {
        long tomorrowTimeInMillis = currentTimeInMillis + 86400000;

        DateTime tomorrow = new DateTime(tomorrowTimeInMillis);
        int intTomorrow = tomorrow.getDayOfMonth();
        DateTime today = new DateTime(selectedTimeInMillis);
        int intToday = today.getDayOfMonth();

        if(intToday == intTomorrow)
        {
            strDay = "tomorrow";
        }
        else
        {
            days = -days;
            strDay = "after "+ days +" days from today";
        }


    }

    Log.v("strDay: ",""+strDay);
  }
}

You just need to change the value of day and you will get the desire output.
Currently I have given date 10 as input so output will be today.

I have set date/day = 10 , month = 8 , year = 2013 , hour = 15 , min = 28

For past dates:

input day 9 output yesterday

input day 3 output before 7 days from today

input year 2012 and day 10 output before 365 days from today

For future dates:

input day 11 output tomorrow

input day 27 output after 17 days from today

input day 23 and year 2016 output after 1109 days from today

Answer:

Why not just check for yesterday and tomorrow to avoid the in 0 days/0 days ago bug and leave DateUtils.getRelativeTimeSpanString handle the remaining cases?

String relative = null;

if(now < due && (due-now)<864000){
    relative = "tomorrow";
}else if(now > due && (now-due)<864000){
    relative = "yesterday";
}else{
    relative = DateUtils.getRelativeTimeSpanString(due, now, DateUtils.DAY_IN_MILLIS); // e.g. "in 4 days"
}

Log.d("result", relative);

Edit: You may also add today with a simple check as well.

Answer:

Best way to format a date relative to now on Android

I suggest you to use JodaTime

It’s lightweight handy library and i think actually the best tool for working with Date instances.

And you can start here.

Answer:

The actual reason is the number 864000 is in miliseconds, which corresponds to 14 minutes. 14 minutes is so small compared to DAY_IN_MILLIS (a day). There for you get “in 0 days”.
If you want it to produce “in 14 mins”, just change DAY_IN_MILLIS to MIN_IN_MILLIS.

Answer:

build.gradle

compile 'joda-time:joda-time:2.9.9'

Utils.java

private static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MMM dd, yyyy");
    private static SimpleDateFormat TIME_FORMAT = new SimpleDateFormat(" 'at' h:mm aa");
    public static String getRelativeDateTimeString(Calendar startDateCalendar) {
        if (startDateCalendar == null) return null;

        DateTime startDate = new DateTime(startDateCalendar.getTimeInMillis());
        DateTime today = new DateTime();
        int days = Days.daysBetween(today.withTimeAtStartOfDay(), startDate.withTimeAtStartOfDay()).getDays();

        String date;
        switch (days) {
            case -1: date = "Yesterday"; break;
            case 0: date = "Today"; break;
            case 1: date = "Tomorrow"; break;
            default: date = DATE_FORMAT.format(startDateCalendar.getTime()); break;
        }
        String time = TIME_FORMAT.format(startDateCalendar.getTime());
        return date + time;
    }

Output

Yesterday at 9:52 AM
Today at 9:52 AM
Tomorrow at 9:52 AM
Sep 05, 2017 at 9:52 AM

Answer:

I came here for an alternative but I can’t find perfect rather than my code.
So I shared here any improvements are welcome.

public String getCreatedAtRelative() {
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
    df.setTimeZone(TimeZone.getTimeZone("IST"));
    CharSequence relative = null;
    try {
        relative = DateUtils.getRelativeTimeSpanString(df.parse(createdAt).getTime(), new Date().getTime(),
                0L, DateUtils.FORMAT_ABBREV_ALL);
    } catch (ParseException e) {
        Log.e("Parse Exception adapter", "created at", e);
    } catch (NullPointerException e) {
        e.printStackTrace();
    }
    if (null == relative) {
        return createdAt;
    } else {
        return relative.toString().replace(".", " ");
    }
}

Answer:

So your computation is based on milliseconds unit, then you format the result with SimpleDateFormat.

For this, you can easily use SimpleDateFormat formatter like this :

Date date = new Date(milliseconds);
SimpleDateFormat formatter = new SimpleDateFormat("EEEE dd MMMM yyyy");
String strDate = formatter.format(date);

So your computation should be based on milliseconds unit, then you format the result with SimpleDateFormat.

The pattern (“EEEE dd MMMM yyyy”) allows you to get a date format like Monday, 04 February 2013.

You can change the pattern as you like : “EEEE dd/MM/yy”, …

Answer:

for Android you can use most simple way with Joda-Time-Android library:

Date yourTime = new Date();
DateTime dateTime = new DateTime(yourTime); //or simple DateTime.now()
final String result = DateUtils.getRelativeTimeSpanString(getContext(), dateTime);

Answer:

long now = System.currentTimeMillis();

DateUtils.getRelativeDateTimeString(mContext, now), DateUtils.SECOND_IN_MILLIS, DateUtils.DAY_IN_MILLIS, 0)

a link!