如何处理Android和PHP / MySQL之间的时区?

时间:2017-03-30 12:20:47

标签: php android mysql timezone

我正在构建后端队列系统。我的应用用户需要在上午08:00:00左右自动从服务器获取数据,每个时区都需要。

每个用户都需要分配到一天的特定时间。由于应用程序使用具有特定每分钟调用限制的API,因此他只能在此时获取数据。

如何将客户端与服务器同步?

注意

我遇到了具体的问题,并且已经解决了。我正在发布解决方案作为一个完整的答案,结合我在解决它时发现的许多答案。

1 个答案:

答案 0 :(得分:1)

解决方案的核心

为了清楚起见,使用每个Java / PHP / MySQL支持的UTC中的时间值,因为:

  

虽然GMT和UTC在实践中分享相同的当前时间,但两者之间存在基本差异:   GMT是一些在欧洲和非洲一些国家正式使用的时区。可以使用24小时格式(0 - 24)或12小时格式(1 - 12 am / pm)显示时间。   UTC不是时区,而是一个时间标准,是全球公民时间和时区的基础。这意味着没有国家或地区正式使用UTC作为本地时间。

source

它为您提供简单的解决方案,因为一旦您使用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类型与时区无关。

在计算的UTC时间设置闹钟

您在应用中收到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);