Problem with Calendar.get(Calendar.HOUR)

2019-04-28 15:43发布

问题:

I am trying to display in a TextView when my application last updated (e.g., "Last updated at 12:13). I am trying to use a Calendar instance and I thought I understood it correctly but I seem to be having trouble. I know to get an instance I use the method Calendar.getInstance(). And then to get the hour and minute I was using Calendar.get(Calendar.HOUR) and Calendar.get(Calendar.MINUTE). My minute field returns correctly but Calendar.HOUR is returning the hour on a 24 hour clock and I want a 12 hour clock. I thought HOUR_OF_DAY was 24 hour clock. Where am I going wrong?

Here is the code I'm using:

Calendar rightNow = Calendar.getInstance();
mTv.setText("Refreshed! Last updated " + 
           rightNow.get(Calendar.HOUR) + ":" + 
           rightNow.get(Calendar.MINUTE) + ".");

mTv is my TextView that I'm updating. Thanks for any help.

Also, it would be ideal if I could say "Last updated 5 minutes ago." instead of "Last updated at 12:13pm". But I'm not sure the best way to have this update each minute without draining resources or the battery...?

回答1:

I'd recommend using SimpleDateFormat in combination with the Date class for formatting the time:

Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("K:mm a");
String formattedTime = sdf.format(now);

Short explanation how it works: You create a SimpleDateFormat object and pass a String to it's construtor which tells it how to format every time/date object that gets passed to the format() function of it. There are plenty of constants/letters which represent a special time object (e.g. seconds, an AM/PM marker, .. see the class documentation for the full list).

"K:mm a" means a "11:42 AM" format - one or two digits for the hour (depending on its value) in a 12 hour format, always two digits for minutes (mm) and either AM or PM (a), depending on the time.

After you did that, just pass a Date object to the format() function, and you'll get a formatted string. Note that a Date just holds one single point in time, if you create it from the constructor with no arguments ("= new Date()") it uses the current time. If you need another time, you can pass a long argument with the millis, you may get that from Calendar.getTimeInMillis().

As of implementing the "updated XY minutes ago function" - yes you'd have to update this every minute and you have to calculate the difference between the update and the current time. I'd say it's not worth it from a battery and extra work perspective. If your app uses standard short update cycles (e.g. every hour or somthing along those lines) and is not fullscreen, the user has a visible clock on top/bottom of his screen. If he really wants to check how long it was since the update, he can take a short look and compare (mostly just minutes or hours/minutes). And IMHO thats no inconvinience for a user, at least it would not for me. I'd just compare without thinking about that. But I tend to kill apps which waste my battery for no useful reason.

Also note that not everybody uses a 12-hour format. To get a localized time format depending on users settings/country use DateFormat.getTimeInstance(). This returns a DateFormat, but this works like the SimpleDateFormat, just pass a time to format().



回答2:

Use Calendar.HOUR_OF_DAY for 24h clock

Calendar rightNow = Calendar.getInstance();
mTv.setText("Refreshed! Last updated " + 
rightNow.get(Calendar.HOUR_OF_DAY) + ":" + 
rightNow.get(Calendar.MINUTE) + ".");


回答3:

You can update editText in each minute using a thread like following

Thread t = new Thread(){
public void run() {     
    Calendar oldTime = Calendar.getInstance();
    oldMinute =  oldTime .get(Calendar.MINUTE);
    while(true) {
            Calendar rightNow= Calendar.getInstance();          
        newMinute = rightNow.get(Calendar.MINUTE);
        if(newMinute != oldMinute) {

            oldMinute = newMinute;

            mTv.setText("Refreshed! Last updated " + 
                       rightNow.get(Calendar.HOUR) + ":" + 
                       rightNow.get(Calendar.MINUTE) + ".");
        }
    }
}
t.start();


回答4:

Well, Calendar.get(Calendar.HOUR) should be returning 12-hour time, but if you wanted to produce your slightly nicer text, you can use the TimeUnit class for parsing simplicity.

long millis = Calendar.getInstance().getTimeInMillis();
String.format("Last updated %d min, %d sec ago.", 
    TimeUnit.MILLISECONDS.toMinutes(millis),
    TimeUnit.MILLISECONDS.toSeconds(millis) - 
    TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis))
);