Convert Human Date (local Time Gmt) To Date
Solution 1:
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:
DateTimeFormatterformatter= DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ROOT);
ZonedDateTimenewDateTime= 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
DateTimeFormatterformatter= 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.
DateTimeFormatterformatter= 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:
DatenewDate= DateTimeUtils.toDate(newDateTime.toInstant());
Links
- Oracle tutorial: Date Time explaining how to use
java.time
. - Java Specification Request (JSR) 310, where
java.time
was first described. - ThreeTen Backport project, the backport of
java.time
to Java 6 and 7 (ThreeTen for JSR-310). - ThreeTenABP, Android edition of ThreeTen Backport
- Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Solution 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));
Post a Comment for "Convert Human Date (local Time Gmt) To Date"