午夜后倒计时错误(与时区和时钟有关)
Countdown timer bug after midnight (Related to Timezone and Clock )
我的应用程序中有几个用户报告了一段时间的奇怪行为 reset/bug,我对此感到困惑,在测试和收集日志之后 - 我认为我的计时器,如果之前启动午夜,立即重置为 20 多个小时,我不知道为什么或如何防止这种情况。
该项目是开源的,欢迎任何人帮助我,这里是链接:
关于 app/project 的信息:
- Select 个应用,select 所需的锁定时间,锁定应用。
Time/Date 相关片段
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 结束。
但是,如果有人在 23:55:00 开始封锁 30 分钟,"Time left to unlock" 将跳到 21 小时,而不是 30 分钟。只有当新的一天 starts/timer 在午夜之前开始时才会发生这种情况。
出现此问题是因为您以 "H:m:ss" 格式存储了时间,但忽略了日期方面。使用 System.currentTimeMillis()
可以得到 1970 年 1 月 1 日之后的毫秒数。因此这包括日期方面。取这两个值的差值将得到过期的毫秒数,您可以根据任何时间间隔检查经过的时间。
改为这样做:
当为计时器保存时间时应该使用毫秒而不是 H:mm:ss :
long millisNow = System.currentTimeMillis();
将 millisNow 保存到数据库。
并保存应该经过的时间:
int minutes = 30;
long millisElapse = 30 * 60 * 1000;
将其保存到数据库(或您需要的任何时间间隔)
现在得到差异
long diff = timeNow - timeDatabase;
if(diff > millisElapse){
//end session
}
顺便说一句:您发布的格式 "H:M:ss"。大写 "M" 代表月(!)而不是分钟。
查看 "Date and Time Patterns" SimpleDateFormat
上的文档
我的应用程序中有几个用户报告了一段时间的奇怪行为 reset/bug,我对此感到困惑,在测试和收集日志之后 - 我认为我的计时器,如果之前启动午夜,立即重置为 20 多个小时,我不知道为什么或如何防止这种情况。
该项目是开源的,欢迎任何人帮助我,这里是链接:
关于 app/project 的信息:
- Select 个应用,select 所需的锁定时间,锁定应用。
Time/Date 相关片段
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 结束。
但是,如果有人在 23:55:00 开始封锁 30 分钟,"Time left to unlock" 将跳到 21 小时,而不是 30 分钟。只有当新的一天 starts/timer 在午夜之前开始时才会发生这种情况。
出现此问题是因为您以 "H:m:ss" 格式存储了时间,但忽略了日期方面。使用 System.currentTimeMillis()
可以得到 1970 年 1 月 1 日之后的毫秒数。因此这包括日期方面。取这两个值的差值将得到过期的毫秒数,您可以根据任何时间间隔检查经过的时间。
改为这样做:
当为计时器保存时间时应该使用毫秒而不是 H:mm:ss :
long millisNow = System.currentTimeMillis();
将 millisNow 保存到数据库。
并保存应该经过的时间:
int minutes = 30;
long millisElapse = 30 * 60 * 1000;
将其保存到数据库(或您需要的任何时间间隔)
现在得到差异
long diff = timeNow - timeDatabase;
if(diff > millisElapse){
//end session
}
顺便说一句:您发布的格式 "H:M:ss"。大写 "M" 代表月(!)而不是分钟。
查看 "Date and Time Patterns" SimpleDateFormat