1

I am getting date and time from JSON API URL which format is like this

    '2021-03-05 09:18:07' which is in String form.

but when I want to convert it in milliseconds it gives me an error of index 10. I don't know why this issue is coming I check other Stackoverflow answer but did not successed

  DateTimeFormatter formatter ;
                                if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
                                    formatter = DateTimeFormatter.ofPattern(
                                            "yyyy-MM-dd'T'HH:mm:ss", Locale.ROOT);
                                    String dates = object.getString("created_at");
                                   long  timeInMilliseconds = OffsetDateTime.parse(dates, formatter)
                                            .toInstant()
                                            .toEpochMilli();
                                    System.out.println("Date in milli :: USING ThreeTenABP >>> " + 
                                   timeInMilliseconds);

                                }
                                String text = TimeAgo.using(timeInMilliseconds);
                                FeedModel.setDateSnap(text);

and here is error

     java.time.format.DateTimeParseException: Text '2021-03-05 09:18:07' could not be parsed: Unable 
     to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2021-03-05T09:18:07 of type 
     java.time.format.Parsed
    at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855)
    at java.time.OffsetDateTime.parse(OffsetDateTime.java:396)
    at com.example.wasigram.MainActivity$1.onResponse(MainActivity.java:91)
    at com.androidnetworking.common.ANRequest.deliverSuccessResponse(ANRequest.java:729)
    at com.androidnetworking.common.ANRequest.access$6500(ANRequest.java:80)
    at com.androidnetworking.common.ANRequest$6.run(ANRequest.java:709)
    at android.os.Handler.handleCallback(Handler.java:888)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:213)
    at android.app.ActivityThread.main(ActivityThread.java:8178)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
 Caused by: java.time.DateTimeException: Unable to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2021-03-05T09:18:07 of type java.time.format.Parsed
    
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Adnan haider
  • 553
  • 8
  • 21

2 Answers2

2

Using Java SE 8 API:

You can use DateTimeFormatter#withZone to get a formatter with the specified zone.

Also, use the correct format, yyyy-MM-dd HH:mm:ss which does not have 'T' which you have put in your pattern by mistake. In fact, I prefer using u to y as explained in this answer.

Demo:

import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2021-03-05 09:18:07";
        
        DateTimeFormatter formatter = DateTimeFormatter
                                        .ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH)
                                        .withZone(ZoneOffset.UTC);
        
        long millis = OffsetDateTime
                        .parse(strDateTime, formatter)
                        .toInstant()
                        .toEpochMilli();
        
        System.out.println(millis);
    }
}

Output:

1614935887000

Learn more about the modern date-time API from Trail: Date Time.

Using ThreeTen-Backport API:

import java.util.Locale;

import org.threeten.bp.LocalDateTime;
import org.threeten.bp.ZoneOffset;
import org.threeten.bp.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        String strDateTime = "2021-03-05 09:18:07";
        
        DateTimeFormatter formatter = DateTimeFormatter
                                        .ofPattern("uuuu-MM-dd HH:mm:ss", Locale.ENGLISH);
        
        long millis = LocalDateTime
                        .parse(strDateTime, formatter)
                        .toInstant(ZoneOffset.UTC)
                        .toEpochMilli();
        
        System.out.println(millis);
    }
}

Output:

1614935887000
Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110
0

You’ve got two issues:

  1. Your format pattern string does not exactly match your string from JSON.
  2. You cannot naïvely parse a stirng that doesn’t contain a UTC offset into an OffsetDateTime.

The format pattern string

Index 10 in your string 2021-03-05 09:18:07 is where the space after the day of month is. So let’s look at your format pattern to see what is expected to come after the day of month. Your format pattern string is yyyy-MM-dd'T'HH:mm:ss, and after the day of month comes 'T', which means a literal T, that is, the T is not a pattern letter. Your exception comes because a T and a space are not equal.

A tip for parsing problems: When you cannot see what’s wrong in parsing, try formatting first.

    String dates = "2021-03-05 09:18:07";
    DateTimeFormatter formatter 
            = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss", Locale.ROOT);
    
    OffsetDateTime expectedResult
            = OffsetDateTime.of(2021, 3, 5, 9, 18, 7, 0, ZoneOffset.ofHours(1));
    
    System.out.println("Parsing:   " + dates);
    System.out.println("Formatted: " + expectedResult.format(formatter));

Output is:

Parsing:   2021-03-05 09:18:07
Formatted: 2021-03-05T09:18:07

I hope that it’s now easier to see the difference between the space in your string and the T in the string that the formatter expects.

You may have figured the solution out already: in the format pattern string put a space instead of 'T' (if you like, you can put the space in single quotes, but it’s not necessary).

Parsing into an OffsetDateTime

This fix still fails:

    // Put a space in the format pattern string
    DateTimeFormatter formatter 
            = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
    
    OffsetDateTime odt = OffsetDateTime.parse(dates, formatter);

Exception in thread "main" java.time.format.DateTimeParseException: Text '2021-03-05 09:18:07' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {},ISO resolved to 2021-03-05T09:18:07 of type java.time.format.Parsed

Funnily this is also the exception in the stack trace in your question.

An OffsetDateTime must contain an offset from UTC, and Java has got no place to get it from. Do you know which time zone is assumed by the API that you got the string from? If so, use it. My suggestion is:

    ZoneId zoneAssumedByApi = ZoneId.of("Antarctica/Troll");
    long  timeInMilliseconds = LocalDateTime.parse(dates, formatter)
            .atZone(zoneAssumedByApi)
            .toInstant()
            .toEpochMilli();
    System.out.println("Date in milli :: USING ThreeTenABP >>> "
            + timeInMilliseconds);

Date in milli :: USING ThreeTenABP >>> 1614935887000

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • i have got from server which i show you in my answer so what can i do after that without UTC' – Adnan haider Mar 06 '21 at 12:23
  • Well, I am sorry, if you don’t know whether the server uses Pacific/Auckland, UTC or Pacific/Pago_Pago time zone, then you cannot convert the date and time to milliseconds since the epoch. 2021-03-05 09:18:07 falls in a time span of some 24 or 26 hours depending on the time zone it is in. – Ole V.V. Mar 06 '21 at 12:32
  • atzone show error but atZoneSimilarLocal and atZoneSameInstant which one choose? – Adnan haider Mar 06 '21 at 12:36
  • Usually `atZoneSameInstant()`, but it depends on the context and the requirements. Did you remember `LocalDateTime.parse` rather than `OffsetDateTime`? – Ole V.V. Mar 06 '21 at 13:00