Parsing from SimpleDateFormat to Date not working? - java

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.

Related

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;

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.

Can't make java.text.SimpleDateFormat to work

I have a Date object as follows:
java.util.Date d = new java.util.Date(System.currentTimeMillis()); // Mon Dec 23 14:57:28 PST 2013
I need to format the date to get another Date object with this format instead:
2013-12-23 14:57:28
I tried this code:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
sdf.format(d); // d is still Mon Dec 23 14:57:28 PST 2013, no formatting.
I tried this code:
String s = d.toString();
try {
d = sdf.parse(s);
} catch (Exception e)
e.printStackTrace(); // java.text.ParseException: Unparseable date: "Mon Dec 23 14:35:48 PST 2013"
Would you please tell me what am I doing wrong? I googled searched it but the solutions to format a Date was more or less what I tried. Any help is greatly appreciated.
You don't understand what a Date is, and what format() does. A Date is just a number of milliseconds. Nothing more. It doesn't have any format. Formatting a date doesn't change the date at all. It returns a string containing a human readable representation of the date (like "2012-11-23" or "Monday, April 2").
So, the following instruction:
sdf.format(d);
is effectively a noop. You ignore the string that it returns.
If what you want is to have a specific format used when calling date.toString(), it's impossible. When you want to display a date in a specific format (yyyy-MM-dd for example), instead of doing
System.out.println(date);
use
DateFormat format = new SimpleDaeFormat("yyyy-MM-dd");
System.out.println(format.format(date));
All this is clearly explained in the javadoc. You should read it.
SimpleDateFormat, does not change the date format, it gives you a formatted date for display purpose only, not for anything else.
util.Date will always have one format (a long number of milliseconds) that you can format to any way you want in order to display using SimpleDateFormat. So in effect no matter what date you get you can format to what format you want.
If you explain why you are trying to do what you are trying to do, then maybe we can support you better.

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

How to parse month full form string using DateFormat in Java?

I tried this:
DateFormat fmt = new SimpleDateFormat("MMMM dd, yyyy");
Date d = fmt.parse("June 27, 2007");
error:
Exception in thread "main" java.text.ParseException: Unparseable date: "June 27, 2007"
The java docs say I should use four characters to match the full form.
I'm only able to use MMM successfully with abbreviated months like "Jun" but i need to match full form.
Text: For formatting, if the number
of pattern letters is 4 or more, the
full form is used; otherwise a short
or abbreviated form is used if
available. For parsing, both forms are
accepted, independent of the number of
pattern letters.
https://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html
You are probably using a locale where the month names are not "January", "February", etc. but some other words in your local language.
Try specifying the locale you wish to use, for example Locale.US:
DateFormat fmt = new SimpleDateFormat("MMMM dd, yyyy", Locale.US);
Date d = fmt.parse("June 27, 2007");
Also, you have an extra space in the date string, but actually this has no effect on the result. It works either way.
LocalDate from java.time
Use LocalDate from java.time, the modern Java date and time API, for a date
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MMMM d, u", Locale.ENGLISH);
LocalDate date = LocalDate.parse("June 27, 2007", dateFormatter);
System.out.println(date);
Output:
2007-06-27
As others have said already, remember to specify an English-speaking locale when your string is in English. A LocalDate is a date without time of day, so a lot better suitable for the date from your string than the old Date class. Despite its name a Date does not represent a date but a point in time that falls on at least two different dates in different time zones of the world.
Only if you need an old-fashioned Date for an API that you cannot afford to upgrade to java.time just now, convert like this:
Instant startOfDay = date.atStartOfDay(ZoneId.systemDefault()).toInstant();
Date oldfashionedDate = Date.from(startOfDay);
System.out.println(oldfashionedDate);
Output in my time zone:
Wed Jun 27 00:00:00 CEST 2007
Link
Oracle tutorial: Date Time explaining how to use java.time.
Just to top this up to the new Java 8 API:
DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("MMMM dd, yyyy").toFormatter();
TemporalAccessor ta = formatter.parse("June 27, 2007");
Instant instant = LocalDate.from(ta).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
Date d = Date.from(instant);
assertThat(d.getYear(), is(107));
assertThat(d.getMonth(), is(5));
A bit more verbose but you also see that the methods of Date used are deprecated ;-) Time to move on.
val currentTime = Calendar.getInstance().time
SimpleDateFormat("MMMM", Locale.getDefault()).format(date.time)

Categories