java 如何在android中获得两个时区之间的时差?

ugmeyewa  于 2023-01-29  发布在  Java
关注(0)|答案(4)|浏览(142)

我需要获取不同时区的两个日期之间的时差。目前我正在执行以下操作:

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();

我有100n1x个小时。我做错什么了?

whlutmcx

whlutmcx1#

getTimeInMillis()返回UTC* 中的纪元以来的毫秒数 *。换句话说,时区与它无关。
我怀疑你实际上想要:

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";

...其中srcZoneIdtargetZoneIdvalid 时区ID。注意“EDT”不是时区ID;最多是“半个时区”。我强烈建议避免使用3个字母的缩写,因为它们实际上并不能识别时区。例如,使用“America/New_约克”和“Europe/伦敦”就可以了。
当然,尽管上述方法在2011年是一种合理的方法,但如果您使用的是Java8或更高版本,那么使用java.time中的类(而不是java.util.Calendarjava.util.TimeZone等)肯定是值得的。

atmip9wb

atmip9wb2#

乔恩很接近,但由于字符限制,我不能编辑他的答案。这是相同的代码,但“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”和“GMT”,如果这个方法不包含这些时区字符串,它将返回0偏移。

ztigrdn8

ztigrdn83#

Java.时间

Question和answer written at that time使用java.util日期-时间API,这在2011年是正确的做法。2014年3月,modern Date-Time API作为Java 8标准库的一部分发布,取代了传统的日期-时间API,从那时起,强烈建议切换到java.time,即现代日期-时间API。

使用java.time的解决方案

    • 请勿使用三个字母的时区ID**:在使用现代的日期-时间API之前,让我们看看Java 7 Timezonedocumentation中的以下重要说明:

三个字母的时区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

ONLINE DEMO

如果所需的差值与GMT/UTC不同,则会更加简单

上述解决方案是任意两个时区的通用解决方案。然而,如果所需的差值是GMT/UTC,则会变得更加简单。在这种情况下,您不需要计算差值,因为时区的偏移量总是相对于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 *)采用DST。在DST期间,它与UTC的偏移为4小时,在非DST期间(例如现在,2023年1月28日),它与UTC的偏移为5小时。查看this page以了解有关它的详细信息。
fslejnso

fslejnso4#

这里是我的代码二计算两个不同时区之间的时差。如当前时区(格林尼治标准时间+05:00)和外国时区(格林尼治标准时间+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 API水平(PT+30M)和低于26 API水平(30:00)

相关问题