我有以下方法,我想更短或更快,如果没有别的。欢迎所有评论:
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;
}
答案 0 :(得分:40)
以下是使用标准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;
}
}
答案 1 :(得分:3)
你写了“所有评论欢迎”所以这是我使用joda-time的方式。 :)
我喜欢用iPhone近期通话的简短智能方式显示日期和时间(类似于google wave帖子)。那是“hh:mm”如果今天,“昨天”或工作日的名称如果< 7天,否则 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在这里很方便,但其他方法也可以。 :)
答案 2 :(得分: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;
}
答案 3 :(得分: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";
}
&LT;%=天%GT;会回来:
TODAY
YESTERDAY
x DAYS AGO
答案 4 :(得分:2)
我对这个问题的理解是提供一种生成输出的简单方法,如下所示:
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的新手,也许其他人可能会指出代码是否不健全。在下面的代码&#39; timeLong&#39;是我的事件在纪元时间(毫秒)的时间。
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;
}
答案 5 :(得分:2)
问题和其他答案忽略了时区的关键问题。该输入字符串缺少任何时区或offset-from-UTC。因此,在假设它表示JVM当前默认时区中的日期时间时,将解析该字符串。危险的业务,因为(a)该假设可能是错误的,(b)默认情况可能随时发生变化,甚至在运行期间。
问题和其他答案忽略了另一个关键问题:Locale
。 Locale确定用于在解析(和生成)期间从输入字符串转换日期名称和月份名称的人类语言。
如果未指定,JVM的当前默认语言环境将用于转换。与时区一样,您的JVM默认语言环境可以随时更改,甚至在运行时期间也可以更改。
最好指定所需/期望的区域设置。
问题和其他答案使用旧的日期时间类,这些类已被证明设计糟糕且麻烦。 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
,我们可以使用指定的Locale生成日期时间值的文本表示,以便翻译日期名称和月份名称。
为了确定日期时间是今天还是昨天,我们只关心日期部分而没有时间。为此,我们可以在java.time中使用LocalDate
类。
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 [America / New_York] |即时:2016-02-06T16:23:00Z |输出:今天上午11:23 | outputPerLocale:2016年2月6日上午11:23:00
顺便说一下,我建议在AM
或PM
之前加一个空格,以便于阅读。
答案 6 :(得分:1)
看看jodatime: http://joda-time.sourceforge.net/
这是doc中的一些示例代码:
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);
}
答案 7 :(得分: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();
}
}
答案 8 :(得分:0)