28

I have a date textview. And my textview holds a date string like 2011.09.17. Well I still do want to have that but I also want to add some more user friendly info for some specific dates like today or yesterday. For example if today is 2011.09.17 I want my textview to have value of yesterday instead 2011.09.16 and today instead 2011.09.17.

well I already managed to do this :), but in the ugly way :(. I do this with a lot of 'if->than' which is really uglly and what ever I want to add some new rule like if the date is older than one year I want to put string like last year or so.... I really need to add ugly logic.

My question is is there a nicer way to do this ? is there something like design pattern for this ? What is the recommended way to do this ? I am sure that many people have encounter this kind of problems

if there some bather approach than thousand of ifs ? if not thanks any way at least I will stop searching for bather solution

any suggestions , snippet or so will be appreciated

Thanks

Lukap
  • 31,523
  • 64
  • 157
  • 244

6 Answers6

53

You could try getRelativeDateTimeString in DateUtils http://developer.android.com/reference/android/text/format/DateUtils.html

a.ch.
  • 8,285
  • 5
  • 40
  • 53
Christopher Souvey
  • 2,890
  • 21
  • 21
10
public class RelativeWeekday {                
    private final Calendar mCalendar;                

    public RelativeWeekday(Calendar calendar) {                
        mCalendar = calendar;                
    }                

    @Override                
    public String toString() {                
        Calendar today = Calendar.getInstance(Locale.getDefault());
        int dayOfYear = mCalendar.get(Calendar.DAY_OF_YEAR);
        if (Math.abs(dayOfYear - today.get(Calendar.DAY_OF_YEAR)) < 2) {
            return getRelativeDay(today);
        }              

        return getWeekDay();                
    }                

    private String getRelativeDay(Calendar today) {                
        return DateUtils.getRelativeTimeSpanString(                
                mCalendar.getTimeInMillis(),                
                today.getTimeInMillis(),                
                DateUtils.DAY_IN_MILLIS,                
                DateUtils.FORMAT_SHOW_WEEKDAY).toString();                
    }                

    private String getWeekDay() {                
        SimpleDateFormat dayFormat = new SimpleDateFormat("EEEE");                
        return dayFormat.format(mCalendar.getTimeInMillis());                
    }                
}
JP Ventura
  • 5,564
  • 6
  • 52
  • 69
9

I usually use this handy java library for Relative Time formatting. Prety Time Library

Eefret
  • 4,724
  • 4
  • 30
  • 46
Ye Myat Min
  • 1,429
  • 2
  • 17
  • 29
  • 3
    url open empty page – Furqan Jan 31 '17 at 12:28
  • I know this is a very old answer, but still, a little more introduction to the library and including other possibilities wouldn't hurt. A lot of people don't want to use libraries as a default. Although that's up to @Lukap for choosing this as the best answer... – NoHarmDan Apr 29 '20 at 16:57
0

Try this, i implemented it using joda-datatime2.2.jar and java SimpleDateFormat

import java.text.SimpleDateFormat;
import java.util.Date;
import org.joda.time.DateMidnight;
import org.joda.time.DateTime;
import org.joda.time.Days;
public class SmartDateTimeUtil {
private static String getHourMinuteString(Date date){
    SimpleDateFormat hourMinuteFormat = new SimpleDateFormat(" h:m a");
    return hourMinuteFormat.format(date);
}

private static String getDateString(Date date){
    SimpleDateFormat dateStringFormat = new SimpleDateFormat("EEE',' MMM d y',' h:m a");
    return dateStringFormat.format(date);
}

private static boolean isToday (DateTime dateTime) {
       DateMidnight today = new DateMidnight();
       return today.equals(dateTime.toDateMidnight());
}

private static boolean isYesterday (DateTime dateTime) {
       DateMidnight yesterday = (new DateMidnight()).minusDays(1);
       return yesterday.equals(dateTime.toDateMidnight());
}

private static boolean isTomorrow(DateTime dateTime){
    DateMidnight tomorrow = (new DateMidnight()).plusDays(1);
       return tomorrow.equals(dateTime.toDateMidnight());
}
private static String getDayString(Date date) {
        SimpleDateFormat weekdayFormat = new SimpleDateFormat("EEE',' h:m a");
        String s;
        if (isToday(new DateTime(date)))
            s = "Today";
        else if (isYesterday(new DateTime(date)))
            s = "Yesterday," + getHourMinuteString(date);
        else if(isTomorrow(new DateTime(date)))
            s = "Tomorrow," +getHourMinuteString(date);
        else
            s = weekdayFormat.format(date);
        return s;
}

public static String getDateString_shortAndSmart(Date date) {
        String s;
        DateTime nowDT = new DateTime();
        DateTime dateDT = new DateTime(date);
        int days = Days.daysBetween(dateDT, nowDT).getDays();   
        if (isToday(new DateTime(date)))
            s = "Today,"+getHourMinuteString(date);
        else if (days < 7)
            s = getDayString(date);
        else
            s = getDateString(date);
        return s;
}

}

Simple cases to use and test the Util class:

import java.util.Calendar;
import java.util.Date;

public class SmartDateTimeUtilTest {
    public static void main(String[] args) {
        System.out.println("Date now:"+SmartDateTimeUtil.getDateString_shortAndSmart(new Date()));
        System.out.println("Date 5 days before :"+SmartDateTimeUtil.getDateString_shortAndSmart(getFutureDay(-5)));
        System.out.println("Date 1 day before :"+SmartDateTimeUtil.getDateString_shortAndSmart(getFutureDay(-1)));
        System.out.println("Date last month:"+SmartDateTimeUtil.getDateString_shortAndSmart(getFutureMonth(-1)));
        System.out.println("Date last year:"+SmartDateTimeUtil.getDateString_shortAndSmart(getFutureDate(-1)));
        System.out.println("Date 1 day after :"+SmartDateTimeUtil.getDateString_shortAndSmart(getFutureDay(1)));
    }
    public static Date getFutureDate(int numberOfYears){
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.YEAR, numberOfYears); 
        return c.getTime();
    }
    public static Date getFutureMonth(int numberOfYears){
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.MONTH, numberOfYears); 
        return c.getTime();
    }

    public static Date getFutureDay(int numberOfYears){
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.DATE, numberOfYears); 
        return c.getTime();
    }
}
NarendraSoni
  • 2,210
  • 18
  • 26
  • Just noting that DateMidnight has been deprecated. Replacing DateMidnight with LocalDate should work with newer versions of Joda-Time. – dabarnard May 04 '16 at 11:26
0

getRelativeTimeSpanString added in API level 3

getRelativeTimeSpanString (long time, long now, long minResolution)

Returns a string describing 'time' as a time relative to 'now'.

Time spans in the past are formatted like "42 minutes ago". Time spans in the future are formatted like "In 42 minutes". More information you can find here:

https://developer.android.com/reference/android/text/format/DateUtils

    Calendar now = Calendar.getInstance();
    return DateUtils.getRelativeTimeSpanString(time, now.getTimeInMillis(), DateUtils.DAY_IN_MILLIS);
Alier
  • 11
  • 2
  • 4
    While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. – Nic3500 Oct 17 '18 at 12:02
-2

For android Use JodaTime library in build.gradle file:

compile 'net.danlew:android.joda:2.9.9'

public static String formateddate(String date) {
    DateTime dateTime = DateTimeFormat.forPattern("dd-MMM-yyyy").parseDateTime(date);
    DateTime today = new DateTime();
    DateTime yesterday = today.minusDays(1);
    DateTime twodaysago = today.minusDays(2);
    DateTime tomorrow= today.minusDays(-1);

    if (dateTime.toLocalDate().equals(today.toLocalDate())) {
        return "Today ";
    } else if (dateTime.toLocalDate().equals(yesterday.toLocalDate())) {
        return "Yesterday ";
    } else if (dateTime.toLocalDate().equals(twodaysago.toLocalDate())) {
        return "2 days ago ";
    } else if (dateTime.toLocalDate().equals(tomorrow.toLocalDate())) {
        return "Tomorrow ";
    } else {
        return date;
    }
}
Ashish
  • 873
  • 10
  • 20