开发者

Android how to get time difference between two time zones in android?

I need to get time difference between two dates in different time zones. Currently I am doing this:

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

I get 0 hours. What am开发者_JAVA百科 I doing wrong?


getTimeInMillis() returns the number of milliseconds since the epoch in UTC. In other words, the time zone is irrelevant to it.

I suspect you actually want:

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

... where srcZoneId and targetZoneId are valid time zone IDs. Note that "EDT" is not a time zone ID; it's sort of "half a time zone" at best. I would strongly recommend avoiding the 3-letter abbreviations, which don't actually identify time zones. For example, using "America/New_York" and "Europe/London" for the above would be fine.

And of course, while the above was a reasonable approach back in 2011, if you're using Java 8 or above it's definitely worth using classes in java.time rather java.util.Calendar, java.util.TimeZone etc.


java.time

The question and the answer written at that time use the java.util date-time API which was the right thing to do in 2011. In March 2014, the modern Date-Time API was released as part of the Java 8 standard library which supplanted the legacy date-time API and since then it is strongly recommended to switch to java.time, the modern date-time API.

Solution using java.time

Do not use three-letter timezone ID: Before doing it using the modern date-time API, let's see the following important note from the Java 7 Timezone documentation:

Three-letter time zone IDs

For compatibility with JDK 1.1.x, some other three-letter time zone IDs (such as "PST", "CTT", "AST") are also supported. However, their use is deprecated because the same abbreviation is often used for multiple time zones (for example, "CST" could be U.S. "Central Standard Time" and "China Standard Time"), and the Java platform can then only recognize one of them.

The desired solution:

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

Output now*:

5

ONLINE DEMO

It gets even simpler if the desired difference is from GMT/UTC

The above solution is a general solution for any two time zones. However, if the desired difference is from GMT/UTC, it gets even simpler. In this case, you don't need to calculate the difference because the offset of a time zone is always given w.r.t. UTC whose offset is 00:00 hours.

Demo:

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

Output:

5
5

Learn more about the modern Date-Time API from Trail: Date Time.


* US Eastern Time (e.g. America/New_York) observes DST. During the DST period, its offset from UTC is 4 hours and during the non-DST period (e.g. now, 28-Jan-2023), it's 5 hours. Check this page to learn more about it.


Jon is close, but due to character restrictions I can't edit his answer. This is the same code but with "EDT" changed to "EST" for Eastern Standard Time.

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

But this solution makes a major assumption that TimeZone.getAvailableIDs() has within it's string array both "EST" and "GMT". If that method doesn't contain those timezone strings it will come back as 0 offset.


Here is my code two calculate the time difference between two different timezones. like current timezone(GMT+05:00) and foreign timezone(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);
                }
            }
}

Result: for above 26 API level (PT+30M) and for below (30:00)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜