我正在构建后端队列系统。我的应用用户需要在上午08:00:00左右自动从服务器获取数据,每个时区都需要。
每个用户都需要分配到一天的特定时间。由于应用程序使用具有特定每分钟调用限制的API,因此他只能在此时获取数据。
如何将客户端与服务器同步?
注意
我遇到了具体的问题,并且已经解决了。我正在发布解决方案作为一个完整的答案,结合我在解决它时发现的许多答案。
答案 0 :(得分:1)
为了清楚起见,使用每个Java / PHP / MySQL支持的UTC
中的时间值,因为:
虽然GMT和UTC在实践中分享相同的当前时间,但两者之间存在基本差异: GMT是一些在欧洲和非洲一些国家正式使用的时区。可以使用24小时格式(0 - 24)或12小时格式(1 - 12 am / pm)显示时间。 UTC不是时区,而是一个时间标准,是全球公民时间和时区的基础。这意味着没有国家或地区正式使用UTC作为本地时间。
它为您提供简单的解决方案,因为一旦您使用UTC,您只需要将其转换为服务器或客户端'用于显示目的的时区。
您需要将客户端的时区发送到后端,以计算您希望他将API调用的时间。您想将08:00:00当地时间转换为UTC,但这是一个技巧,因为有不兼容的时区' Java和PHP之间的字符串。
// Java/Android
SimpleDateFormat sdf = new SimpleDateFormat("z");
我住在波兰,使用上面的代码我会根据季节得到2个不同的值(冬天时CET
和夏令时CEST
)。
// PHP
$tz1 = new DateTimeZone('CET');
$tz2 = new DateTimeZone('CEST');
问题在于,当我将其传递给PHP时,CET
完全可以支持时区字符串,但CEST
不是。
要统一代码,您需要使用:
// Java/Android
SimpleDateFormat sdf = new SimpleDateFormat("ZZZZ");
它为您提供了一个时区:
GMT+01:00 // for CET
GMT+02:00 // for CEST
请注意,当您使用
http://api.domain.com?timezone=GTM+02:00
这样的网址发送广告时,您需要将+
更改为%2B
,因为转换为GTM 02:00
的时区不能在PHP中运行
获得客户的时区后,在PHP中,您将当地时间上午08:00:00转换为UTC
。
$tz = new DateTimeZone('GMT+02:00');
$dt = new DateTime('2017-03-30 08:00:00', $tz);
$dt->setTimezone(new DateTimeZone('UTC'));
echo $dt->format('H:i:s');
// echoes 06:00:00
然后在MySQL类型的列中存储计算值。您不需要关心数据库中的时区,因为TIME和DATE类型与时区无关。
您在应用中收到06:00:00作为回复,并使用AlarmManager
对象设置Calendar
,如下所示:
// set UTC as a time zone
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.setTime(new Date());
long timeNow = cal.getTimeInMillis();
// set 06:00:00
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.HOUR_OF_DAY, 6);
// make sure to set alarm in future
long timeAlarm = cal.getTimeInMillis();
if (timeAlarm <= timeNow) {
cal.add(Calendar.HOUR_OF_DAY, 24);
}
alarm.setRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(),
24*60*60*1000, pintent);