Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to format a date relative to now on Android

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?

like image 483
Todd Davies Avatar asked Feb 04 '13 13:02

Todd Davies


People also ask

How can I get current date format in Android?

You can use the SimpleDateFormat class for formatting date in your desired format. Just check this link where you get an idea for your example. For example: String dateStr = "04/05/2010"; SimpleDateFormat curFormater = new SimpleDateFormat("dd/MM/yyyy"); Date dateObj = curFormater.

How do I change the date format on my Android calendar?

Calendar calendar = Calendar. getInstance(); SimpleDateFormat format = new SimpleDateFormat("EEEE, MMMM d, yyyy 'at' h:mm a"); System. out. println(format.


3 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

like image 151
Nikola Despotoski Avatar answered Sep 28 '22 07:09

Nikola Despotoski


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
like image 40
TheFlash Avatar answered Sep 28 '22 06:09

TheFlash


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.

like image 20
Dzhuneyt Avatar answered Sep 28 '22 07:09

Dzhuneyt