如何在android中检测夏令时转换

Posted

技术标签:

【中文标题】如何在android中检测夏令时转换【英文标题】:How to detect Daylight Saving Time transition in android 【发布时间】:2016-07-15 05:09:24 【问题描述】:

我有一个 android 应用程序,它有一个服务女巫根据一些时间计算触发警报。

问题出在时区更改时(即:对于位于法国并从 UTC+1 变为 UTC+2 的用户)。应用程序不会收到有关此更改的通知,因此它会延迟触发警报。

我已经检查过 android TimeZone API 并且知道有一些方法可以提供帮助,例如:

useDaylightTime()

inDaylightTime(Date time)

getDSTSavings()

是否有可能知道更改何时发生,以便在我的计算算法中考虑它?

顺便说一句:我已经查看了很多来自 *** 的博客和问答,但是 不要帮忙:(

编辑(清单文件和接收器类):

这是我的清单:

<receiver android:name=".receiver.NotificationReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
        <action android:name="android.intent.action.TIMEZONE_CHANGED" />
    </intent-filter>
</receiver>

接收器类:

public class NotificationReceiver extends BroadcastReceiver 

    @Override
    public void onReceive(Context context, Intent intent) 
        WakeLock.acquire(context);
        Intent service = new Intent(context, NotificationService.class);
        service.putExtras(intent);
        context.startService(service);

        // Timezone or time change
        if (intent.getAction() != null
            && (intent.getAction().equals(Intent.ACTION_TIME_CHANGED)
                || intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)))
        
            Intent i = new Intent(context, DialogPopUpTimeChange.class);
            i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(i);
        
    

【问题讨论】:

Date and time change listener in Android?的可能重复 不,这不是重复的,因为我已经尝试使用 BroadcastReceiver 但没有帮助。我想知道时区更改何时发生 你没有在你的问题中这么说。当时间变化时,为什么不能使用 BroadcastReceiver 来更新警报? 您在我添加详细信息时发表了评论 :) 对于广播接收器,如果电信公司进行了更改,它不会收到任何信息。这就是为什么我正在寻找另一种选择。 您的结果与其他答案声称的相反。时间变化广播可以经常触发,一天几次,甚至一分钟多次,这取决于设备必须与运营商重新同步的频率。我已经看到了几种不同的解决方法来检测“真正的”DST 更改。甚至声称AlarmManager 会自动处理夏令时更改。但我找不到任何关于未收到广播的报告。也许您没有正确注册它们。您能出示您的注册清单/代码吗? 【参考方案1】:

好吧,我是这样解决这个问题的:

1- 我保留了 Android 清单(见问题)

2- 然后我稍微改变了接收器:

public class NotificationReceiver extends BroadcastReceiver 

    @Override
    public void onReceive(Context context, Intent intent) 
        WakeLock.acquire(context);
        // Timezone or time change
        if (intent.getAction() != null
            && (intent.getAction().equals(Intent.ACTION_TIME_CHANGED)
            || intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)))
        
            calculateTimeZone(context);
        
    

3- 下面是计算新时区的方法和夏令时的使用:

public void calculateTimeZone(Context context) 
    float ONE_HOUR_MILLIS = 60 * 60 * 1000;

    // Current timezone and date
    TimeZone timeZone = TimeZone.getDefault();
    Date nowDate = new Date();
    float offsetFromUtc = timeZone.getOffset(nowDate.getTime()) / ONE_HOUR_MILLIS;

    // Daylight Saving time
    if (timeZone.useDaylightTime()) 
        // DST is used
        // I'm saving this is preferences for later use

        // save the offset value to use it later
        float dstOffset = timeZone.getDSTSavings() / ONE_HOUR_MILLIS;
        // DstOffsetValue = dstOffset
        // I'm saving this is preferences for later use

        // save that now we are in DST mode
        if (timeZone.inDaylightTime(nowDate)) 
            // Now you are in use of DST mode
            // I'm saving this is preferences for later use
         else 
            // DST mode is not used for this timezone
            // I'm saving this is preferences for later use
        
    

就是这样。因此,解决方案是将所有 API(在问题中列出)组合在一起。

我希望这个解决方案对其他人有所帮助。如果你有任何问题 直接在评论里发吧

【讨论】:

以上是关于如何在android中检测夏令时转换的主要内容,如果未能解决你的问题,请参考以下文章

如何在android中处理时区和夏令时?

如何从 Unix 纪元时间转换并在 Python 中考虑夏令时?

如何在 Joda Time 中检测模糊的 DST 重叠?

如何在 R 中将山地标准时间 (MST) 转换为山地夏令时间 (MDT)

JODA 夏令时转换

如何获取另一个时区的夏令时状态