0

I have time 12:00:00 in format HH:mm:ss.
I know that this time comes from server witch is setup with +3 offset.
If i use SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");, it parses time with regard to device, which can be in a different timezone.
Is there another way to parse it with regard to +3 offset except adding it to the original string?

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Yarh
  • 4,459
  • 5
  • 45
  • 95
  • 1
    FYI, that class has been outmoded for years by the *java.time* classes, specifically `DateTimeFormatter`. – Basil Bourque Jan 24 '18 at 22:55
  • Do you have a date? Combining a time-of-day with an offset-from-UTC without the context of a date does not make sense. – Basil Bourque Jan 24 '18 at 22:58
  • 1
    This is the job of the [`OffsetTime` class of `java.time`](https://docs.oracle.com/javase/9/docs/api/index.html?overview-summary.html). Follow the link and take a look. – Ole V.V. Jan 25 '18 at 12:51

3 Answers3

3

First, should your server rather send the time in UTC? If clients are everywhere, this would seem more time zone neutral and standardized. However, the way to handle it in code wouldn’t be much different. In any case the server offset form UTC could be constant:

private static final ZoneOffset serverOffset = ZoneOffset.ofHours(3);

In real code you will probably want to make it configurable somehow, though. To parse:

    OffsetTime serverTime = LocalTime.parse("12:00:00").atOffset(serverOffset);
    System.out.println(serverTime);

This prints

12:00+03:00

Since your time format agrees with LocalTime’s default (ISO 8601), we need no explicit formatter. If a representation of the time with offset is all you need, we’re done. If you need to convert to the user’s local time, to do that reliably you need to decide both a time zone and a date:

    LocalTime clientTime = serverTime.atDate(LocalDate.of(2018, Month.JANUARY, 25))
            .atZoneSameInstant(ZoneId.of("Indian/Maldives"))
            .toLocalTime();
    System.out.println(clientTime);

With the chosen day and zone we get

14:00

Please substitute your desired time zone and date.

Just hypothetically, if you knew the user’s offset from UTC, you could use just that:

    LocalTime clientTime = serverTime.withOffsetSameInstant(ZoneOffset.of("-08:45"))
            .toLocalTime();

The example yields 00:15. However, no one knows when the politicians introduce summer time (DST) or other anomalies in the user’s time zone, so I discourage relying on an offset alone.

And yes, I too am using java.time. SimpleDateFormat is not only long outdated, it is also notoriously troublesome, so java.time is what I warmly recommend.

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

Set the timezone on your SimpleDateFormat object:

SimpleDateFormat fmt = new SimpleDateFormat("HH:mm:ss");
fmt.setTimeZone(TimeZone.getTimeZone("GMT+03:00"));

I recommend you use the Java 8 date and time API (package java.time) instead of the old API, of which SimpleDateFormat is a part.

Jesper
  • 202,709
  • 46
  • 318
  • 350
1

Using the Java 8 DateTime API:

DateTimeFormatter formatter = DateTimeFormatter
        .ofPattern("HH:mm:ss");

LocalTime clientLocalTime = LocalTime
        .parse("12:00:00", formatter)
        // Create an OffsetTime object set to the server's +3 offset zone
        .atOffset(ZoneOffset.ofHours(3))
        // Convert the time from the server timezone to the client's local timezone.
        // This expects the time value to be from the same day,
        // otherwise the local timezone offset may be incorrect.
        .withOffsetSameInstant(ZoneId.systemDefault().getRules().getOffset(Instant.now()))
        // Drop the timezone info - not necessary
        .toLocalTime();
Ján Halaša
  • 8,167
  • 1
  • 36
  • 36