Unparseable date: "Thu, 7 Dec 2017 07:40:40 " - java

I am getting the above exception while trying to parse. I tried the following date format,
SimpleDateFormat sdf = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss ", Locale.ENGLISH);

java.time
The SimpleDateFormat class is not only long outdated, it is also notoriously troublesome. I recommend you stop using it and use java.time the modern Java date and time API also known as JSR-310, instead. It is so much nicer to work with.
System.out.println(LocalDateTime.parse("Thu, 7 Dec 2017 07:40:40 ",
DateTimeFormatter.ofPattern("E, d MMM yyyy HH:mm:ss ", Locale.ENGLISH)));
This prints the expected date and time:
2017-12-07T07:40:40
What went wrong
In your format pattern string, you’ve got two spaces before and two spaces after yyyy, where it seems that in your date-time string there is only one space in each of those places. While SimpleDateFormat is infamous for parsing strings that it ought to reject, it does object in this case by throwing the ParseException the message of which you quote in the question title.
If you compare my format pattern string to yours, you will notice I use just one d where you use two. SimpleDateFormat parses 7 with dd where the modern classes are stricter: d matches a date-of-month of either 1 or 2 digits. where dd requires two digits. You may of course exploit this for stricter validation if you need it.
Question: Can I use the modern API with my Java version?
If using at least Java 6, you can.
In Java 8 and later the new API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the new classes (ThreeTen for JSR 310).
On Android, use the Android edition of ThreeTen Backport. It’s called ThreeTenABP, and there’s a thorough explanation in this question: How to use ThreeTenABP in Android Project.
For learning to use java.time, see the Oracle tutorial or find other resoureces on the net.

it seems working fine with space as well...what exception you get?
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class SimpleDateFormatExample {
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss ",Locale.ENGLISH);
String strDate= sdf.format(new Date());
System.out.println(strDate);
}
}
Ouput:Fri, 08 Dec 2017 07:54:08

Related

Converting dates time to other timezones

how to I convert date time to others time zone using java.
example : 11 June 2021 20:00 to 11 June 2021 06:00 PM
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
Date parsed = format.parse("2021-03-01 20:00");
*\\to//*
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm z");
Date parsed = format.parse("2021-03-01 06:00 PM");
like this
First of all you should use the new java 8 API for data and time, java.time, secondly you need to have a zone to convert to and from. Here I have assumed you want to use the zone of the device (and convert to GMT) as from and GMT as to.
String input = "2021-03-01 20:00";
DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").withZone(ZoneId.systemDefault());
DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd h:mm a").withZone(ZoneId.of("GMT"));
TemporalAccessor date = inputFormatter.parse(input);
String output = outputFormatter.format(date);
System.out.println(output);
Joakim Danielson is on to the right thing in his answer: use java.time, the modern Java date and time API, for your date and time work. My solution roughly follows the same overall pattern. There are some details I’d like to show you.
private static final DateTimeFormatter inputFormatter
= DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
private static final DateTimeFormatter outputFormatter
= DateTimeFormatter.ofPattern("yyyy-MM-dd h:mm a");
DateTimeFormatter is thread-safe so there’s no problem instantiating them only once even if they are used from different threads.
String input = "2021-03-01 20:00";
String output = LocalDateTime.parse(input, inputFormatter)
.atZone(ZoneId.systemDefault())
.withZoneSameInstant(ZoneOffset.UTC)
.format(outputFormatter);
System.out.println(output);
Output is the same as from Joakim’s code. In my time zone (Europe/Copenhagen) it is:
2021-03-01 7:00 PM
java.time lends itself well to a fluent writing style. Why not exploit it? Since conversion to a different time zone was the point, I prefer to make it explicit in the code. The withZoneSameInstant() call makes the conversion. And I prefer to parse into either LocalDateTime or ZonedDateTime rather than using the low-level TemporalAccessor interface directly. The documentation of the interface says:
This interface is a framework-level interface that should not be
widely used in application code. Instead, applications should create
and pass around instances of concrete types, such as LocalDate.
There are many reasons for this, part of which is that implementations
of this interface may be in calendar systems other than ISO. …
I need api 21 support. This is not available on api 21
Indeed java.time works nicely on Android API level 21.
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 either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from org.threeten.bp with subpackages.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Documentation of TemporalAccessor
Question: cannot resolve symbol 'java.time.LocalDate' error in android studio about using java.time on earlier Andoird
Question: Android - Date in API Level 21 [closed]
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).
Java 8+ APIs available through desugaring
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
You must get your date format to a specific zone, as you have not mentioned in the post, i will give 1 sample below,
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(yyyy-MM-dd HH:mm);
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Now using this simpleDateFormat for your specific timezone, you can format the value.
The key to the solution is to get the zone offset between two date-times which you can calculate with Duration#between and then change the zone offset of the first date-time into that of the second one (which is equal to the hours and minutes part of the calculated duration.
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
public class Main {
public static void main(String[] args) {
// Given date-time strings
String strOne = "11 June 2021 20:00";
String strTwo = "11 June 2021 06:00 PM";
// Respective formatters
DateTimeFormatter dtfOne = DateTimeFormatter.ofPattern("dd MMMM uuuu HH:mm", Locale.ENGLISH);
DateTimeFormatter dtfTwo = DateTimeFormatter.ofPattern("dd MMMM uuuu hh:mm a", Locale.ENGLISH);
// Respective instances of LocalDateTime
LocalDateTime ldtOne = LocalDateTime.parse(strOne, dtfOne);
LocalDateTime ldtTwo = LocalDateTime.parse(strTwo, dtfTwo);
// Duration between the two date-times
Duration duration = Duration.between(ldtOne, ldtTwo);
int hours = duration.toHoursPart();
int minutes = duration.toMinutesPart();
// Zone offset with hours and minutes of the duration
ZoneOffset zoneOffset = ZoneOffset.ofHoursMinutes(hours, minutes);
//
ZonedDateTime zdt = ldtOne.atZone(ZoneId.systemDefault()) // ZonedDateTime using JVM's time zone
.withZoneSameInstant(zoneOffset); // ZonedDateTime using the given zone offset
System.out.println(zdt);
String formatted = zdt.format(dtfTwo);// Format the given ZonedDateTime using the given formatter
System.out.println(formatted);
}
}
The date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API. Learn more about the modern date-time API at Trail: Date Time.
Note: If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

SimpleDateFormat shows wrong local Time

I want to store a string into a databse (SQLite) for an Android App with the current time and date. For that purpose I am using SimpleDateFormat. Unfortunately it does not show the correct time when. I tried two options.
First Option (from SimpleDateFormat with TimeZone)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z", Locale.getDefault());
sdf.format(new Date());
Second option (from Java SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'") gives timezone as IST)
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss'Z'");
sdf2.setTimeZone(TimeZone.getTimeZone("CEST"));
In both cases the time is just wrong. It is not the local time that my laptop or phone is showing but the output time is 2 hours earlier. How can I change that? I would like to have the current time of Berlin (CEST) that is also shown on my computer. I appreciate every comment.
Use Europe/Berlin instead of CEST and you will get the expected result.
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
sdf2.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
System.out.println(sdf2.format(new Date()));
}
}
Output:
2020-09-27 18:38:04 +0200
A piece of advice:
I recommend you switch from the outdated and error-prone java.util date-time API and SimpleDateFormat to the modern java.time date-time API and the corresponding formatting API (package, java.time.format). Learn more about the modern date-time API from Trail: Date Time. If your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
Using the modern date-time API:
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Europe/Berlin"));
// Default format
System.out.println(zdt);
// Some custom format
System.out.println(zdt.format(DateTimeFormatter.ofPattern("EEEE dd uuuu hh:mm:ss a z")));
}
}
Output:
2020-09-27T18:42:53.620168+02:00[Europe/Berlin]
Sunday 27 2020 06:42:53 pm CEST
The modern API will alert you whereas legacy API may failover:
import java.time.ZoneId;
import java.time.ZonedDateTime;
public class Main {
public static void main(String[] args) {
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("CEST"));
// ...
}
}
Output:
Exception in thread "main" java.time.zone.ZoneRulesException: Unknown time-zone ID: CEST
at java.base/java.time.zone.ZoneRulesProvider.getProvider(ZoneRulesProvider.java:279)
at java.base/java.time.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:234)
at java.base/java.time.ZoneRegion.ofId(ZoneRegion.java:120)
at java.base/java.time.ZoneId.of(ZoneId.java:408)
at java.base/java.time.ZoneId.of(ZoneId.java:356)
at Main.main(Main.java:6)
As you can see, you get an exception in this case whereas SimpleDateFormat will give you undesirable result as shown below:
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class Main {
public static void main(String[] args) {
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
sdf2.setTimeZone(TimeZone.getTimeZone("CEST"));
System.out.println(sdf2.format(new Date()));
}
}
Output:
2020-09-27 16:47:45 +0000
You might be wondering what this undesirable result refers to. The answer is: when SimpleDateFormat doesn't understand a time-zone, it failovers (defaults) to GMT (same as UTC) i.e. it has ignored CEST and applied GMT in this case (not a good feature IMHO 😊).
ISO 8601
Assuming that your SQLite hasn’t got a datetime datatype I recommend that you use ISO 8601 format, the international standard, for storing your date-times as strings to SQLite. Next, consider using java.time, the modern Java date and time API, for your date and time work. The two suggestions go nicely hand in hand. Common recommendations say to store date and time in UTC, but I understand that you prefer Europe/Berlin time.
ZoneId databaseTimeZone = ZoneId.of("Europe/Berlin");
ZonedDateTime now = ZonedDateTime.now(databaseTimeZone);
String databaseTime = now.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
System.out.println(databaseTime);
Output from the above when running just now:
2020-09-27T15:54:21.53+02:00
I have on purpose included the offset from UTC in the string. This will allow anyone retrieving the string to convert the time to UTC or the time zone of their preference. If the user travels to India to see Taj Mahal and retrieves the data there, converting to India Standard Time is no problem. The offset also disambiguates times in the night in October when Berlin changes from summer time (DST) to standard time and the same clock times repeat. Times before the change will have offset +02:00, times after the change will have +01:00.
How can I change the format(?)
Edit: If you insist on your own format for information and human readability, build a formatter for that. The ZonedDateTime already has the time in your chosen time zone, so that time is also the one you will have when you format it:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss Z");
String databaseTime = now.format(formatter);
Now the result is:
2020-09-27 16:22:23 +0200
Further edit: Since human readability is the only requirement for that column, go all-in on that and use java’s predefined localized format, for example:
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG)
.withLocale(Locale.GERMAN);
September 2020 19:06:03 MESZ
If it’s too long for you, use FormatStyle.MEDIUM instead.
Further further edit: And why? The question is whether 27. September 2020 19:06:03 MESZ is easier to read and understand correctly than 2020-09-27 16:22:23 +0200. You should make it as easy for yourself as you reasonably can. There is a point in including the offset, +0200, though, since it is unambiguous whereas a time zone abbreviation like MESZ is not guaranteed to be (many time zone abbreviations are ambiguous).
What went wrong in your code?
You are probably running your code on a computer with its time zone set to UTC (or some other time zone that is currently two hours behind Berlin time). In your second snippet you are trying to make up for this fact by setting the time zone of you formatter to CEST (Central European Summer Time). The way you are doing that is not what you want, and it also does not work. Both have to do with the fact that CEST is not a time zone. CEST is two hours ahead of UTC, and if it had worked, you would have got two hours ahead of UTC also during the standard time of year where Berlin is only 1 hour ahead of UTC, that is, the wrong time. Since CEST is not a time zone, TimeZone does not recognize it as a time zone. And this is as confusing as the TimeZone class is: instead of objecting, it tacitly gives you GMT, so you have got nowhere. I really recommend avoiding using that class. The correct time zone identifier for Berlin is Europe/Berlin, the one I am also using in my code. Time zone identifiers come in the region/city format.
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 either use desugaring or the Android edition of ThreeTen Backport. It’s called ThreeTenABP. In the latter case make sure you import the date and time classes from org.threeten.bp with subpackages.
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).
Java 8+ APIs available through desugaring
ThreeTenABP, Android edition of ThreeTen Backport
Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.
Wikipedia article: ISO 8601
Well, i faced the same issue a week ago and I figured out that the problem is in the TimeZone settings
If you are getting the date as a string and you need to format it to another format use the code below
public String getCalendarDate(String inputDate){
Date date = getDateFromSource(inputDate);
SimpleDateFormat formatter = new SimpleDateFormat("EEEE, d MMMM yyyy", Locale.getDefault());
formatter.setTimeZone(TimeZone.getDefault());
return formatter.format(date);
}
Date getDateFromSource(String apiDate){
Date newFormattedDate = null;
SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH);
parser.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
newFormattedDate = parser.parse(apiDate);
} catch (ParseException e) {
e.printStackTrace();
}
return newFormattedDate;
}
In the getDateFromSource function change the date format to the source format, while in the getCalendarDate function, change the format to your required format.
If you already have the Date object, you can ignore the getDateFromSource function and put it directly in the second one
For those who use Kotlin this is the equivalent code
fun getCalendarDate(apiDate: String): String{
val date = getDateFromApi(apiDate)
val formatter = SimpleDateFormat("EEEE, d MMMM yyyy", Locale.getDefault())
formatter.timeZone = TimeZone.getDefault()
return formatter.format(date)
}
private fun getDateFromApi(apiDate: String) :Date{
val parser = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH)
parser.timeZone = TimeZone.getTimeZone("UTC")
return parser.parse(apiDate)!!
}

SimpleDateFormat Parsing on Android [duplicate]

This question already has answers here:
Java - Unparseable date
(3 answers)
Getting error java.text.ParseException: Unparseable date: (at offset 0) even if the Simple date format and string value are identical
(4 answers)
Closed 4 years ago.
I am trying to parse the following date/time:
Wed, 29 Aug 2018 12:56:00 +0200
Currently, I am using the following code which works on my Android emulator but on my actual phone I get a "java.text.ParseException: Unparseable date"
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");
this.pubDate = sdf.parse(s_pubDate);
You need to explicitly set the formatter locale, otherwise it would try to pars it based on phone locale and that may cause an error. I think that the cause in your case.
Your emulated device has one locale, while your phone has the one, that can't pars date in such format.
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z",
**YOUR DESIRED LOCALE**);
java.time
String dateTimeString = "Wed, 29 Aug 2018 12:56:00 +0200";
OffsetDateTime dateTime = OffsetDateTime.parse(
dateTimeString, DateTimeFormatter.RFC_1123_DATE_TIME);
System.out.println(dateTime);
Output from this snippet is:
2018-08-29T12:56+02:00
The format of the string you want to parse is RFC 1123. This format is built into Java, so spares you the trouble of building your own formatter for parsing. Furthermore RFC 1123 is always in English, so there is no risk that your phone’s default locale (or any other locale) interferes.
I am using java.time, the modern Java date and time API. The SimpleDateFormat that you tried to use is not only long outdated, it is also notoriously troublesome.
Question: Can I use java.time on Android?
Yes, java.time works nicely on 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, I’m told) the modern API comes built-in.
In Java 6 and 7 get the ThreeTen Backport, the backport of the new 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
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.

Convert Human Date (Local Time GMT) to date

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)
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
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.timeto 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.
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));

Getting a weird exception Unparseable date: "6 Aug 2012"

I got a date time format - "dd MMM yyyy", when trying to parse "6 Aug 2012", I get an java.text.ParseException Unparseable date.
Every thing looks fine, do you see the problem?
You need to mention the Locale as well...
Date date = new SimpleDateFormat("dd MMMM yyyy", Locale.ENGLISH).parse("6 Aug 2012");
Use something like:
DateFormat sdf = new SimpleDateFormat("dd MMM yyyy", Locale.ENGLISH);
Date date = sdf.parse("6 Aug 2012");
Use the split() function with the delimiter " "
String s = “6 Aug 2012”;
String[] arr = s.split(" ");
int day = Integer.parseInt(arr[0]);
String month = arr[1];
int year = Integer.parseInt(arr[2]);
This should work for you. You will need to provide a locale
Date date = new SimpleDateFormat("dd MMM yyyy", Locale.ENGLISH).parse("6 Aug 2012");
Or
Date date = new SimpleDateFormat("dd MMM yyyy", new Locale("EN")).parse("6 Aug 2012");
While the other answers are correct but outdated and since this question is still being visited, here is the modern answer.
java.time and ThreeTenABP
Use java.time, the modern Java date and time API, for your date work. This will work with your Android version/minSDK:
DateTimeFormatter dateFormatter
= DateTimeFormatter.ofPattern("d MMM uuuu", Locale.ENGLISH);
String str = "6 Aug 2012";
LocalDate date = LocalDate.parse(str, dateFormatter);
System.out.println(date);
Output:
2012-08-06
In the format pattern java.time uses just one d for either one or two digit day of month. For year you may use either of yyyy, uuuu, y and u. And as the others have said, specify locale. If Aug is English, then an English-speaking locale.
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
Similar question to this one: Java - Unparseable date.
Oracle tutorial: Date Time explaining how to use java.time.
Question: uuuu versus yyyy in DateTimeFormatter formatting pattern codes in Java?
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.

Categories

Resources