I know this question is asked quite a bit, and obviously you can't parse any arbitrary date. However, I find that the python-dateutil library is able to parse every date I throw at it, all while requiring absolutely zero effort in figuring out a date format string. Joda time is always sold as being a great Java date parser, but it still requires you to decide what format your date is in before you pick a Format (or create your own). You can't just call DateFormatter.parse(mydate) and magically get a Date object back.
For example, the date "Wed Mar 04 05:09:06 GMT-06:00 2009" is properly parsed with python-dateutil:
import dateutil.parser
print dateutil.parser.parse('Wed Mar 04 05:09:06 GMT-06:00 2009')
but the following Joda time call doesn't work:
String date = "Wed Mar 04 05:09:06 GMT-06:00 2009";
DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
DateTime dt = fmt.parseDateTime(date);
System.out.println(date);
And creating your own DateTimeFormatter defeats the purpose, since that seems to be the same as using SimpleDateFormatter with the correct format string.
Is there a comparable way to parse a date in Java, like python-dateutil? I don't care about errors, I just want it to mostly perfect.
Your best bet is really asking help to regex to match the date format pattern and/or to do brute forcing.
Several years ago I wrote a little silly DateUtil class which did the job. Here's an extract of relevance:
private static final Map<String, String> DATE_FORMAT_REGEXPS = new HashMap<String, String>() {{
put("^\\d{8}$", "yyyyMMdd");
put("^\\d{1,2}-\\d{1,2}-\\d{4}$", "dd-MM-yyyy");
put("^\\d{4}-\\d{1,2}-\\d{1,2}$", "yyyy-MM-dd");
put("^\\d{1,2}/\\d{1,2}/\\d{4}$", "MM/dd/yyyy");
put("^\\d{4}/\\d{1,2}/\\d{1,2}$", "yyyy/MM/dd");
put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}$", "dd MMM yyyy");
put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}$", "dd MMMM yyyy");
put("^\\d{12}$", "yyyyMMddHHmm");
put("^\\d{8}\\s\\d{4}$", "yyyyMMdd HHmm");
put("^\\d{1,2}-\\d{1,2}-\\d{4}\\s\\d{1,2}:\\d{2}$", "dd-MM-yyyy HH:mm");
put("^\\d{4}-\\d{1,2}-\\d{1,2}\\s\\d{1,2}:\\d{2}$", "yyyy-MM-dd HH:mm");
put("^\\d{1,2}/\\d{1,2}/\\d{4}\\s\\d{1,2}:\\d{2}$", "MM/dd/yyyy HH:mm");
put("^\\d{4}/\\d{1,2}/\\d{1,2}\\s\\d{1,2}:\\d{2}$", "yyyy/MM/dd HH:mm");
put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}\\s\\d{1,2}:\\d{2}$", "dd MMM yyyy HH:mm");
put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}\\s\\d{1,2}:\\d{2}$", "dd MMMM yyyy HH:mm");
put("^\\d{14}$", "yyyyMMddHHmmss");
put("^\\d{8}\\s\\d{6}$", "yyyyMMdd HHmmss");
put("^\\d{1,2}-\\d{1,2}-\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd-MM-yyyy HH:mm:ss");
put("^\\d{4}-\\d{1,2}-\\d{1,2}\\s\\d{1,2}:\\d{2}:\\d{2}$", "yyyy-MM-dd HH:mm:ss");
put("^\\d{1,2}/\\d{1,2}/\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "MM/dd/yyyy HH:mm:ss");
put("^\\d{4}/\\d{1,2}/\\d{1,2}\\s\\d{1,2}:\\d{2}:\\d{2}$", "yyyy/MM/dd HH:mm:ss");
put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd MMM yyyy HH:mm:ss");
put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd MMMM yyyy HH:mm:ss");
}};
/**
* Determine SimpleDateFormat pattern matching with the given date string. Returns null if
* format is unknown. You can simply extend DateUtil with more formats if needed.
* #param dateString The date string to determine the SimpleDateFormat pattern for.
* #return The matching SimpleDateFormat pattern, or null if format is unknown.
* #see SimpleDateFormat
*/
public static String determineDateFormat(String dateString) {
for (String regexp : DATE_FORMAT_REGEXPS.keySet()) {
if (dateString.toLowerCase().matches(regexp)) {
return DATE_FORMAT_REGEXPS.get(regexp);
}
}
return null; // Unknown format.
}
(cough, double brace initialization, cough, it was just to get it all to fit in 100 char max length ;) )
You can easily expand it yourself with new regex and dateformat patterns.
There is a nice library called Natty which I think fits your purposes:
Natty is a natural language date parser written in Java. Given a date
expression, natty will apply standard language recognition and translation
techniques to produce a list of corresponding dates with optional parse and
syntax information.
You can also try it online!
You could try dateparser.
It can recognize any String automatically, and parse it into Date, Calendar, LocalDateTime, OffsetDateTime correctly and quickly(1us~1.5us).
It doesn't based on any natural language analyzer or SimpleDateFormat or regex.Pattern.
With it, you don't have to prepare any appropriate patterns like yyyy-MM-dd'T'HH:mm:ss.SSSZ or yyyy-MM-dd'T'HH:mm:ss.SSSZZ:
Date date = DateParserUtils.parseDate("2015-04-29T10:15:00.500+0000");
Calendar calendar = DateParserUtils.parseCalendar("2015-04-29T10:15:00.500Z");
LocalDateTime dateTime = DateParserUtils.parseDateTime("2015-04-29 10:15:00.500 +00:00");
All works fine, please enjoy it.
What I have seen done is a Date util class that contains several typical date formats. So, when DateUtil.parse(date) is called, it tries to parse the date with each date format internally and only throws exceptions if none of the internal formats can parse it.
It is basically a brute force approach to your problem.
//download library: org.ocpsoft.prettytime.nlp.PrettyTimeParser
String str = "2020.03.03";
Date date = new PrettyTimeParser().parseSyntax(str).get(0).getDates().get(0);
System.out.println(date)
I have no idea about this parsing how to do in python. In java we can do like this
SimpleDateFormat sdf1 = new SimpleDateFormat("dd-MM-yyyy");
java.util.Date normalDate = null;
java.sql.Date sqlDate = null;
normalDate = sdf1.parse(date);
sqlDate = new java.sql.Date(normalDate.getTime());
System.out.println(sqlDate);
i think like java some predefined functions will be there in python. You can follow this method.
This methods parse the String date to Sql Date (dd-MM-yyyy);
import java.text.SimpleDateFormat;
import java.text.ParseException;
public class HelloWorld{
public static void main(String []args){
String date ="26-12-2019";
SimpleDateFormat sdf1 = new SimpleDateFormat("dd-MM-yyyy");
java.util.Date normalDate = null;
java.sql.Date sqlDate = null;
if( !date.isEmpty()) {
try {
normalDate = sdf1.parse(date);
sqlDate = new java.sql.Date(normalDate.getTime());
System.out.println(sqlDate);
} catch (ParseException e) {
}
}
}
}
execute this!
What is the Java DateTime format for this one?
Mon Nov 26 13:57:03 SGT 2012
I want to convert this string to Date and convert it to another format like "yyyy-MM-dd HH:mm:ss".
To convert from date to string is not hard.
Format formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
But I find no valid format to convert "Mon Nov 26 13:57:03 SGT 2012" to become date format...
=====
found solution:
DateFormat oldDateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
Format newDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date oldDate = oldDateFormat.parse(oldTimeString);
String newDateString = newDateFormat.format(oldDate);
This will work, EEE MMM dd HH:mm:ss z yyyy
You can find examples in the javadoc of SimpleDateFormat. See http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html
Try SimpleDateFormat.parse() function to convert the string to Date.
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
Date parseDate = sdf.parse(strInput);
Watch out for the Parse Exception
Well, this code produces some output
import java.util.*;
import java.text.*;
public class Test {
public static void main(String[] args) throws ParseException {
DateFormat inputFormat = new SimpleDateFormat("E MMM dd HH:mm:ss z yyyy",
Locale.US);
DateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
Locale.US);
String text = "Mon Nov 26 13:57:03 SGT 2012";
Date date = inputFormat.parse(text);
System.out.println(outputFormat.format(date));
}
}
... but it uses the default system time zone for output. It's not clear what time zone you want the result in. There's nothing in Date to store the time zone, which makes it hard to preserve the original time zone given in the text, so you'll need to decide for yourself which zone to use.
Note that I've specified Locale.US in both input and output; that's typically appropriate when you're specifying a custom format, particularly for the input which relies on month and day names.
As noted in comments, I would personally recommend using Joda Time if you possibly can for date/time work... it's a far better API than Date/Calendar. Unfortunately, Joda Time is incapable of parsing time zones - from the docs for DateTimeFormat:
Zone names: Time zone names ('z') cannot be parsed.
It's also worth noting that if there's any way you can affect the input data, moving them away from using time zone abbreviations would be a good step.
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class CPDateTime
{
public static void main(String[] args)
{
Calendar cal = Calendar.getInstance();
//subtracting a day
//cal.add(Calendar.DATE, -1);
cal.add(Calendar.MONTH, -1);
SimpleDateFormat prev_day = new SimpleDateFormat("dd");
SimpleDateFormat prev_month = new SimpleDateFormat("MM");
SimpleDateFormat prev_year = new SimpleDateFormat("YYYY");
String prev_day_str = prev_day.format(new Date(cal.getTimeInMillis()));
System.out.println(prev_day_str);
String prev_month_str = prev_month.format(new Date(cal.getTimeInMillis()));
System.out.println(prev_month_str);
String prev_year_str = prev_year.format(new Date(cal.getTimeInMillis()));
System.out.println(prev_year_str);
}
}
My first attempt was:
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
Date date = formatter.parse(string);
It throws ParseException, so I found this hack:
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
TimeZone timeZone = TimeZone.getTimeZone("Etc/GMT");
formatter.setTimeZone(timeZone);
Date date = formatter.parse(string);
It did not work either, and now I'm stuck. It parses without problems if I just change the timezone to "GMT".
edit: An example string to parse would be "2011-11-29 10:40:24 Etc/GMT"
edit2: I would prefer not to remove timezone information completely. I am coding a server that receives the date from an external user, so perhaps other dates will have other timezones.
To be more precise: This specific date I receive is from the receipt from the apple server after making an in app purchase on an iphone app, but I could also receive dates from other sources.
Don't know if this question is still relevant to you, but if you use Joda time, this'll work:
DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss ZZZ").parseDateTime(s)
Without Joda time the following will work (bit more work though):
String s = "2011-11-29 10:40:24 Etc/GMT";
// split the input in a date and a timezone part
int lastSpaceIndex = s.lastIndexOf(' ');
String dateString = s.substring(0, lastSpaceIndex);
String timeZoneString = s.substring(lastSpaceIndex + 1);
// convert the timezone to an actual TimeZone object
// and feed that to the formatter
TimeZone zone = TimeZone.getTimeZone(timeZoneString);
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
formatter.setTimeZone(zone);
// parse the timezoneless part
Date date = formatter.parse(dateString);
It didn't work for me either the thing is I tried setting TimeZone of SimpleDateFormatter to "Etc/GMT" and then formatted a new date here is the output:
2011-11-30 10:46:32 GMT+00:00
So Etc/GMT is being translated as GMT+00:00
If you really want to stick to parse "2011-09-02 10:26:35 Etc/GMT" then following will help too without even considering explicit Timezone change:
java.text.SimpleDateFormat isoFormat = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss 'Etc/GMT'");
isoFormat.parse("2010-05-23 09:01:02 Etc/GMT");
Works fine.
Following code is working for me
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("Etc/GMT"));
try { System.out.println( sdf.parse("2011-09-02 10:26:35 Etc/GMT") );
} catch (ParseException e){
e.printStackTrace();
}
Earlier I posted the following question: How can I convert this date in Java?
But now I would like to know how I can convert this string into a date/time.
2010-03-15T16:34:46Z
For example: 03/15/10
UPDATED:
String pattern = "MM/dd/yy 'at' HH:mm";
Date date = new Date();
try {
date = new SimpleDateFormat(pattern).parse(q.getUpdated_at());
} catch (ParseException e) {
e.printStackTrace();
}
dateText.setText(new SimpleDateFormat("MM/dd/yy 'at' hh:mma").format(date));
Gives me a result like:
Mon Mar 15 16:34:50 MST 2010
How can I format it to be
03/15/10 at 4:34PM
?
Both SimpleDateFormat and joda-time DateTimeFormat can parse this, using this pattern:
String pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'";
For example:
Date date = new SimpleDateFormat(pattern).parse(dateString);
And (joda-time):
DateTimeFormatter dtf = DateTimeFormat.forPattern(pattern);
DateTime dateTime = dtf.parseDateTime(s);
Update
You have 2 date formats involved - one for parsing the input, and one for formatting the output. So:
dateText.setText(new SimpleDateFormat("MM/dd/yy 'at' hh:mma").format(date));
(Of course, for the sake of optimization, you can instantiate the SimpleDateFormat only once, and reuse it)
In a nutshell, you want to convert a date in a string format to a date in another string format. You have:
2010-03-15T16:34:46Z
and you want
03/15/10 at 4:34PM
You don't want to end up using java.util.Date object as you initially implied in your question. You also don't want to use its toString() since that returns a fixed format as definied in its javadoc.
The answer of Bozho still applies. Use java.text.SimpleDateFormat. First, you need to parse the date in string format into a Date object so that you can format it back into another string format.
// First parse string in pattern "yyyy-MM-dd'T'HH:mm:ss'Z'" to date object.
String dateString1 = "2010-03-15T16:34:46Z";
Date date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(dateString1);
// Then format date object to string in pattern "MM/dd/yy 'at' h:mma".
String dateString2 = new SimpleDateFormat("MM/dd/yy 'at' h:mma").format(date);
System.out.println(dateString2); // 03/15/10 at 4:34PM
If you want to format output string, change following line in your code
dateText.setText(date.toString());
to
dateText.setText(String.format("%1$tm/%1$td/%1$ty at %1$tl:%1$tM%1$Tp", date));
I've got a bunch of dates in this String format:
String date = "Wed Sep 15 16:31:05 BST 2010";
and I'd like to convert it back to a date or calendar object. Before I go and reinvent the wheel, are there any easy ways of doing this, preferably present in the JDK?
Using SimpleDateFormat
String format = "EE MMM dd HH:mm:ss zz yyyy";
SimpleDateFormat sdf = new SimpleDateFormat(format, Locale.US);
Date result = sdf.parse(date);
Alternatively, as suggested by Jon Skeet, you can use JodaTime's DateTimeFormat - the pattern should be the same. But it appears that the BDT/BST/BDST timezone aliases are not supported properly by JodaTime.
Well, that's what java.text.DateFormat is for (and particularly its SimpleDateFormat subclass) - but personally I would suggest that you use Joda Time instead.
In particular Joda Time's DateTimeFormatter class is thread-safe, unlike SimpleDateFormat - so you can create a single instance with the appropriate pattern, and use it from any thread. Additionally, the DateTimeFormat class acts as a factory with lots of preset patterns in ISODateFormat. Oh, and controlling the time zone etc is rather better with Joda Time.
Finally, Joda Time is simply a better date and time API. It's not perfect, but it's much better than the built-in Date and Calendar support in Java.
EDIT: Trying to parse your sample string, I'm having trouble with the "BST" bit... partly because that's not really a full time zone (it's just the DST part of the Europe/London time zone) and partly because I can't quite get Joda Time to do what I want... it looks like in this one case, SimpleDateFormat wins out :(
SimpleDateFormat
public static void main(String[] args) {
try { String str_date="11-June-07";
DateFormat formatter ;
Date date ;
formatter = new SimpleDateFormat("dd-MMM-yy");
date = (Date)formatter.parse(str_date);
System.out.println("Today is " +date );
} catch (ParseException e)
{System.out.println("Exception :"+e); }
}
JodaTime
import org.joda.time.format.*;
import org.joda.time.*;
...
String dateString = "2009-04-17 10:41:33";
// parse the string
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
DateTime dateTime = formatter.parseDateTime(dateString);
// add two hours
dateTime = dateTime.plusHours(2); // easier than mucking about with Calendar and constants
System.out.println(dateTime);