-3

I am developing an android application. What should I do to get the current time based on Turkish local time?

val now = Calendar.getInstance(TimeZone.getTimeZone("GMT+3"))

the result is:

2020-08-25T18:16:30

but this website result is different: https://www.timeanddate.com/worldclock/turkey/istanbul

2020-08-25T16:46:30

The output is printed using the following code snippet:

DebugHelper.info("one now => ${now.getDisplayMonthNameDayTime(FULL_PATTERN)}")

Extention Function:

const val FULL_PATTERN = "yyyy-MM-dd'T'HH:mm:ss"

fun Calendar.getDisplayMonthNameDayTime(pattern: String = "dd MMM , HH:mm ") = SimpleDateFormat(
    pattern,
    Locale.getDefault()
).format(time).toUpperCase(Locale.getDefault())

Vahid Garousi
  • 546
  • 4
  • 17
  • **Read the documentation**, i.e. the javadoc of [`Calendar`](https://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html), which clearly lists a [`getInstance(TimeZone zone)`](https://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html#getInstance-java.util.TimeZone-) method. – Andreas Aug 25 '20 at 13:25
  • I have definitely read it, but there was a problem that I asked you dear ones .. Thank you for your patience in the face of my little knowledge. – Vahid Garousi Aug 25 '20 at 13:33
  • @Andreas You are right, sorry – Vahid Garousi Aug 25 '20 at 13:49
  • 1
    *"the result is"* How did you get that result? Simply printing the `Calendar` object doesn't show that specific string. – Andreas Aug 25 '20 at 14:01
  • @Andreas please check again – Vahid Garousi Aug 26 '20 at 05:32
  • 1
    `getDisplayMonthNameDayTime` doesn't set a time zone on the `SimpleDateFormat` it creates, so it works as-if you had called `setTimeZone(TimeZone.getDefault())`, similar to how you unnecessarily use `Locale.getDefault()`. I don't know Kotlin, so I'm unsure whether `time` refers is the `protected long` field or the `Date getTime()` method, but in either case the value doesn't carry time zone information, so it loses the `TimeZone` assigned to the `Calendar`. Which means that the output is **always in the *default* time zone** of the JVM running the code, regardless of the Calendar's time zone. – Andreas Aug 26 '20 at 10:33

3 Answers3

3

If you want to use a modern and less troublesome API, then use java.time, especially java.time.ZonedDateTime.

See this minimal example:

public static void main(String[] args) {
    ZonedDateTime istanbulDateTime = ZonedDateTime.now(ZoneId.of("Europe/Istanbul"));
    System.out.println(istanbulDateTime);
}

Output (some seconds ago):

2020-08-25T16:32:56.069+03:00[Europe/Istanbul]

As an alternative, there is ZoneId.of("Asia/Istanbul"), too, but the values only differ in the description of the continent. Just a matter of taste, I think.

EDIT
After your edit I realized you aren't relying on a time zone but rather an offset. That brings in another alternative from java.time, that is java.time.OffsetDateTime.

For the sake of completeness, here's a possible solution which only takes a ZoneOffset without the need to provide a zone by String:

public static void main(String[] args) {
    OffsetDateTime utcPlusThreeDateTime = OffsetDateTime.now(ZoneOffset.ofHours(3));
    System.out.println(utcPlusThreeDateTime);
}

which output (a few seconds ago)

2020-08-25T16:53:14.490+03:00

... and yes, since there's API desugaring in Android, you can use it with a suitable gradle plugin.

deHaar
  • 17,687
  • 10
  • 38
  • 51
  • thank you. I can use this method. my minimum sdk is 21 – Vahid Garousi Aug 25 '20 at 13:51
  • 2
    I'd go with the ZDT - makes it more future-proof in case Turkey's timezone changes in future, or if they reintroduce daylight savings (they abolished it in 2016). – darrengorman Aug 25 '20 at 14:04
  • 1
    @darrengorman totally agree, but OP obviously tried it himself with an offset, that's why I added the solution using `OffsetDateTime` and `ZoneOffset`. – deHaar Aug 25 '20 at 14:06
1

The solution

Use ZoneId.of("Asia/Istanbul") and a ZonedDateTime from java.time, the modern Java date and time API, as demonstrated in the answer by deHaar.

The problem

You problem is in this line:

).format(time).toUpperCase(Locale.getDefault())

time gives you the time of the Calendar object as a Date (another poorly designed and long outdated class that we should not use anymore). A Date hasn’t got any time zone, so the time zone and offset information from the Calendar is lost. So when you format this Date, you are using the time zone of the SimpleDateFormat, not the time zone of the Calendar.

Your Calendar’s time zone was GMT+03:00 alright. As others have mentioned, you should prefer Europe/Istanbul or Asia/Istanbul, though.

Links

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

Turkey have an issue with real time in java...

you need to do you own hack with GMT+03

TimeZone.getTimeZone("GMT+03")

code:

TimeZone timeZone = TimeZone.getTimeZone("GMT+03");
Calendar calendar = Calendar.getInstance(timeZone);