I have following method that I would like to make shorter or faster if nothing else. Please all comments are welcome:
Bellow method takes a date object, formates it ("EEE hh:mma MMM d, yyyy") and then figures out if the date is today or yesterday and than, if it is, it returns "(Yesterday | Today) hh:mma" formated string.
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;
}
my understanding of the question is provide a simple method to produce output like the following:
the code below worked for me, but i am new to android and maybe others could point out if the code is not robust. in code below 'timeLong' is the time of my events in epoch time (milliseconds).
Time Zone
The Question and the other Answers ignore the crucial issue of time zone. That input string lacks any time zone or offset-from-UTC. So that string will be parsed while assuming it represents a date-time in your JVM’s current default time zone. Risky business as (a) that assumption may be false, and (b) that default can change at any moment, even during runtime.
Locale
The Question and other Answers ignore another crucial issue:
Locale
. The Locale determines the human language used to translate the name of day and name of month from the input string during parsing (and generating).If not specified the JVM’s current default Locale will be used for translation. Just as with time zone, your JVM’s default Locale can change at any moment, even during runtime.
Better to specify your desired/expected Locale.
java.time
The Question and the other Answers use the old date-time classes that have proven to be poorly designed and troublesome. Java 8 and later has the java.time framework built-in whose classes supplant the old ones.
You method to parse a string while generating a new string should be broken up into two methods. One method should parse to obtain date-time objects. The second should take date-time objects and generate the desired string output. Then each can be used separately. And this approach leads us away from thinking of strings as date-time values. Strings are textual representations of date-time values. Your business logic should focus on manipulating those date-time values as objects, not focus on strings.
Parsing
Generating
Given a
ZonedDateTime
in hand from the method above, we can generate a textual representation of its date-time value using a specified Locale for translation of name-of-day and name-of-month.To determine if the date-time is for today or yesterday, we only care about the date portion without time of day. For that we can use the
LocalDate
class in java.time.Example
Exercise those two methods.
Arbitrarily choosing a time zone of
America/New_York
as the Question does not specify.By the way, you can ask java.time to automatically format the output string according to the cultural norms of the Locale instead of hard-coding a format.
Dump to console.
By the way, I suggest putting a SPACE before the
AM
orPM
for easier reading.You wrote "all comments welcome" so here's my way using joda-time. :)
I am a fan of displaying dates and times in the short and smart way of iPhone's recent calls (similar to google wave posts). That is "hh:mm" if today, "yesterday" or name of weekday if <7 days, else yyyy-MM-dd.
where I use a set of SimpleDateFormat (as weekdayFormat above) to format the time to the desired strings, and where DateTime and DateMidnight are joda-time classes.
In these cases the number of elapsed days between two DateTime:s is less relevant than how people would define the time talking about it. Instead of counting days (or milliseconds as I've seen some people do) DateMidnight comes handy here, though other methods would work just as well. :)
this for today,yesterday,tomorrow
Look at jodatime: http://joda-time.sourceforge.net/
this is some example code from the doc:
Another way of comparing dates apart from the accepted answer above using java.util.Date.getTime() (note: long should be used instead of int):
<%=days%> would return: