Ошибка таймера обратного отсчета после полуночи (относится к часовому поясу и часам) - PullRequest
0 голосов
/ 02 января 2019

У меня есть несколько пользователей в моем приложении, сообщающих о странном поведении сброса / ошибки времени, я был сбит с толку этим и после тестирования и сбора журналов - я подумал, что мой таймер, если он запускается до полуночи, сбрасывается вБолее 20 часов, я не могу понять, почему или как это предотвратить.

Проект с открытым исходным кодом, и любой желающий может помочь мне с этим, вот ссылки:

GitHub

Информация о приложении / проекте:

  • Выбор приложений, выбор необходимого времени блокировки, блокировка приложений.

Мой класс таймера (Полный)

Фрагмент, относящийся ко времени / дате

 public class Timer_Service extends Service {

public static final long NOTIFY_INTERVAL = 1000;
public static String str_receiver = "com.nephi.getoffyourphone.receiver";
public String str_testing;
Calendar calendar;
SimpleDateFormat simpleDateFormat;
String strDate;
Date date_current, date_diff;
//Root Detector
RootBeer rootbeer;
//Con Manager
WifiManager wifiManager;
//DH Helper
DB_Helper db;
Intent intent;
Intent lockIntent;
Intent Shame;
//Shame Int Counter
private Handler mHandler = new Handler();
private Timer mTimer = null;

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    super.onCreate();
    //Lock Screen launch
    lockIntent = new Intent(this, locked.class);
    lockIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    calendar = Calendar.getInstance();
    simpleDateFormat = new SimpleDateFormat("H:M:ss");

    mTimer = new Timer();
    mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 5, NOTIFY_INTERVAL);
    intent = new Intent(str_receiver);

    //Root Detector
    rootbeer = new RootBeer(this);
    //Wifi Manager
    wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);

    //DB
    db = new DB_Helper(this);
}  

public String twoDatesBetweenTime() {


    try {
        date_current = simpleDateFormat.parse(strDate);
    } catch (Exception e) {

    }

    try {
        // Gets the first timestamp when the lockdown started
        date_diff = simpleDateFormat.parse(db.get_Data(1));
    } catch (Exception e) {

    }

    try {


        long diff = date_current.getTime() - date_diff.getTime();
        int int_hours = Integer.valueOf(db.get_Hours(1));
        long int_timer;
        if (int_hours > 10) {
            int_timer = TimeUnit.MINUTES.toMillis(int_hours);
        } else {
            int_timer = TimeUnit.HOURS.toMillis(int_hours);
        }
        long long_hours = int_timer - diff;
        long diffSeconds2 = long_hours / 1000 % 60;
        long diffMinutes2 = long_hours / (60 * 1000) % 60;
        long diffHours2 = long_hours / (60 * 60 * 1000) % 24;


        if (long_hours >= 0) {
            str_testing = String.format("%d:%d:%02d", diffHours2, diffMinutes2, diffSeconds2);
            Log.e("TIME", str_testing);

        } else {
            stopService(new Intent(getApplicationContext(), Timer_Service.class));

            mTimer.cancel();
        }

Есть предложения?


РЕДАКТИРОВАТЬ:

  • Таймер работает нормально, если кто-то установит блокировку, например, 30 минут, он обратный отсчет 30 минут и разблокируется, когда это будет сделано.

Скажем, кто-то начал блокировку в21:30:00, таймер будет работать нормально и закончится в 10: 00: 00.

Однако, если кто-то запустил lockdown в 23:55:00 в течение 30 минут, «Время, оставленное для разблокировки» будет прыгать до 21 часа, а не 30 минут.Это происходит только тогда, когда начинается новый день / таймер запускается до полуночи.

1 Ответ

0 голосов
/ 02 января 2019

Проблема возникает из-за того, что у вас есть время, сохраненное в формате «H: m: ss», но вы игнорируете аспект даты.Использование System.currentTimeMillis() дает вам миллисекунды после 1 января 1970 года. Так что это включает аспект даты.Взяв разность двух значений, вы получите истекшие миллисекунды, которые вы можете проверить по любому временному интервалу за истекшее время.


Сделайте это вместо:

При сохранении временидля запуска таймера следует использовать миллисекунду вместо Ч: мм: сс:

long millisNow = System.currentTimeMillis();

сохранить миллисекунду в базе данных.

и сохранить время, которое должно пройти:

int minutes = 30;
long millisElapse = 30 * 60 * 1000;

сохранить это в базе данных (или в любой нужный вам промежуток времени)

теперь получите разницу

long diff = timeNow - timeDatabase;

if(diff > millisElapse){
    //end session
}


Кстати: формат, который вы опубликовали "H: M": сс».Столица "М" стоит месяц (!), А не минуты.
Ознакомьтесь с документацией по шаблонам даты и времени. SimpleDateFormat

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...