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:
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.
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.
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.
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.
To obtain an old-fashioned Date
object for TimeAgo
, convert like this:
Date newDate = DateTimeUtils.toDate(newDateTime.toInstant());
java.time
.java.time
was first described.java.time
to Java 6 and 7 (ThreeTen for JSR-310).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));