-1

When I print date that I get from server, it shows Mon Jun 24 16:15:31 GMT+09:00 2019

val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
val date: Date? = formatter.parse(checkedDate) // date from server
val transformedDate = ("${String.format("%02d", date!!.month + 1)}.${String.format("%02d", date!!.date)}.${date.year + 1900}")
val title: String? = ("$transformedDate")

val longGmtTime = date.time
val mZone = TimeZone.getDefault()
val offset = mZone.getOffset(longGmtTime)
val longLocalTime = longGmtTime + offset - (9 * HOUR)

val localDate = Date() // local date
localDate.time = longLocalTime
val localFormatTime = formatter.format(localDate)
val transformedLocalDate = ("${String.format("%02d", localDate!!.month + 1)}.${String.format("%02d", localDate!!.date)}.${localDate.year + 1900}")

And it gives me server time: 2019-06-24 16:15:31 -> 06.24.2019, local time(Asia/Seoul)-> 2019-06-25 01:15:30 ->06.25.2019 for the result.

The server time and local time must be the same. But the local time shows somewhere else.

What's the problem?

c-an
  • 3,543
  • 5
  • 35
  • 82
  • work in UTC and convert both? – Shark Jun 24 '19 at 09:38
  • What do you mean? – c-an Jun 24 '19 at 11:02
  • If you don't receive a timezone with your timestamp, you have to consider it to be in local time. – tynn Jun 24 '19 at 11:22
  • What is it you want to do? Isn’t `Mon Jun 24 16:15:31 GMT+09:00 2019` already local time? Do you need to do anything at all? (apart from considering the modern date and time API) – Ole V.V. Jun 24 '19 at 13:57
  • That's server time. And I want to convert it to local time. – c-an Jun 24 '19 at 13:59
  • Related: (1) [Java Date and utcTimeOffset [closed\]](https://stackoverflow.com/questions/51949842/java-date-and-utctimeoffset) (2) [Convert Time from one time zone to another using Java 8 Time](https://stackoverflow.com/questions/29962770/convert-time-from-one-time-zone-to-another-using-java-8-time) – Ole V.V. Jun 24 '19 at 17:09
  • I assume the downvotes are either because it’s not clear what you want or because the question seems poorly researched. I didn’t understand the question until I tried running your code myself and saw the results. And as hinted in my previous comment, there are similar questions and answers already that could probably have helped you before you asked your question (there are many more than the two I linked to). – Ole V.V. Jun 24 '19 at 17:53

2 Answers2

3

What's the problem?

The gross problem list includes:

  • You are using the poorly designed and long outdated Java date and time classes Date, TimeZone and SimpleDateFormat.
  • You are using the deprecated methods getMonth, getDate and getYear of the Date class. These methods work unreliably across time zone, which is the main reason why they were deprecated.
  • You are doing the time zone conversion manually using addition, subtraction and multiplication. Date and time math is error-prone, and you should always leave it to proven library methods.
  • The millisecond count you get from Date.getTime is since the epoch of 1970-01-01T00:00:00 UTC. This is a unique moment in time and independent of time zone, so adding to and subtracting from the millisecond count for time zone conversion makes no sense.
  • I can reproduce your result when I set my JVM’s default time zone to Asia/Seoul and assume that HOUR is 0 (or some value in the range from 0 through 111). I assume that you had wanted HOUR to denote the number of milliseconds in an hour, 3 600 000 (at least usually, exceptions exist).
  • You were formatting your date by concatenating the results of calls to Strirg.format. It’s better to leave formatting to a specialized date formatter.

The fix: java.time

    ZoneId serverTimeZone = ZoneId.of("Asia/Seoul");
    DateTimeFormatter serverFormatter = DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
    ZoneId clientTimeZone = ZoneId.systemDefault();

    String checkedDate = "2019-06-24 16:15:31";
    ZonedDateTime serverDateTime = LocalDateTime.parse(checkedDate, serverFormatter)
            .atZone(serverTimeZone);
    ZonedDateTime clientDateTime = serverDateTime.withZoneSameInstant(clientTimeZone);
    System.out.println("clientDateTime: " + clientDateTime);

Sorry that I can write and run only Java code, I trust you to translate. With my JVM’s time zone still set to Asia/Seoul I get:

clientDateTime: 2019-06-24T16:15:31+09:00[Asia/Seoul]

The server time and the client time are the same, as you requested. If instead I keep my own time zone, I get:

clientDateTime: 2019-06-24T09:15:31+02:00[Europe/Copenhagen]

So there is a conversion taking place.

To format the date:

    DateTimeFormatter displayFormatter = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
            .withLocale(Locale.forLanguageTag("ko-KR"));
    String transformedLocalDate = clientDateTime.format(displayFormatter);
    System.out.println("transformedLocalDate: " + transformedLocalDate);

transformedLocalDate: 2019. 6. 24.

Or if you insist on month.date.year:

    DateTimeFormatter displayFormatter = DateTimeFormatter.ofPattern("MM.dd.u");

transformedLocalDate: 06.24.2019

A further recommendation would be to have your server deliver a date-time string in UTC in ISO 8601 format. That would go like 2019-06-24T07:15:31Z for the moment used in the examples.

Question: Can I use java.time with minSdk API level 23 on Android?

Yes, java.time works nicely on older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
  • In Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • That way requires minSdk API 26. My minSdk is API 23. Is there any alternative way..? – c-an Jun 25 '19 at 01:41
  • 1
    It doesn’t require API level 26. With API level 23 it requires the ThreeTenABP library. Just read until the end of the answer. :-) – Ole V.V. Jun 25 '19 at 01:50
0

You should specify setup server timezone instead of you device (which is default)

Dmytro Batyuk
  • 957
  • 8
  • 15