I am facing ParseException for French locale with SImpleDateFormat [duplicate] - java

This question already has answers here:
Parsing french dates in Java [duplicate]
(2 answers)
Closed 6 years ago.
I am getting ParseException with SimpleDateFormat in French locale.
There is a issue with other locale as well but I just debugged that for French. I am selecting date from UI calendar(say something like 01-Avr-2016, format "dd-MMM-yyyy") and when I pass this to my code:
String dateval = "01-Avr-2016";
Locale lformat = Locale.getDefault();
DateFormat specifiedDateFormat = new SimpleDateFormat( "dd-MMM-yyyy", lformat );
specifiedDateFormat.parse( dateval );
The above code is throwing error. I found that shortmonths in SimpleDateFormat come along with period(".") (for above example it would be "avr.") and I can write some logic to handle the period but I don't want to write any specific logic for French locale.
Instead I want to know why the month selected from calendar(coming from DateComponent) as "Avr" rather than "avr."? How can I handle that use case?

So first off, your error comes from the fact that the parse() method throws a ParseException. You need to handle it.
Secondly, in the French locale, shortened months are expected to be given with a period following the abbreviation. If you can handle adding the period, you should have no issues. As both "01-avr.-2016" and "01-Avr.-2016" are valid parseable dates.
There's a great related question about parsing French dates at Parsing French Dates in Java
String dateval = "01-avr.-2016";
Locale lformat = Locale.FRENCH;
DateFormat specifiedDateFormat = new SimpleDateFormat( "dd-MMM-yyyy", lformat );
try{
specifiedDateFormat.parse( dateval );
}
catch(ParseException pe){
pe.printStackTrace();
//or whatever logic you want to do on an invalid entry
}
For the case where you want to handle the "avr" or "Avr" directly, use Joda Time as follows:
LocalDate frenchDate = DateTimeFormat.forPattern("dd-MMM-yyyy").withLocale( Locale.FRENCH ).parseLocalDate("01-Avr-2016");

In Java 8 in Date Time Api, you can use this way,
// french date formatting (1. avril 2014)
String frenchDate = dateTime.format(DateTimeFormatter.ofPattern("d. MMMM yyyy", new Locale("fr")));
For more:
http://www.mscharhag.com/java/java-8-date-time-api
The following table shows how dates are formatted for each style with the French locales:
Sample Date Formats of French is given below
Style French Locale
DEFAULT 30 juin 2009
SHORT 30/06/09
MEDIUM 30 juin 2009
LONG 30 juin 2009
FULL mardi 30 juin 2009
Update:
Use DateFormat.getDateInstance(int style, Locale locale) instead of creating your own patterns with SimpleDateFormat.

Related

How would I format dates of different languages to get the difference between the current day and a day in the future?

So the goal is to be able to get the current date (no problem there) and compare it to a date coming in, which can be either the current date or a date in the future. Not only that, but because of how other languages write out or structure dates, the date string that comes in can change format-wise depending on the language.
If the device is set to English, the string comes in like so:
"Monday, January 30, 2023"
But if the device is set to French, the string looks like this instead:
"lundi 30 janvier 2023"
... and Spanish like this:
"lunes, 30 de enero de 2023"
... and so on. Italian is slightly different, and I've also tried German, which is also slightly different.
I did try DateFormat with DateFormat.LONG and Locale.getDefault() as the parameters (so that it would always use the Locale the device is set to and will always get the full date) but it throws an "unparsable date" error for every language, even the English string.
How would I take any of the given strings above and format them in a way that I can compare the date to the current date (a value like LocalDate.now())? Is there an overarching way to do so across languages, or do I need to create formats for all of these? The purpose is to see how far out the date asked for is from the current date to adjust what is visible in my app (done based on days - is the asked for date 3 days out from the current date? 4 days? 5?).
Thanks in advance for any and all help and insight!
You must to configure your dates patterns for each language (Locale) => This output is exactly what you want, try to adapt it with your function need :
public static void main(String[] args) {
Locale enLocale = Locale.UK;
String datePatternForEn = "EEEE', 'MMMM', 'dd yyyy";
Locale frLocale = Locale.FRANCE;
String datePatternForFr = "EEEE dd MMMM yyyy";
Locale spLocale = new Locale("es", "ES");
String datePatternForSp = "EEEE',' dd' de 'MMMM' de 'yyyy";
DateTimeFormatter englishDateFormat = DateTimeFormatter.ofPattern(datePatternForEn, enLocale);
DateTimeFormatter frenchDateFormat = DateTimeFormatter.ofPattern(datePatternForFr, frLocale);
DateTimeFormatter spanishDateFormat = DateTimeFormatter.ofPattern(datePatternForSp, spLocale);
System.out.println(LocalDate.now().format(englishDateFormat));
System.out.println(LocalDate.now().format(frenchDateFormat));
System.out.println(LocalDate.now().format(spanishDateFormat));
}

Getting "parse exception"

I want to change the string into the date formate for that I am using SimpleDateFormat class. I am passing the string as String+Integer.toString(int) from list of strings and SimpleDateFormat pattern as an inputs.
Note: Instead of String+Integer.toString(int) if I pass actual string like "Jan 09 2019" successfully convert string into the date. I tried a lot with different things.
dateList is a list of "MMM dd" formate dates.
Adding year on that formate by doing dateList.get(5)+Integer.toString(year) which is giving me parse exception <<-- Instead of this if I hardcode the date like Jan 09 2019 converting string into the date.
finalDatesInMMMDDYYYYFormat is another list where I am saving the dates in MMM dd yyyy format.
Utils.parseDate is a method I wrote in Utils class where I mentioned try-catch block.
int year = 2019;
private List<String> dateList = new ArrayList<>();
private List<Date> finalDatesInMMMDDYYYYFormat = new ArrayList<>();
final String testString = dateList.get(5)+Integer.toString(year);
finalDatesInMMMDDYYYYFormat.add(Utils.parseDate(testString, new SimpleDateFormat("MMM dd yyyy")));
Expected: Change the string into the date and add it to finalDatesInMMMDDYYYYFormat
Actual: Getting parse exception.
java.time
int year = 2019;
DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("MMM dd")
.toFormatter(Locale.ENGLISH);
List<LocalDate> finalDatesWithoutFormat = new ArrayList<>();
String dateString = "JAN 09";
MonthDay md = MonthDay.parse(dateString, dateFormatter);
finalDatesWithoutFormat.add(md.atYear(year));
System.out.println(finalDatesWithoutFormat);
The output from this snippet is:
[2019-01-09]
java.time, the modern Java date and time API, includes a class for a date without year, MonthDay, which may serve your purpose better than an ordinary date. My code also shows how to supply a year to obtain a LocalDate (a date without time of day).
I recommend you don’t use Date and SimpleDateFormat. Those classes are poorly designed and long outdated, the latter in particular notoriously troublesome.
What went wrong in your code?
From the information you have provided it’s not possible to tell why your code didn’t work. Possible explanations include the following, but there might be others.
As rockfarkas said in another answer, when concatenating your strings you were not putting any space between day of month and year, but the format string you used for parsing required a space there.
If your month abbreviations are in English, for example, and your JVM’s default locale is not English, parsing will fail (except in the rare cases where the month abbreviation coincides). You should always give your formatter a locale to specify the language used in the string to be parsed (or produced).
As an aside, your variable name finalDatesInMMMDDYYYYFormat was misleading since a Date hasn’t got (cannot have) a format.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Another example of wrong locale causing date parsing to fail: Java - Unparseable date
If you want parse format "MMM dd yyyy", you should add an extra space to your test string like this:
final String testString = dateList.get(5) + ' ' + year;

Parsing from SimpleDateFormat to Date not working?

SimpleDateFormat df = new SimpleDateFormat();
Date lastLogin = null;
try {
String troubleChild = lineScanner.next();
lastLogin = df.parse(troubleChild);
} catch (ParseException e) {
System.out.println("ohnoes");
}
Hi I'm quite new to using the date functions and I've come up with a problem. I have a file that is being parsed into various variables and they all work except this one i can never get it so that it passes the try/catch clause i've looked up similar problems but none of them work on my code.(The date i am inputting is in the format: Mon, Oct 30 22:20:11 GMT 2017) please can I get some help and thanks for it!
Solution: java.time
Please don’t take the trouble with the long outmoded classes Date and SimpleDateFormat. Instead use java.time, the modern Java date and time API also known as JSR-310:
DateTimeFormatter dtf
= DateTimeFormatter.ofPattern("E, MMM d H:mm:ss z uuuu", Locale.UK);
String inputDate = "Mon, Oct 30 22:20:11 GMT 2017";
ZonedDateTime lastLogin = ZonedDateTime.parse(inputDate, dtf);
System.out.println(lastLogin);
This prints
2017-10-30T22:20:11Z[GMT]
Since dates and times may come in so many different textual formats, I am using a format pattern string to specify your particular format. For which letters you may use, and what difference it makes whether you use 1, 3 or 4 of the same letter, see the documentation. Beware that format pattern strings are case sensitive.
Problem: SimpleDateFormat
You used the no-arg SimpleDateFormat constructor. The way I read the documentation, this gives you the default date format for your locale. If your JVM is running UK locale, I believe the format goes like 28/11/17 10:57 — not much like the input format you were trying to parse. You can use System.out.println(df.format(new Date())); to find out. The usual SimpleDateFormat constructor to use would be SimpleDateFormat(String, Locale) so that you may again supply a format pattern string and a locale.

java.text.ParseException: Unparseable date: "01:19 PM"

I just try to parse a simple time! Here is my code:
String s = "01:19 PM";
Date time = null;
DateFormat parseFormat = new SimpleDateFormat("hh:mm aa");
try {
time = parseFormat.parse(s);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I am getting this exception:
java.text.ParseException: Unparseable date: "01:19 PM"
at java.text.DateFormat.parse(Unknown Source)
This works:
public static void main(String[] args) throws Exception {
String s = "01:19 PM";
Date time = null;
DateFormat parseFormat = new SimpleDateFormat("hh:mm a", Locale.ENGLISH);
System.out.println(time = parseFormat.parse(s));
}
ouputs:
Thu Jan 01 13:19:00 KST 1970
The pattern letter a is the Am/pm marker, but it is locale specific. Obviously AM and PM are valid in the English locale, but they are not valid in the Hungarian locale for example.
You get ParseException because you have a non-english locale set, and in your locale PM is invalid.
// This is OK, English locale, "PM" is valid in English
Locale.setDefault(Locale.forLanguageTag("en"));
new SimpleDateFormat("hh:mm aa").parse("01:19 PM");
// This will throw Exception, Hungarian locale, "PM" is invalid in Hungarian
Locale.setDefault(Locale.forLanguageTag("hu"));
new SimpleDateFormat("hh:mm aa").parse("01:19 PM");
To get around this problem, the Locale can be specified in the constructor:
// No matter what is the default locale, this will work:
new SimpleDateFormat("hh:mm aa", Locale.US).parse("01:19 PM");
LocalTime
Modern answer using LocalTime class.
LocalTime time = null;
DateTimeFormatter parseFormatter
= DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH);
try {
time = LocalTime.parse(s, parseFormatter);
} catch (DateTimeParseException dtpe) {
System.out.println(dtpe.getMessage());
}
This turns the string from the question, 01:19 PM, into a LocalTime equal to 13:19.
We still need to provide the locale. Since AM/PM markers are hardly used in practice in other locales than English, I considered Locale.ENGLISH a fairly safe bet. Please substitute your own.
Already when this question was asked in 2014, the modern replacement for the old classes Date and SimpleDateFormat was out, the modern Java date and time API. Today I consider the old classes long outdated and warmly recommend using the modern ones instead. They have generally shown to be remarkably more programmer friendly and convenient to work with.
Just for one simple little thing, if we fail to give a locale on a system with a default locale that doesn’t recognize AM and PM, the modern formatter will give us an exception with the message Text '01:19 PM' could not be parsed at index 6. Index 6 is where it says PM, so we’re already on our way. Yes, I know there is a way to get the index out of the exception thrown by the outdated class, but the majority of programmers were never aware and hence did not use it.
More importantly, the new API offers a class LocalTime that gives us what we want and need here: just the time-of-day without the date. This allows us to model our data much more precisely. There are a number of questions on Stack Overflow caused by confusion in turn caused by the fact that a Date necessarily includes both date and time when sometimes you want only one or the other.
I think that instead of "hh:mm aa" it should be "h:mm a"
According to the official documentation you should use this format string: "h:mm a"
But also your format string is correct because I'm getting no errors executing your code.
Try this format: "K:m a"
Check the docs too: SimpleDateFormat
Also, check your locale, your problem seems to be locale-specific.

How can I get the current time in particular format, for a particular zone?

I want to get the current DateTime in a zone of my choice and in a particular format (eg HH-MM-SS, MM-DD-YY, MoMo-DD-YY-HH-MM-SS etc).
How can I do this, using JodaTime?
Given that you've already seen the user guide (which includes sections on time zones and formatting), it's not really clear where your confusion is. Some sample code to get you going:
DateTimeZone zone = DateTimeZone.forID("Europe/London");
DateTime currentTimeInLondon = new DateTime(zone);
DateTimeFormatter formatter = DateTimeFormat.forPattern("HH:mm:ss, MM-dd-yyyy");
String text = formatter.print(currentTimeInLondon); // e.g. 08:24:54, 09-26-2012
It would be worth you taking some time to analyze why you couldn't get to this code yourself, given the information in the user guide. Being able to work out how to use APIs is a very important skill as a software engineer - you mustn't expect to be spoonfed code all the time.
this may help you.
http://joda-time.sourceforge.net/userguide.html
Use following code to get time according to particular zone with format.
Locale locale = Locale.FRENCH;
// Format with a custom format
DateFormat formatter = new SimpleDateFormat("E, dd MMM yyyy", locale);
String s = formatter.format(new Date());
// mar., 29 sept. 2012
// Format with a default format
s = DateFormat.getDateInstance(DateFormat.MEDIUM, locale).format(new Date());
// 29 sept. 2012

Categories