用今天、昨天、明天等字符串格式化日期的正确方法

Posted

技术标签:

【中文标题】用今天、昨天、明天等字符串格式化日期的正确方法【英文标题】:Right way to format date with strings like today, yesterday, tomorrow etc 【发布时间】:2011-11-19 16:42:14 【问题描述】:

我有一个日期文本视图。我的 textview 包含一个日期字符串,例如 2011.09.17。好吧,我仍然想拥有它,但我也想为今天或昨天等特定日期添加更多用户友好的信息。例如,如果今天是 2011.09.17,我希望我的 textview 具有昨天而不是 2011.09.16 和今天的值 2011.09.17。

好吧,我已经设法做到了 :),但是以丑陋的方式 :(。我用很多 'if->than' 来做到这一点,这真的很丑陋,而且我想添加一些新规则,比如 if日期超过一年我想把字符串放在去年左右......我真的需要添加丑陋的逻辑。

我的问题是有没有更好的方法来做到这一点?有没有类似设计模式的东西?推荐的方法是什么?相信很多人都遇到过这样的问题

如果有比一千个 if 更有效的方法吗?如果不感谢任何方式,至少我会停止寻找沐浴者解决方案

任何建议,sn-p 左右将不胜感激

谢谢

【问题讨论】:

在这里查看我的答案***.com/a/46086798/578309 不应该将此线程的最后一个答案标记为正确的吗? 看看这个***.com/a/60861554/5506292 【参考方案1】:

您可以在 DateUtils 中尝试getRelativeDateTimeString http://developer.android.com/reference/android/text/format/DateUtils.html

【讨论】:

【参考方案2】:

我通常使用这个方便的 java 库来格式化相对时间。 Prety Time Library

【讨论】:

网址打开空白页面 我知道这是一个非常古老的答案,但是,对库进行更多介绍并包括其他可能性不会有什么坏处。很多人不想默认使用库。虽然这取决于@Lukap 选择这个作为最佳答案......【参考方案3】:
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());                
                    

【讨论】:

【参考方案4】:

试试这个,我使用 joda-datatime2.2.jar 和 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;



使用和测试Util类的简单案例:

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();
    

【讨论】:

只是注意到 DateMidnight 已被弃用。用 LocalDate 替换 DateMidnight 应该适用于较新版本的 Joda-Time。【参考方案5】:

getRelativeTimeSpanString 在 API 级别 3 中添加

getRelativeTimeSpanString(长时间, 很久了, long minResolution)

返回一个字符串,将“时间”描述为相对于“现在”的时间。

过去的时间跨度格式类似于“42 分钟前”。未来时间跨度的格式类似于“42 分钟内”。 您可以在此处找到更多信息:

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

    Calendar now = Calendar.getInstance();
    return DateUtils.getRelativeTimeSpanString(time, now.getTimeInMillis(), DateUtils.DAY_IN_MILLIS);

【讨论】:

虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。【参考方案6】:

对于 android 在 build.gradle 文件中使用 JodaTime 库:

编译'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;
    

【讨论】:

此方案不支持本地化

以上是关于用今天、昨天、明天等字符串格式化日期的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

Moment.js - 明天、今天和昨天

获取时间以及格式化--今天昨天和明天

Django“naturalday”模板过滤器:回退到格式化日期?

js 获取昨天,今天和明天的年月日格式

python代码获取今天昨天明天的日期

如何使用 DateFormatter 显示昨天、今天和明天