java Android - 在 Chronometer 中计算经过的时间

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13295140/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 12:10:44  来源:igfitidea点击:

Android - calculations with time elapsed in the Chronometer

javaandroidtimetimerchronometer

提问by flawyte

In Chronometer, how can we extract the time elapsed and store it separately in variables.

在 Chronometer 中,我们如何提取经过的时间并将其单独存储在变量中。

For example, store the number of hours, minutes, seconds elapsed in separate int variables?

例如,将经过的小时数、分钟数、秒数存储在单独的 int 变量中?

Is it possible? If Yes, How?

是否可以?如果是,如何?

Apart from Chronometer can it be better done using some other concept? If Yes, what is it?

除了 Chronometer 之外,使用其他概念可以更好地完成吗?如果是,那是什么?

回答by flawyte

You can get the time value (in milliseconds) doing that :

您可以获得时间值(以毫秒为单位):

long timeElapsed = SystemClock.elapsedRealtime() - chrono.getBase();

Then you can simply retrieve the hours, minutes and seconds as follows :

然后你可以简单地检索小时、分钟和秒,如下所示:

long timeElapsed = 7564000; //For example
int hours = (int) (timeElapsed / 3600000);
int minutes = (int) (timeElapsed - hours * 3600000) / 60000;
int seconds = (int) (timeElapsed - hours * 3600000 - minutes * 60000) / 1000;
//hours = 2
//minutes = 6
//seconds = 4

回答by Sam

A couple ideas jump out at me:

我突然想到了几个想法:

  • A Chronometer extends a TextView so use getText()and parse the time with each ":"(or whatever the local time separator is).
  • You can also calculate the current time in milliseconds on your own, pass this to a Java Calendar object and use it's get()method:

    Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
    calendar.setTimeInMillis(SystemClock.elapsedRealtime() - chronometer.getBase());
    int hour = calendar.get(Calendar.HOUR_OF_DAY);
    // etc
    
  • Chronometer 扩展了 TextView,因此使用getText()并解析每个":"(或任何本地时间分隔符)的时间。
  • 您还可以自己计算当前时间(以毫秒为单位),将其传递给 Java Calendar 对象并使用它的get()方法:

    Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
    calendar.setTimeInMillis(SystemClock.elapsedRealtime() - chronometer.getBase());
    int hour = calendar.get(Calendar.HOUR_OF_DAY);
    // etc
    

回答by Aerinx

You could also create your own Chronometer, here is an example I use as a countdown timer, but the idea is just the same in reverse, you should only need to change the CountQueue CountDownTimer to add minutes and hours instead of substracting them, changing the @Override onTick to store iSec as 60 minus the current value and changing "void setTimeText()" to however you want to display the values. setTrainingCountdown() should also change so it starts at 0 by default.

你也可以创建你自己的 Chronometer,这是我用作倒数计时器的一个例子,但这个想法正好相反,你应该只需要更改 CountQueue CountDownTimer 来添加分钟和小时而不是减去它们,改变@Override onTick 将 iSec 存储为 60 减去当前值并将“void setTimeText()”更改为您想要显示的值。setTrainingCountdown() 也应该改变,所以它默认从 0 开始。

To use it you just bind any TextView when creating a new SkillQCountdown and you start it with setTrainingCountdown() you might want to create a way to pause and restart the timer (just stop the timer and store the values, then restart with stored values). If you want to store and show milliseconds as well, change this line "counter = new CountQueue(60000, 100);" so you can register the onTick every second instead of every 60 seconds, second value is how frecuently it tries to update the TextView with new values.

要使用它,您只需在创建新的 SkillQCountdown 时绑定任何 TextView 并使用 setTrainingCountdown() 启动它,您可能想要创建一种暂停和重新启动计时器的方法(只需停止计时器并存储值,然后使用存储的值重新启动) . 如果您还想存储和显示毫秒,请更改这一行“counter = new CountQueue(60000, 100);” 所以你可以每秒而不是每 60 秒注册一次 onTick,第二个值是它尝试用新值更新 TextView 的频率。

However, if you just want to store the values precisely, you can get the current time in milliseconds at start of the count and whenever you want to get the values, then substract that values and calculate seconds, minutes and hours the same as you can see it is done inside "public void setTrainingCountdown(long diffInMis)"

但是,如果您只想精确地存储这些值,您可以在计数开始时以毫秒为单位获取当前时间,并且无论何时您想要获取这些值,然后减去该值并尽可能计算秒、分和小时看到它是在“public void setTrainingCountdown(long diffInMis)”中完成的

public class SkillQCountdown {

    int iDay,iHour,iMin,iSec;
    CountQueue counter;
    NumberFormat myFormat = NumberFormat.getInstance();

    Context mContext;
    private TextView text = null;

    public SkillQCountdown(Context context, TextView text){
        mContext = context;
        this.text = text;
    }

    public void setTrainingCountdown(long diffInMis) {
        myFormat.setMinimumIntegerDigits(2);

        try {
            if(diffInMis < 0) {
                Toast.makeText(mContext, "Skill Queue unsynchronized"
                        ,Toast.LENGTH_SHORT).show();

            }else {             
                long diff = TimeUnit.MILLISECONDS.toSeconds(diffInMis);
                iDay = (int) (diff/(60*60*24));

                long lday = (diff%(60*60*24));
                iHour = (int)(lday/3600);

                long lhour = (lday%(60*60));
                iMin = (int)(lhour/60);

                long lmin= (lhour%(60));
                iSec = (int)(lmin);

                setTimeText();

                counter = new CountQueue(iSec*1000, 100);
                counter.start();}

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

    private void setTimeText() {
        StringBuilder sb = new StringBuilder();
        String strText = null;

        if (iDay > 0) {
            sb.append(myFormat.format(iDay));
            if (iDay == 1) {
                sb.append(" day ");
            }else {
                sb.append(" days ");
            }
        }

        if (iHour > 0 || iDay > 0) {
            sb.append(myFormat.format(iHour));
            if (iHour == 1) {
                sb.append(" hour ");
            }else {
                sb.append(" hours ");
            }
        }

        if (iMin > 0 || iHour > 0 || iDay > 0) {
            sb.append(myFormat.format(iMin));
            if (iMin == 1) {
                sb.append(" minute ");
            }else {
                sb.append(" minutes ");
            }
        }

        if (iSec > 0 || iMin > 0 || iHour > 0 || iDay > 0) {
            sb.append(myFormat.format(iSec));
            sb.append(" seconds");
            strText = sb.substring(0);
        }else {
            strText = mContext.getString(R.string.msg_skillQueueEmpty);
        }

        text.setText(strText);
    }

    private class CountQueue extends CountDownTimer{
        public CountQueue(long millisInFuture, long countDownInterval) {
            super(millisInFuture, countDownInterval);
        }
        @Override
        public void onFinish() {
            iSec = 0;
            setTimeText();

            counter = new CountQueue(60000, 100);
            counter.start();
            iMin-=1;

            if(iMin < 0 && (iHour > 0 || iDay > 0)) {
                iMin=59;
                iHour-=1;

                if(iHour < 0 && iDay > 0) {
                    iHour=23;
                    iDay-=1;
                }
            }
        }

        @Override
        public void onTick(long millisUntilFinished) {
            if (Math.floor((float)millisUntilFinished / 1000.0f) != iSec) {  
                iSec = (int) Math.floor((float)millisUntilFinished / 1000.0f);
                setTimeText();
             }
        }
    }

}