如何在安卓系统中获取两个时区的时差



我需要得到不同时区的两个日期之间的时差。当前我正在做的是:

Calendar c1=Calendar.getInstance(TimeZone.getTimeZone("EDT"));
Calendar c2=Calendar.getInstance(TimeZone.getTimeZone("GMT"));
String diff=((c2.getTimeInMillis()-c1.getTimeInMillis())/(1000*60*60))+" hours";
new AlertDialog.Builder(this).setMessage(diff).create().show();

我得到0小时。我做错了什么?

getTimeInMillis()返回从UTC的epoch开始的毫秒数。换句话说,时区与它无关。

我怀疑你实际上想要:

long currentTime = System.currentTimeMillis();
int edtOffset = TimeZone.getTimeZone(srcZoneId).getOffset(currentTime);
int gmtOffset = TimeZone.getTimeZone(targetZoneId).getOffset(currentTime);
int hourDifference = (gmtOffset - edtOffset) / (1000 * 60 * 60);
String diff = hourDifference + " hours";

…其中,srcZoneIdtargetZoneId有效的时区id。注意"EDT"不是时区ID;有点像"半个时区"在最好的情况下。我强烈建议避免使用3个字母的缩写,因为它们实际上并不能识别时区。例如,使用"America/New_York"one_answers"欧洲/London"以上都可以。

当然,虽然上述方法在2011年是一种合理的方法,但如果您使用的是Java 8或更高版本,那么绝对值得在Java中使用类。java.util.Calendar, java.util.TimeZone

java.time

当时写的问题和答案使用java.util日期时间API,这是2011年的正确做法。2014年3月,现代日期时间API作为Java 8标准库的一部分发布,取代了传统的日期时间API,从那时起强烈建议切换到java.time,现代日期时间API。

使用java.time

解决方案

不要使用三个字母的时区ID:在使用现代日期时间API之前,让我们看看Java 7 Timezone文档中的以下重要注意事项:

三个字母的时区id

与JDK 1.1兼容。x,其他三个字母的时区id(如"PST", "CTT", "AST")也支持。然而,的使用是不赞成的,因为相同缩写通常用于多个时区(例如,"CST"可能是美国"中央标准时间"。和"中国标准时间"),以及Java平台只能识别其中一个。

理想解:

import java.time.Instant;
import java.time.ZoneId;
import java.util.concurrent.TimeUnit;
class Main {
    public static void main(String[] args) {
        Instant now = Instant.now();
        long offest1InSec = ZoneId.of("America/New_York").getRules().getOffset(now).getTotalSeconds();
        long offest2InSec = ZoneId.of("Etc/UTC").getRules().getOffset(now).getTotalSeconds();
        long hours = TimeUnit.HOURS.convert(offest2InSec - offest1InSec, TimeUnit.SECONDS);
        System.out.println(hours);
    }
}
输出现在

<一口> * :

5
<<p> 在线演示/kbd>

如果所需的差异来自GMT/UTC

,则更简单

以上解是任意两个时区的通解。但是,如果所需的差异来自GMT/UTC,则会变得更简单。在这种情况下,您不需要计算差异,因为时区的偏移量总是给出w.r.t. UTC,其偏移量为00:00小时。

:

import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.concurrent.TimeUnit;
class Main {
    public static void main(String[] args) {
        long hours = Math.abs(TimeUnit.HOURS.convert(
                ZoneId.of("America/New_York").getRules().getOffset(Instant.now()).getTotalSeconds(), TimeUnit.SECONDS));
        System.out.println(hours);
        
        // Alternatively,
        hours = Math.abs(TimeUnit.HOURS.convert(
                ZonedDateTime.now(ZoneId.of("America/New_York")).getOffset().getTotalSeconds(), TimeUnit.SECONDS));
        System.out.println(hours);
    }
}

:

5
5

Trail: Date Time了解更多关于现代日期时间API的信息。


*美国东部时间(例如America/New_York)采用夏时制。在夏时制期间,它与UTC的偏移量为4小时,在非夏时制期间(例如现在,2023年1月28日),它与UTC的偏移量为5小时。

Jon很接近,但由于字符限制,我无法编辑他的答案。这是相同的代码,但将东部标准时间的"EDT"改为"EST"。

long currentTime = System.currentTimeMillis();
int edtOffset = TimeZone.getTimeZone("EST").getOffset(currentTime);
int gmtOffset = TimeZone.getTimeZone("GMT").getOffset(currentTime);
int hourDifference = (gmtOffset - edtOffset) / (1000 * 60 * 60);
String diff = hourDifference + " hours";

但是这个解决方案做出了一个主要的假设,即TimeZone.getAvailableIDs()在它的字符串数组中同时具有"EST"one_answers"GMT"。如果该方法不包含这些时区字符串,它将返回0偏移

下面是我的代码两个计算两个不同时区之间的时差。如当前时区(GMT+05:00)和国外时区(GMT+05:30)。

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                LocalDate today = LocalDate.now();
                Duration timeDifference = Duration.between(today.atStartOfDay(ZoneId.of(foreigntimezone)), today.atStartOfDay(ZoneId.of(currenttimezone)));
                holder.textViewTimeDifference.setText(timeDifference.toString());
            } else {
                long now = System.currentTimeMillis();
                long diffMilliSeconds = TimeZone.getTimeZone(gmtReplaceUTC).getOffset(now) - TimeZone.getTimeZone(currentTimeZone).getOffset(now);
                if (diffMilliSeconds > 0) {
                    String timeDifference = formatTime(diffMilliSeconds);
                    holder.textViewTimeDifference.setText(timeDifference);
                } else {
                    String timeDifference = formatTime(-diffMilliSeconds);
                    holder.textViewTimeDifference.setText("-" + timeDifference);
                }
            }
}

结果:空气污染指数26以上(PT+30M)及以下(30:00)

相关内容

  • 没有找到相关文章

最新更新