0

I'm developing and android app and I'm trying to find the current difference in time between my device and Russia local time .

I managed to get the difference between my device time and GMT as follow

        Calendar cc = Calendar.getInstance(TimeZone.getTimeZone("GMT"), 
              Locale.getDefault());
        Date currentLocalTime = cc.getTime();
        DateFormat xdate = new SimpleDateFormat("Z");
        String timetime = xdate.format(currentLocalTime);
        Log.i("out","OFF SET FROM GMT " + timetime);

I tried changing GMT to MSK but that didnt work .

How do I get the output to be MSK +/- x ?

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
user780277
  • 81
  • 1
  • 4

5 Answers5

2

This is quite easy to get a difference between two time zones. We know that Moscow in GMT+3 time zone:

ZonedDateTime utcTime = ZonedDateTime.now(ZoneOffset.UTC);
ZonedDateTime moscowTime = ZonedDateTime.now(ZoneId.of("Europe/Moscow"));
int utcOffs = utcTime.getOffset().getTotalSeconds();
int moscowOffs = moscowTime.getOffset().getTotalSeconds();
double hoursOffs = (moscowOffs - utcOffs) / 3600.0; // hoursOffs = 3.0

P.S. Not using java.time

Calendar utcTime = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
Calendar moscowTime = Calendar.getInstance(TimeZone.getTimeZone("Europe/Moscow"));
int utcOffs = utcTime.getTimeZone().getRawOffset();
int moscowOffs = moscowTime.getTimeZone().getRawOffset();
double hoursOffs = (moscowOffs - utcOffs) / 1000 / 3600.0; // hoursOffs = 3.0
Oleg Cherednik
  • 17,377
  • 4
  • 21
  • 35
  • Unfortunately `java.time` was only added to Android in API 26 (8.0). For most developers that doesn't have enough deployment percentage yet. – Joachim Sauer Jun 06 '18 at 09:23
  • @JoachimSauer Actually, I do not see `Android` badge under the question, only `java` – Oleg Cherednik Jun 06 '18 at 10:19
  • True, but OP has posted about the Android API and called `Log.i` in the sample code. It would have been better if he had stated that explicitly. – Joachim Sauer Jun 06 '18 at 10:21
  • @OleV.V. No problem, if you can use source code. I have fixed it. – Oleg Cherednik Jun 07 '18 at 06:09
  • 1
    @JoachimSauer Much of the *java.time* functionality is back-ported to Java 6 & Java 7 in the [***ThreeTen-Backport***](http://www.threeten.org/threetenbp/) project. Further adapted for earlier Android in the [***ThreeTenABP***](https://github.com/JakeWharton/ThreeTenABP) project. See [*How to use ThreeTenABP…*](http://stackoverflow.com/q/38922754/642706). – Basil Bourque Jun 12 '18 at 02:13
1

java.time

    Instant now = Instant.now();
    ZoneOffset deviceOffset = now.atZone(ZoneId.systemDefault()).getOffset();
    ZoneOffset russiaOffset = now.atZone(ZoneId.of("Europe/Moscow")).getOffset();
    int diffSeconds = deviceOffset.getTotalSeconds() - russiaOffset.getTotalSeconds();
    Duration diff = Duration.ofSeconds(diffSeconds);
    System.out.format(Locale.getDefault(),
            "Current offset between device time and Moscow time: %+03d%02d%n",
            diff.toHours(), diff.toMinutesPart());

Running the above today in Europe/Copenhagen time zone I got:

Current offset between device time and Moscow time: -0100

Since Denmark is currently on summer time (DST) and therefore at offset +0200, and Moscow is at +0300 (all year), this output is correct.

“Russia time” is ambiguous since Russia is using 11 different time zone. There’s a link to a list at the bottom. You mentioned MSK, so I assumed you meant Moscow time. You shouldn’t rely on three or four letter time zone abbreviations, though, at least not in your code. While MSK may be unambiguous, the abbreviations are not standardized and very many of them ambiguous. Instead give time zone as Europe/Moscow (or Asia/Srednekolymsk, etc.).

The toMinutesPart method I am using was introduced in Java 9. For Java 6 through 8 you need to subtract the hours from the duration and then use toMinutes.

Why didn’t your approach work?

Pattern letter Z in a formatter always gives you offset from UTC. So you cannot use it for obtaining offset from Moscow time (or any other time).

As an aside consider throwing away the long outmoded and notoriously troublesome DateFormat and SimpleDateFormat and equally outdated friends Date and Calendar. java.time, the modern Java date and time API is so much nicer to work with.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

All you need to do is this,

LocalDateTime.now(ZoneId.of("Europe/Moscow"));

Another Solution:

final SimpleDateFormat dateFormatter =
    new SimpleDateFormat("EEE, MMM d, yyyy hh:mm:ss a z");
dateFormatter.setTimeZone(TimeZone.getTimeZone("Europe/Moscow"));
System.out.println("MSK Time: " + dateFormatter.format(new Date()));
user2004685
  • 9,548
  • 5
  • 37
  • 54
  • is there another solution ? because this call requires a much higher api than i intend to use ( 16 ) – user780277 Jun 05 '18 at 22:12
  • @user780277 Updated. – user2004685 Jun 05 '18 at 22:19
  • Thank you but this only gives me current time in Moscow. All i need is how many hours is the difference between my location and Moscow – user780277 Jun 05 '18 at 22:21
  • `OffsetDateTime.now(ZoneId.of("Europe/Moscow")).getOffset()` will give you the offset from GMT. To use it on API level 16 add [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP) to your project. See [this question](https://stackoverflow.com/questions/38922754/how-to-use-threetenabp-in-android-project). – Ole V.V. Jun 06 '18 at 08:35
  • @user780277 Much of the *java.time* functionality is back-ported to Java 6 & Java 7 in the [***ThreeTen-Backport***](http://www.threeten.org/threetenbp/) project. Further adapted for earlier Android in the [***ThreeTenABP***](https://github.com/JakeWharton/ThreeTenABP) project. See [*How to use ThreeTenABP…*](http://stackoverflow.com/q/38922754/642706). – Basil Bourque Jun 12 '18 at 02:14
  • `LocalDateTime` is the wrong class here, as it lacks any concept of time zone or offset-from-UTC. So a `LocalDateTime` does *not* represent a specific moment. Instead, use `Instant` or `ZonedDateTime`. Also, this does not address the Question, which is looking for the offset-from-UTC in a particular zone at a particular moment. – Basil Bourque Jun 12 '18 at 02:15
0

I solved it thanks to Mihai Adrian as the following

 long now = System.currentTimeMillis();

        String tzx = "Europe/Moscow";
        TimeZone mTimeZone = TimeZone.getTimeZone(tzx);
        int remote = mTimeZone.getOffset(now);

        TimeZone mTimeZone2 = TimeZone.getDefault();
        int local = mTimeZone2.getOffset(now);

        double differenceInHours = (local - remote) / 3600000.0;

        double number = differenceInHours;
        int value_h = (int) number;
        double frac = number - value_h;
        int value_m=(int) (frac*60);
        String result=value_h+" and " +value_m;
user780277
  • 81
  • 1
  • 4
0

You can do something like below, Take the Calender with required time zone and get the hour and Day of month for that zone.to get the hour difference subtract the hourDifference of both the time zone.

    Calendar c = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
    c.setTimeInMillis(new Date().getTime());

    int GmtHourOfDay = c.get(Calendar.HOUR_OF_DAY);
    int GmtDayOfMonth = c.get(Calendar.DAY_OF_MONTH);


    c = new GregorianCalendar(TimeZone.getTimeZone("Europe/Moscow"));
    c.setTimeInMillis(new Date().getTime());

    int RussHourOfDay = c.get(Calendar.HOUR_OF_DAY);
    int RussDayOfMonth = c.get(Calendar.DAY_OF_MONTH);

    int hourDifference = GmtHourOfDay - RussHourOfDay;
    int dayDifference = GmtDayOfMonth - RussDayOfMonth;
    if (dayDifference != 0) {
    hourDifference = hourDifference + 24;
    }
    System.out.println(hourDifference);
Zia
  • 1,001
  • 1
  • 13
  • 25