13

我有以下方法,如果没有别的,我想缩短或更快。欢迎大家发表意见:

Bellow 方法获取一个日期对象,将其格式化(“EEE hh:mma MMM d, yyyy”),然后确定日期是今天还是昨天,如果是,则返回“(昨天 | 今天)hh:mma " 格式化字符串。

    public static String formatToYesterdayOrToday(String date) {
    SimpleDateFormat sdf = new SimpleDateFormat("EEE hh:mma MMM d, yyyy");
    Date in = null;

    try {
        in = sdf.parse(date);
    } catch (ParseException e) {
        log.debug("Date parsing error:", e);
    }

    Calendar x = Calendar.getInstance();
    x.setTime(in);

    String hour = Integer.toString(x.get(Calendar.HOUR));
    String minute = Integer.toString(x.get(Calendar.MINUTE));
    String pm_am = x.get(Calendar.AM_PM) == Calendar.AM ? "AM" : "PM";

    x.set(Calendar.HOUR, 0);
    x.set(Calendar.HOUR_OF_DAY, 0);
    x.set(Calendar.MINUTE, 0);
    x.set(Calendar.SECOND, 0);
    x.set(Calendar.MILLISECOND, 0);

    Calendar today = Calendar.getInstance();
    today.set(Calendar.HOUR, 0);
    today.set(Calendar.HOUR_OF_DAY, 0);
    today.set(Calendar.MINUTE, 0);
    today.set(Calendar.SECOND, 0);
    today.set(Calendar.MILLISECOND, 0);

    Calendar yesterday = Calendar.getInstance();
    yesterday.set(Calendar.HOUR, 0);
    yesterday.set(Calendar.HOUR_OF_DAY, 0);
    yesterday.set(Calendar.MINUTE, 0);
    yesterday.set(Calendar.SECOND, 0);
    yesterday.set(Calendar.MILLISECOND, 0);
    yesterday.add(Calendar.DATE, -1);

    if (x.compareTo(today) == 0) {
        return "Today " + hour + ":" + minute + pm_am;
    }
    if (x.compareTo(yesterday) == 0) {
        return "Yesterday " + hour + ":" + minute + pm_am;
    }
    return date;
}
4

9 回答 9

46

以下是使用标准 API 改进它的方法:

public static String formatToYesterdayOrToday(String date) throws ParseException {
    Date dateTime = new SimpleDateFormat("EEE hh:mma MMM d, yyyy").parse(date);
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(dateTime);
    Calendar today = Calendar.getInstance();
    Calendar yesterday = Calendar.getInstance();
    yesterday.add(Calendar.DATE, -1);
    DateFormat timeFormatter = new SimpleDateFormat("hh:mma");

    if (calendar.get(Calendar.YEAR) == today.get(Calendar.YEAR) && calendar.get(Calendar.DAY_OF_YEAR) == today.get(Calendar.DAY_OF_YEAR)) {
        return "Today " + timeFormatter.format(dateTime);
    } else if (calendar.get(Calendar.YEAR) == yesterday.get(Calendar.YEAR) && calendar.get(Calendar.DAY_OF_YEAR) == yesterday.get(Calendar.DAY_OF_YEAR)) {
        return "Yesterday " + timeFormatter.format(dateTime);
    } else {
        return date;
    }
}

以下是使用Jodatime的方法:

public static String formatToYesterdayOrToday(String date) {
    DateTime dateTime = DateTimeFormat.forPattern("EEE hh:mma MMM d, yyyy").parseDateTime(date);
    DateTime today = new DateTime();
    DateTime yesterday = today.minusDays(1);
    DateTimeFormatter timeFormatter = DateTimeFormat.forPattern("hh:mma");

    if (dateTime.toLocalDate().equals(today.toLocalDate())) {
        return "Today " + timeFormatter.print(dateTime);
    } else if (dateTime.toLocalDate().equals(yesterday.toLocalDate())) {
        return "Yesterday " + timeFormatter.print(dateTime);
    } else {
        return date;
    }
}
于 2010-11-27T15:05:06.467 回答
3

您写了“欢迎所有评论”,所以这是我使用 joda-time 的方式。:)

我喜欢以 iPhone 最近通话的简短而智能的方式显示日期和时间(类似于 google wave 帖子)。如果今天是"hh:mm" ,如果 <7 天是 "yesterday" 或工作日名称,否则是yyyy-MM-dd

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 String getDayString(Date date) {
    String s;

    if (isToday(new DateTime(date)))
        s = "Today";
    else if (isYesterday(new DateTime(date)))
        s = "Yesterday";
    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 = getHourMinuteString(date);
    else if (days < 7)
        s = getDayString(date);
    else
        s = getDateString(date);

    return s;
}

我使用一组 SimpleDateFormat(如上面的 weekdayFormat)将时间格式化为所需的字符串,并且 DateTime 和 DateMidnight 是 joda-time 类。

在这些情况下,两个 DateTime:s 之间经过的天数与人们如何定义谈论它的时间无关。DateMidnight 在这里派上用场,而不是像我看到的一些人那样计算天数(或毫秒),尽管其他方法也可以。:)

于 2011-05-09T09:50:22.617 回答
3

我对这个问题的理解是提供一种简单的方法来产生如下输出:

Today at 20:00
Today at 20:30
Today at 21:00
Tomorrow at 06:45
Tomorrow at 07:00
Tomorrow at 08:15

下面的代码对我有用,但我是 android 新手,如果代码不健壮,也许其他人可以指出。在“timeLong”下面的代码中是我的事件在纪元时间(毫秒)中的时间。

public String convertFromEpochTime (long timeLong) {
    long timeNow = System.currentTimeMillis();

    // get day in relative time
    CharSequence timeDayRelative;
    timeDayRelative = DateUtils.getRelativeTimeSpanString(timeLong, timeNow, DateUtils.DAY_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE);

    // get hour in 24 hour time
    Format hourFormatter = new SimpleDateFormat("HH:mm");
    String timeHour = hourFormatter.format(timeLong);

    // Log.d(DEBUG_TAG, "time of event: " + timeDayRelative + " at " + timeHour);

    String timeDayHour = timeDayRelative + " at "+ timeHour;

    return timeDayHour;
}
于 2015-03-04T09:31:17.137 回答
3

时区

问题和其他答案忽略了时区的关键问题。该输入字符串缺少任何时区或offset-from-UTC。因此,该字符串将被解析,同时假设它代表 JVM 当前默认时区中的日期时间。有风险的业务,因为 (a) 该假设可能是错误的,以及 (b) 该默认值可能随时发生变化,即使运行时也是如此。

语言环境

问题和其他答案忽略了另一个关键问题:Locale. Locale 确定在解析(和生成)期间用于从输入字符串翻译日期名称和月份名称的人类语言。

如果未指定,JVM 的当前默认语言环境将用于翻译。与时区一样,您的 JVM 的默认语言环境可以随时更改,即使运行时也是如此。

最好指定您想要/预期的语言环境。

java.time

问题和其他答案使用已证明设计不良且麻烦的旧日期时间类。Java 8 及更高版本具有内置的java.time框架,其类取代了旧的。

您在生成新字符串时解析字符串的方法应该分为两种方法。一种方法应该解析以获得日期时间对象。第二个应该采用日期时间对象并生成所需的字符串输出。然后每个都可以单独使用。这种方法使我们不再将字符串视为日期时间值。字符串是日期时间值的文本表示。您的业​​务逻辑应该专注于将这些日期时间值作为对象进行操作,而不是专注于字符串。

解析

private ZonedDateTime parseLengthyString ( String input , ZoneId zoneId , Locale locale ) {
    // FIXME: Check for nulls.

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "EEE hh:mma MMM d, uuuu" );
    formatter = formatter.withZone ( zoneId );
    formatter = formatter.withLocale ( locale );
    ZonedDateTime zdt = null;
    try {
        zdt = ZonedDateTime.parse ( input , formatter );
    } catch ( DateTimeParseException e ) {
        // FIXME: handle exeption.
        System.out.println ( "ERROR - e: " + e );
    }
    return zdt; // FIXME: Check for null.
}

生成

鉴于ZonedDateTime上述方法,我们可以使用指定的语言环境生成其日期时间值的文本表示,以翻译日期名称和月份名称。

要确定日期时间是今天还是昨天,我们只关心日期部分而不关心一天中的时间。为此,我们可以使用LocalDatejava.time 中的类。

private String generateLengthyString ( ZonedDateTime zdt , Locale locale ) {
    // FIXME: Check for nulls.

    // Compare the date-only value of incoming date-time to date-only of today and yesterday.
    LocalDate localDateIncoming = zdt.toLocalDate ();

    Instant instant = Instant.now ();
    ZonedDateTime now = ZonedDateTime.now ( zdt.getZone () ); // Get current date-time in same zone as incoming ZonedDateTime.
    LocalDate localDateToday = now.toLocalDate ();
    LocalDate localDateYesterday = localDateToday.minusDays ( 1 );

    DateTimeFormatter formatter = null;
    if ( localDateIncoming.isEqual ( localDateToday ) ) {
        formatter = DateTimeFormatter.ofPattern ( "'Today' hh:mma" , locale ); // FIXME: Localize "Today".
    } else if ( localDateIncoming.isEqual ( localDateYesterday ) ) {
        formatter = DateTimeFormatter.ofPattern ( "'Yesterday' hh:mma" , locale ); // FIXME: Localize "Yesterday".
    } else {
        formatter = DateTimeFormatter.ofPattern ( "EEE hh:mma MMM d, uuuu" , locale );
    }

    String output = zdt.format ( formatter );
    return output; // FIXME: Check for null.
}

例子

练习这两种方法。

任意选择时区,America/New_York如问题未指定。

String input = "Sat 11:23AM Feb 6, 2016";
ZoneId zoneId = ZoneId.of ( "America/New_York" );
Locale locale = Locale.US;
ZonedDateTime zdt = this.parseLengthyString ( input , zoneId , locale );

String output = this.generateLengthyString ( zdt , locale );

顺便说一句,您可以要求 java.time 根据 Locale 的文化规范自动格式化输出字符串,而不是硬编码格式。

String outputPerLocale = zdt.format ( DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.MEDIUM ) );

转储到控制台。

System.out.println ( "input: " + input + " | zdt: " + zdt + " | Instant: " + zdt.toInstant () + " | output: " | output + " + outputPerLocale: " + outputPerLocale );

输入:2016 年 2 月 6 日星期六上午 11:23 | zdt: 2016-02-06T11:23-05:00[美国/纽约] | 即时:2016-02-06T16:23:00Z | 输出:今天上午 11:23 | outputPerLocale:2016 年 2 月 6 日上午 11:23:00

顺便说一句,我建议在AMor之前放置一个空格,PM以便于阅读。

于 2016-02-06T22:00:07.053 回答
2

这是今天,昨天,明天

String formatDate(String fecha){

    String Rfecha=new String();
     SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
     //SimpleDateFormat formatter2 = new SimpleDateFormat("EEEE d MMM");
     SimpleDateFormat formatter2 = new SimpleDateFormat("E, d MMM ");
        try {
           Date hoy=new Date();

            Date date = formatter.parse(fecha);


            String pref="";
           Log.d("hoy long", ""+(hoy.getTime()/ (1000*60*60*24)));
           Log.d("date long", ""+ (date.getTime()/ (1000*60*60*24)));

           int ihoy=(int) (hoy.getTime()/ (1000*60*60*24));
           int idate=(int) (date.getTime()/ (1000*60*60*24));
           int dif=idate-ihoy;



           if(dif==0)
               pref="Today";
           if(dif==1)
               pref="Tomorrow";
           if(dif==-1)
               pref="Yesterday";

            Rfecha=pref+" "+formatter2.format(date);


        } catch (Exception e) {
            e.printStackTrace();
        }

    return Rfecha;
}
于 2013-09-04T17:51:44.657 回答
2

除了上面接受的答案之外,另一种比较日期的方法是使用 java.util.Date.getTime() (注意:应该使用 long 而不是 int):

Date today=new Date();
Date dateObj=null;
long diff=0;
try{
    dateObj= formater1.parse(date);
    diff=(today.getTime()-dateObj.getTime())/(86400000);
}catch(Exception e){}
String days="TODAY";
if(diff==1){
    days = "YESTERDAY";
}else if(diff>1){
    days = String.valueOf(diff) + " " +"DAYS AGO";
}

<%=days%> 将返回:

今天

昨天

x 天前

于 2013-11-26T09:40:24.373 回答
1

看jodatime:http: //joda-time.sourceforge.net/

这是文档中的一些示例代码:

public boolean isAfterPayDay(DateTime datetime) {
  if (datetime.getMonthOfYear() == 2) {   // February is month 2!!
    return datetime.getDayOfMonth() > 26;
  }
  return datetime.getDayOfMonth() > 28;
}

public Days daysToNewYear(LocalDate fromDate) {
  LocalDate newYear = fromDate.plusYears(1).withDayOfYear(1);
  return Days.daysBetween(fromDate, newYear);
}

public boolean isRentalOverdue(DateTime datetimeRented) {
  Period rentalPeriod = new Period().withDays(2).withHours(12);
  return datetimeRented.plus(rentalPeriod).isBeforeNow();
}

public String getBirthMonthText(LocalDate dateOfBirth) {
  return dateOfBirth.monthOfYear().getAsText(Locale.ENGLISH);
}
于 2010-11-27T15:06:43.927 回答
0

这是Balus c 实现的扩展版本。

试试这个,我使用 joda-datatime2.2.jar 和 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();
    }
}
于 2014-12-04T06:03:26.810 回答
0

我知道我参加这个聚会迟到了。但我有这个问题的最短解决方案。如果您想根据日期显示“今天”或“昨天”,那么您只需要使用它

String strDate = "";
if (DateUtils.isToday(date.getTime()))
    strDate = "Today";
else if (DateUtils.isToday(date.getTime() + DateUtils.DAY_IN_MILLIS))
    strDate = "Yesterday";

这里的变量 date 是Date对象。

于 2017-12-22T10:03:41.053 回答