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.
Related
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;
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.
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.
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.
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.