0

I'm stuck with the daylight problem in android the time should be +3 GMT/UTC but I'm getting only +2. is there any solution or I can't handle it? please find below my code

  TimeZone.getDefault().useDaylightTime();
  SimpleDateFormat df = new SimpleDateFormat("HH:mm",Locale.ENGLISH); //"2021-02-18T11:00:00"
        df.setTimeZone(TimeZone.getTimeZone("UTC"));
        return df.format(calendar.getTime());

Note that the DST OFFSET is returning zero. what should I do to handle daylight? Another note my time is Jordan / Amman, In winter this should return +2 but in summer it should return +3

Basil Battikhi
  • 2,638
  • 1
  • 18
  • 34
  • 1
    I recommend you don’t use `TimeZone`, `SimpleDateFormat` and `Calendar`. Those classes are poorly designed and long outdated, `SimpleDateFormat` in particular notoriously troublesome. Instead use `ZoneId` and `LocalTime`, both from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. May 28 '21 at 16:13
  • Switch to `java.time` API. For any reason, if you have to stick to Java 6 or Java 7, you can use [***ThreeTen-Backport***](http://www.threeten.org/threetenbp/) which backports most of the *java.time* functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check [Java 8+ APIs available through desugaring](https://developer.android.com/studio/write/java8-support-table) and [How to use ThreeTenABP in Android Project](https://stackoverflow.com/questions/38922754/how-to-use-threetenabp-in-android-project). – Arvind Kumar Avinash May 28 '21 at 16:38
  • @OleV.V. Thank you for the suggesstion but actually the old android devices don't support java 8 – Basil Battikhi May 28 '21 at 16:45
  • @BasilBattikhi Not directly, you are right. But as long as you're on Android Gradle plugin 4.0 or newer, with coreLibraryDesugaring you can use java.time directly. If you are not, use ThreeTen Backport as described in my answer below and in the links from there. – Ole V.V. May 28 '21 at 16:47

1 Answers1

2

java.time

Consider using java.time, the modern Java date and time API, for your date and time work. Let’s first declare a formatter for your desired time format:

private static final DateTimeFormatter TIME_FORMATTER
        = DateTimeFormatter.ofPattern("HH:mm", Locale.ENGLISH);

Now you may format the time from your Calendar in this way:

    // Assume you are getting a Calendar from somewhere
    Calendar calendar = new GregorianCalendar();
    
    ZonedDateTime dateTime = calendar.toInstant().atZone(ZoneId.systemDefault());
    String dateTimeString = dateTime.format(TIME_FORMATTER);
    
    System.out.println(dateTimeString);

I ran the code just now, that is, 16:33 in UTC or 19:33 in Jordan. The output was:

19:33

If you don’t depend on getting on old-fashioned Calendar from somewhere, it’s probably even simpler and cleaner. For example, to get the current time in your time zone:

    String timeString
            = LocalTime.now(ZoneId.systemDefault()).format(TIME_FORMATTER);
    System.out.println(timeString);

What went wrong in your code?

You set the time zone of your SimpleDateFormat to UTC. So the time in UTC was printed regardless of your default time zone. And since UTC hasn’t got summer time (DST), no such was taken into account.

BTW, this method call of yours does nothing:

    TimeZone.getDefault().useDaylightTime();

From the documentation:

Returns:

true if this TimeZone uses Daylight Saving Time, false, otherwise.

So the method does not alter anything and certainly not the UTC time zone. It only queries whether the mentioned time zone uses summer time (daylight saving time). So since the Asia/Amman time zone does, it should return true in your case.

Question: Doesn’t java.time require Android API level 26?

java.time works nicely on both 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 non-Android 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 either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • thank you for the answer as i said java 8 is not supported in old android devices so I can't use toInstant – Basil Battikhi May 28 '21 at 16:46
  • @BasilBattikhi Not directly, you are right. But as long as you're on Android Gradle plugin 4.0 or newer, with coreLibraryDesugaring you can use java.time directly. If you are not, use ThreeTen Backport as described in the answer and in the links. – Ole V.V. May 28 '21 at 16:48