null Date assigned by SimpleDateFormat.parse() - java

I hate to post another SimpleDateFormat question but I cannot find my answer on Google or in other threads. My code is below and the comments indicate the issue.
// The dateString format is "Thu Jul 19 00:04:11 +0000 2012". I confirmed that there
// is no preceding or trailing white space.
public static GregorianCalendar stringToDate(String dateString) {
GregorianCalendar calendar = new GregorianCalendar();
ParsePosition pos = new ParsePosition(0);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE MMM d H:mm:ss Z yyyy");
Date date = simpleDateFormat.parse(dateString, pos);
// 'Unknown Source' error thrown by setTime() as date is ultimately null.
calendar.setTime(date);
return calendar;
}
I have confirmed my dateString parameter comes through correctly, my position object starts at 0 and I have reviewed the SimpleDateFormat numerous times against http://docs.oracle.com/javase/1.4.2/docs/api/java/text/SimpleDateFormat.html. It looks right to me but I still tested various permutations of 'd' and 'H'. The only thing I can think is that there is some nuance to using this that I am missing, or I am way off base.
This compiles (javac 1.6.0_33), but when run (java version "1.6.0_33") it will not process even the first dateString value passed to it. I am running Windows 7 64-bit, Japanese version.
Any assistance is greatly appreciated.

If the current locale on your computer is Japanese (which is very likely the case here), then SimpleDateFormat will just take the default locale (Japanese) and try to parse the date with it.
If the date string is always in English, you should specify Locale.US in the SimpleDateFormat constructor.

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;

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.

GWT cannot parse timezones like BST ans EDT

I'm kinda new to GWT.
I have been trying to parse a date in the format "dd-MMM-yyyy HH:mm z" but I get an exception when the timezone is EDT or BST.
Doesn't GWT support these timezones while parsing? If so, is there any alternative way which I can use to parse the date using EDT?
Please help.
Code snippet:
DateTimeFormat dateParser = DateTimeFormat.getFormat("dd-MMM-yyyy HH:mm z");
String fomattedDate = dateParser.format(date,Timezone.createTimeZone(TimeZoneConstants.americaNewYork));
Date newDate = dateTimeParser.parse(formattedDate);
This line gives me exception.
After reading the docs for DateTimeFormat it said that it supports a lower number of timezones while parsing.
This code works for me:
TimeZoneConstants timeZoneConstants = GWT.create(TimeZoneConstants.class);
DateTimeFormat dateParser = DateTimeFormat.getFormat("dd-MMM-yyyy HH:mm Z");
String formattedDate = dateParser.format(date, TimeZone.createTimeZone(timeZoneConstants.americaNewYork()));
Date newDate = dateParser.parse(formattedDate);
I have created TimeZoneConstants via deferred binding and changed the format to dd-MMM-yyyy HH:mm Z (capital Z) - with z I did got an IllegalArgumentException indeed.
If you still get issues, try inspect deeply the parsing function to track down the exact problem.

SimpleDateFormat ignores TimeZone

I have read a bunch of posts on this, but, I am obviously missing something. I have date string, and a time zone. I am trying to instantiate a date object as follows:
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
java.util.Date dateObj = sdf.parse("2013-10-06 13:30:00");
System.out.println(dateObj);
What is printed is:
Sun Oct 06 09:30:00 EDT 2013
What I want is a date object in UTC format. Not one converted to EDT. What am I doing wrong?
Thanks.
This is because a Date object does not store any timezone information. Date basically only stores the number of milliseconds since the epoch (Jan. 1, 1970). By default Date will use the timezone associated with the JVM. In order to preserve timezone information you should continue using the DateFormat object that you've already got.
See DateFormat#format(Date): http://docs.oracle.com/javase/7/docs/api/java/text/DateFormat.html#format(java.util.Date)
The following should give you what you're looking for:
System.out.println(sdf.format(dateObj));
Try below code, you'll see that the date parsed 1st time is different from the one parsed after setting timezone. Actually the date is parsed as expected in right timezone. It s while printing it gives you get the machines's default TZ.
You could have printed the dateObj.toGMTString() to check the same, but that is deprecated.
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date dateObj = sdf.parse("2013-10-06 13:30:00");
System.out.println(dateObj.toString());
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
dateObj = sdf.parse("2013-10-06 13:30:00");
System.out.println(dateObj.toString());

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.

Categories