0

I have the following date

2020-02-05T03:17:04.000Z

And I am trying to convert that to hour, and the result should be 22:17 but in my app I get 03:17

So, this is my code

public static String hour_visit(String hora){
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
        Date convertedDate = new Date();
        String fecha_convert = "";
        try {
            convertedDate = dateFormat.parse(hora);
            SimpleDateFormat sdfnewformat = new SimpleDateFormat("HH:mm");
            fecha_convert = sdfnewformat.format(convertedDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return fecha_convert;
    }

What am I doing wrong?

Important:

In my web app I get 22:17 My time zone is SouthAmerica

Shashanth
  • 4,995
  • 7
  • 41
  • 51
Israel
  • 121
  • 10
  • Isin't your code snippet from Swift? What code have you tried in Java/Kotlin? – omz1990 Feb 05 '20 at 03:54
  • let me change my code – Israel Feb 05 '20 at 03:55
  • nothings wrong with your code, at first format it was already in 03:17 and you just pull HH:mm which is still 03:17, double check your data. – L2_Paver Feb 05 '20 at 03:55
  • I chan ge my code to android/java – Israel Feb 05 '20 at 03:57
  • As an aside consider throwing away the long outmoded and notoriously troublesome `SimpleDateFormat` and friends, and adding [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP) to your Android project in order to use java.time, the modern Java date and time API. It is so much nicer to work with. – Ole V.V. Feb 05 '20 at 06:41
  • Does this answer your question? [ISO 8601 String to Date/Time object in Android](https://stackoverflow.com/questions/3941357/iso-8601-string-to-date-time-object-in-android) – Ole V.V. Feb 05 '20 at 06:43

4 Answers4

1

Searching in all internet post I resolved my problem adding this:

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Israel
  • 121
  • 10
1

java.time and ThreeTenABP

    DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");

    String instantString = "2020-02-05T03:17:04.000Z";

    Instant i = Instant.parse(instantString);
    ZonedDateTime dateTime = i.atZone(ZoneId.systemDefault());
    String fechaConvert = dateTime.format(timeFormatter);

    System.out.println("Converted time: " + fechaConvert);

I ran this snippet with my JVM time zone set to America/Guayaquil (Ecuador time) and got:

Converted time: 22:17

(Many other time zones are used in different parts of South America.)

Your string is in the ISO 8601 format for an instant (a point in time). Instant.parse() expects this format, so we need no explicit formatter for parsing.

The date and time classes that you were trying to use, SimpleDateFormat and Date, are poorly designed and long outdated, the former in particular notoriously troublesome. Instead I am using java.time, the modern Java date and time API. I frankly find it a lot nicer to work with.

What went wrong in your code?

One of the many confusing traits of SimpleDatFormat is that it is happy only to parse as much of the given string as it can and tacitly ignore the rest. The Z in your string tells us that the date and time is in UTC, but your SimpleDateFormat ignores this crucial fact. It therefore parses the date and time as though they were in your own time zone. The second SimpleDateFormat instance then formats the wrong time back and gives you the time that was in the string, 03:17 (in this example).

As Andreas said, from API level 24 SimpleDateFormat can correctly parse the Z. On lower API levels it cannot. In contrast java.time has been backported and works on lower API levels too.

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 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
0

Your SimpleDateFormat pattern is missing an X at the end, so it correctly parses the Z at the end of the input.

Test

String hora = "2020-02-05T03:17:04.000Z";
Date convertedDate = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX").parse(hora);
System.out.println(new SimpleDateFormat("HH:mm").format(convertedDate));

Output (in US Eastern time zone)

22:17

UPDATE

Since pattern X requires API Level 24+ in Android, and patterns Z and z don't support the Z zone suffix in the date string, the alternative is to force input to have Z and force parser to use UTC time zone for parsing.

Test

String hora = "2020-02-05T03:17:04.000Z";

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date convertedDate = dateFormat.parse(hora);

SimpleDateFormat sdfnewformat = new SimpleDateFormat("HH:mm");
System.out.println(sdfnewformat.format(convertedDate));

Output (in US Eastern time zone)

22:17
Andreas
  • 154,647
  • 11
  • 152
  • 247
0

Try this

Put your time in a string then split it

String full_dat_tym_buy = "2020-02-05T03:17:04.000Z";
String[] spiltby_T_buy = full_dat_tym_buy.split("T");
date_buy = spiltby_T_buy[0].trim();
String tym_wid_Z_buy = spiltby_T_buy[1].trim();
String spiltby_Dot1_buy = tym_wid_Z_buy.replace(".000Z", "");
replace_tym_buy = spiltby_Dot1_buy.replace(":", "-");
Log.e("replacetime", replace_tym_buy);

then format your date using time zone try

{

String FinalDate = getOnlyDate( replace_tym_buy);
Log.e("difference", String.valueOf(FinalDate));


} catch (Exception exception) {

}

Add this method in your class

private String getOnlyDate(String OurDate_) {
String chk_date = OurDate_;
Log.e("datededde", chk_date);
try {
    SimpleDateFormat formatter = new SimpleDateFormat("HH-mm-ss");
    formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
    Date value = formatter.parse(OurDate_);

    SimpleDateFormat dateFormatter = new SimpleDateFormat("HH:mm"); //this format changeable
    Log.e("time: ", TimeZone.getDefault() + "");
    dateFormatter.setTimeZone(TimeZone.getDefault());
    OurDate_ = dateFormatter.format(value);
    Log.e("OurDate_", OurDate_);
} catch (Exception e) {
    OurDate_ = chk_date;
}
return OurDate_;

}
Apps Maven
  • 1,314
  • 1
  • 4
  • 17