-1

I am working on server and server is sending me date on GMT Local Date like Fri Jun 22 09:29:29 NPT 2018 on String format and I convert it into Date like below:

SimpleDateFormat simpleDateFormat=new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy",Locale.English);
Date newDate=simpleDateFormat.parse("Fri Jun 22 09:29:29 NPT 2018");
TimeAgo ta=new TimeAgo();
Log.d(TAG,""+ta.timeAgo(newDate));

What I need is take out the Time in Ago like 5 hours ago for that I use the one github project on which returns TimeAgo on passing date.

I have already look at this answer but didn't solve my problem.

Exception: Err java.text.ParseException: Unparseable date: "Fri Jun 22 09:29:29 NPT 2018" (at offset 20) Err java.text.ParseException: Unparseable date: "Fri Jun 22 09:29:29 NPT 2018" (at offset 20)

Queendevelopers
  • 183
  • 3
  • 20
  • Possible duplicate of [Java string to date conversion](https://stackoverflow.com/questions/4216745/java-string-to-date-conversion) – deHaar Jun 22 '18 at 06:59
  • @ScaryWombat sorry bro, that was my mistake.. It was few lines on code of I wrote it instead of copy and paste. Now please look at it. I am from Nepal so NPT means Nepali Time – Queendevelopers Jun 22 '18 at 07:05
  • ohh yes, that was a silly mistake! Shit! – Debadatta Jun 22 '18 at 07:14
  • 1
    I can't reproduce the problem in Java 7. Are you sure this is the exact code you're running? – Dawood ibn Kareem Jun 22 '18 at 07:15
  • @DawoodibnKareem Yes this the exact code I am using – Queendevelopers Jun 22 '18 at 07:18
  • Then I have no idea. Although I wonder if something about your environment isn't recognising the NPT zone. Does it work if you put in a more commonly used time zone instead? (I'm not suggesting that as a solution; just as a way of investigating what the problem might be). – Dawood ibn Kareem Jun 22 '18 at 07:24
  • Works OK even on ideone.com – Scary Wombat Jun 22 '18 at 07:27
  • Please humour me. Clean out your build directory and recompile it. Just to make sure. – Dawood ibn Kareem Jun 22 '18 at 07:27
  • @DawoodibnKareem Did sync > Clean Project > Rebuild Project and Run but still same error. – Queendevelopers Jun 22 '18 at 07:39
  • @DawoodibnKareem Just to make sure just tried as you mentioned above, changing NPT to AET and CEST , different Timezone America Eastern Time and Central Europe Time. – Queendevelopers Jun 22 '18 at 07:42
  • Then I have no more ideas. As I said, your code works fine for me, in Java 7. I don't have an actual Android environment to try it out in, but I've been browsing the Android documentation and I can't find any reason for it not to work. – Dawood ibn Kareem Jun 22 '18 at 08:04
  • Also related: [How to convert Date.toString back to Date?](https://stackoverflow.com/questions/9431927/how-to-convert-date-tostring-back-to-date) – Ole V.V. Jun 22 '18 at 08:11
  • @OleV.V. already tried with Locale.English not working – Queendevelopers Jun 22 '18 at 08:13
  • Thanks for the information. It’s weird. On my computer your date string parses into `Fri Jun 22 05:44:29 CEST 2018`. Could you post your stacktrace in the question (format as code for readability). And if you can catch a `ParseException`, then also include the result of calling its `getErrorOffset` method? Thx. – Ole V.V. Jun 22 '18 at 08:17
  • 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, as @notyou suggested. It is so much nicer to work with. ThreeTenABP is for API levels lower than 26 (Android O). – Ole V.V. Jun 22 '18 at 08:21
  • Getting offset at 20. see the updated log above. – Queendevelopers Jun 22 '18 at 08:22
  • Offset 20. So `NPT` is the issue. Now we’re getting somewhere. I have retracted my close vote. – Ole V.V. Jun 22 '18 at 08:23
  • @OleV.V. What would be causing the problem? – Queendevelopers Jun 22 '18 at 08:25

2 Answers2

2

The Date class is predominantly deprecated, so I would suggest not to use that.

Perhaps consider using something like the ZonedDateTime class for your problem.

If you're just looking for 5 hours before the String sent over to you, you could use something like:

String time = "Fri Jun 22 09:29:29 NPT 2018";
DateTimeFormatter format = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz uuuu");
ZonedDateTime zdt = ZonedDateTime.parse(time, format);
System.out.println(zdt.minusHours(5));
achAmháin
  • 4,176
  • 4
  • 17
  • 40
  • 1
    Is it Deprecated on Android? – Scary Wombat Jun 22 '18 at 07:22
  • Do wombats dance in the treetops? – Dawood ibn Kareem Jun 22 '18 at 07:28
  • @ScaryWombat AFAIK, most of the methods and constructors are. – achAmháin Jun 22 '18 at 07:29
  • This DateTimeFormatter.ofPattern() require Android O. so, this is totally useless for now. – Queendevelopers Jun 22 '18 at 07:30
  • OP is not trying to use any of the deprecated methods or constructors of the `Date` class. The fact that many of the methods are deprecated is entirely irrelevant to why OP's code won't work. There's no point in adding in the JSR310 library just to do something that SimpleDateFormat _ought_ to be able to do. – Dawood ibn Kareem Jun 22 '18 at 07:30
  • @DawoodibnKareem fair enough; I failed in assuming it was fully deprecated when I wrote the answer. Perhaps a newer class would suit better anyway in the long run, but I see from a separate comment that they require a later version of Android anyway. – achAmháin Jun 22 '18 at 07:33
  • @DawoodibnKareem *Do wombats dance in the treetops?* You know they do David, I have seen you looking up my skirt. – Scary Wombat Jun 22 '18 at 07:39
  • Are you sure that wasn't Eerie Platypus? – Dawood ibn Kareem Jun 22 '18 at 07:50
  • While not officially deprecated (at least not yet), the `Date` class is long outmoded. `SimpleDateFormat` too and notoriously troublesome. +1. `java.time`, the modern Java date and time API used in this answer, works nicely on Android earlier than Android O when you add [ThreeTenABP](https://github.com/JakeWharton/ThreeTenABP) to your project. – Ole V.V. Jun 22 '18 at 10:42
2

NPT is not recognized as a time zone abbreviation

The parsing of your date-time string (apparently the output from Date.toString()) is the problem (not the subsequent use of TimeAgo, which you could have left out from the question to make it clearer). The unparseable part is at index 20, that is where it says NPT, which I take to mean Nepal Time. So SimpleDateFormat on your Android device or emulator doesn’t recognize NPT as a time zone abbreviation.

Time zone abbreviations come as part of the locale data. I am not an Android developer and don’t know from where Android gets its locale data. A fast web search mentioned ICU and CLDR. You can search more thoroughly and no doubt find information I didn’t find.

I am presenting three suggestions for you to try. I admit at once that the first two are unlikely to solve your problem, but I nevertheless find them worth trying. And I promise that the third will work if the first two don’t.

1. Use ThreeTenABP and java.time

I agree with the answer by notyou that the classes Date and SimpleDateFormat are outmoded and that it’s better to use java.time, the modern Java date and time API. Can you do that on Android prior to Android O? Yes, most of java.time has been backported. The Android edition of the backport is called ThreeTenABP. Use the links at the bottom. Then try:

    DateTimeFormatter formatter 
            = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ROOT);
    ZonedDateTime newDateTime
            = ZonedDateTime.parse("Fri Jun 22 09:29:29 NPT 2018", formatter);
    System.out.println(newDateTime);

Make sure you use the imports for the backport:

import org.threeten.bp.ZonedDateTime;
import org.threeten.bp.format.DateTimeFormatter;

I have tested with the same backport, only not the Android edition. I got:

2018-06-22T09:29:29+05:45[Asia/Kathmandu]

I suspect that ThreeTenABP uses the same locale data, though, and if so, this doesn’t solve your problem.

2. Set the time zone on the formatter

    DateTimeFormatter formatter = DateTimeFormatter
            .ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ROOT)
            .withZone(ZoneId.of("Asia/Kathmandu"));

If it works, I find it straightforward and clean. If you insist on using SimpleDateFormat, you can try a similar trick with it. I get the same output as above.

3. Handle NPT as literal text

This is a hack: require that the three letters NPT occur in the string without interpreting them as a time zone. This eliminates the need for the abbreviation to be recognized as a time zone, so will work.

    DateTimeFormatter formatter = DateTimeFormatter
            .ofPattern("EEE MMM dd HH:mm:ss 'NPT' yyyy", Locale.ROOT)
            .withZone(ZoneId.of("Asia/Kathmandu"));

We also need to set the time zone since this is now the only place Java can get the time zone from.

But TimeAgo requires a Date

To obtain an old-fashioned Date object for TimeAgo, convert like this:

    Date newDate = DateTimeUtils.toDate(newDateTime.toInstant());

Links

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
  • Thanks for your answer, and you don't have android environment to test the code. If you have noticed my comment below on @notyou answer, The DateTimeFormatter class needs API Version 26 (Android O) which is the latest version of Android. If I implement this code in my project only Android Phone with version Oreo will get it work, and all before versions will failed. I am using minSDK to 16 (Api 16 kitkat) to MaxSDK Oreo (26 Oreo ) so, I think this will not be perfect solution for upcoming 4-5 years. – Queendevelopers Jun 22 '18 at 16:39
  • I did read that comment. It seems you didn’t read my answer properly? At least I *tried* to explain how my code will work on older Android devices. The ThreeTenABP that I suggest you use is exactly meant for Android versions prior to Oreo. And in particular if you want to think, say, 4 years ahead, I should say that I present the future-proof way to go. – Ole V.V. Jun 22 '18 at 16:54
  • Really appreciated your answer and time man. Finally, I made it work. I love your Hack. ^_^ . The 1 and 2 steps in not working for me as you said above, but the 3rd step is perfect. I was struggling from this problem from 3 days finally, you saved my life. – Queendevelopers Jun 22 '18 at 17:59