How can I make a DateTimeFormatter that accepts trailing junk? - java

I'm retrofitting old some SimpleDateFormat code to use the new Java 8 DateTimeFormatter. SimpleDateFormat, and thus the old code, accepts strings with stuff in them after the date like "20130311nonsense". The DateTimeFormat I created throws a DateTimeParseException for these strings, which is probably the right thing to do, but I'd like to maintain compatibility. Can I modify my DateTimeFormat to accept these strings?
I'm currently creating it like this:
DateTimeFormatter.ofPattern("yyyyMMdd")

Use the parse() method that takes a ParsePosition, as that one doesn't fail when it doesn't read the entire text:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
TemporalAccessor parse = formatter.parse("20140314 some extra text", new ParsePosition(0));
System.out.println(LocalDate.from(parse));
The ParsePosition instance that you pass will also be updated with the point at which the parsing stopped, so if you need to do something with the leftover text then it will be useful to assign it to a variable prior to calling parse.

Related

Joda DateTimeFormat without - separator?

I am trying to make a joda LocalDate in the format of yyyyMMdd, but every time I parse it to create the object, it inserts hyphens like yyyy-MM-dd for no apparent reason.
DateTimeFormatter format = DateTimeFormat.forPattern("yyyyMMdd");
LocalDate d = format.parseLocalDate("20150101");
Is there a way to get this to end up looking like 20150101 or will it forever be 2015-01-01?
Solution is not to use the toString()-method:
DateTimeFormatter format = DateTimeFormat.forPattern("yyyyMMdd");
LocalDate d = format.parseLocalDate("20150101");
System.out.println(format.print(d)); // 20150101
System.out.println(d); // using toString(): 2015-01-01
Quite simple, isn't it? For me, the form using hyphens is more readable, so this is a natural choice for the standard output of the method toString().
By the way: Both variants are valid ISO-8601-strings. The form without hyphens is called BASIC DATE while the form with hyphens is called EXTENDED DATE.

How to present a date that can be parsed by any DateTimeFormatter pattern in Java?

I'm working with a software that uses a lot of DateTimeFormat parsing, in order to minimize the errors, I wonder if I can present the date String in a certain way that it can be parsed by any DateTimeFormat pattern. Ideally it should work as follows:
String date = "...."
DateTimeFormatter format = DateTimeFormat.forPattern(any pattern I want);
DateTime result = format.parseDateTime(date);
Or does the date have to follow the pattern? Thanks for your help
No, you can not get one size fits all. Think if your string is not a legal date at all, something like "hello", how are you going to parse it?
java.time
Java 8 and later includes the java.time framework (Tutorial). The java.time formatter’s pattern may contain []to mark optional parts. This gives you some flexibility. Say you use format:
M[M]['/']['-']['.']d[d]['/']['-']['.']yyyy[' ']['T'][' ']h[h]:mm:ss
So in this case your string may have one or two digits specifying month, day and hour. Month, day and year may be separated by ., - or / and so forth. For example with format above the following strings will be parsed successfully:
1/10/1995 9:34:45
01-10-1995 09:34:45
01.10.1995T09:34:45
…and so forth.
I wrote a utility that has a set of patterns. Once it gets a String it tries to parse it with all the patterns in the set and sees if it succeeds with one of them. If you write such a set of patterns correctly you may ensure that your util supports any possible String that denotes a valid date.
SimpleDateFromat let you set your own date patters. for example dd/mm/yyyy, mm/dd/yyyy, yyyy-mm-dd etc..
This link can give you a better understanding about date patterns and how to use it
use SimpleDateFormat
SimpleDateFormat sdf=new SimpleDateFormat("dd/MM/yyyy");
Date d=sdf.parse("07/12/2014");

Is there a way to get stricted date parsing than setting leniency to false?

I'm kind of new to Java programming and I need to parse a date I get as a string. The format has to be dd-MM-yyyy but it's irrelevant for the answer I think.
To parse that string into a Calendar object I'm using SimpleDateFormat in the following way:
String example = "16-09-2013";
SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
formato.setLenient(false);
Calendar cal = new GregorianCalendar();
cal.setTime(format.parse(date));
And the result is the one to be expected.
The problem is that it would also parse correctly something like "16-9-2013" (note the absence of leading 0 in the month) and when that happens I'd prefer to throw the exception and catch it to notify appropriately.
I'm restricted to use Java SE without any additions (which takes out Joda Time and the like), so I wonder, is there a way to parse a date string so that it only succeeds if it strictly complies with the format?
You can use a regular expression to check that the string matches the expected format, regex is built into Java SE http://docs.oracle.com/javase/tutorial/essential/regex/
Then you can use the code you have above to check that it is in fact a valid date, and not some invalid date such as feb 31 which the regex would not catch.

SimpleDateFormat appears to fail with "yyyy-MM-dd HH:mm:ss.SSS0"

Why doesn't the following work? It appears that the literal zero at the end is the cause...
final DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS0");
format.setLenient(false);
String d = format.format(new Date());
System.out.println(format.parse(d));
I do not know why would you need to add the zero (0) at the end of your pattern, but you should wrap the not pattern letters inside '' to make them work:
final DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS'0'");
More info:
Java SimpleDateFormat, Examples section at the beginning of the documentation.
The problem with your code is in this line
System.out.println(format.parse(d));
Trying to parse more than 3-digit milliseconds to java.util.Date will result in an exception. The pattern to parse the String should be
"yyyy-MM-dd HH:mm:ss.SSS" //without the zero at the end, now your whole code will work...
If you're working with nanoseconds or your data have them, you could ignore these values, also nanoseconds are not supported in Java Date/Time API (in the documentation they don't even mention it).
If you really, really need to have the nanoseconds for diverse purposes, then you should stick to use a String instead of a Date object.

Java Date format

I have a spring web application that runs in Tomcat. I must set the date and number format for my application to a special format.
Can I set the format in any descriptor to the special in my application or I can set the all system format only?
I want to use this pattern: yyyy.mm.dd.
This code is wrong because it's not a standard locale pattern:
String currentDate = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.UK).format(new Date());
But I don't want type the pattern everywhere in the application, I want set the pattern once.
I want if I type this code:
String currentDate = SimpleDateFormat.getDateInstance(DateFormat.SHORT).format(new Date());
The result is: 2010.08.04.
Is it possible?
java.util.Date objects do not have a format by themselves (they only represent the date and time value, just like integers only represent a number value and don't know anything about formatting numbers).
There is no system-wide default date format setting. When you print a Date object by (implicitly or explicitly) calling toString() on it, it will be printed with a fixed, default format that you can't change:
System.out.println(new Date());
// Example output: Wed Aug 04 09:46:57 CEST 2010
If you want to show a date with a specific format, use a java.text.DateFormat object to format it. For example:
DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
System.out.println(df.format(new Date()));
// Example output: 04-08-2010 09:48:47
You can absolutely format a date any way you want, no matter if you use Spring or not. First though make sure that you really need a "special formatting", not just a format that is default for a certain locale (like deCH or svSE or enGB) because if you just want to convert a date to your countries native date formatting you can simply use
String currentDate = SimpleDateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.UK).format(new Date());
And if you really want a custom formatting, you can do like this
String currentDateMyFormat = new SimpleDateFormat("dd:MMM:yy HH.mm").format(new Date());
Of course you can reverse the process (from String to Date) by replacing format with parse.
Hope this answers your question because just like Xu before me, I am not sure I understood your question completely ;)
Since you're talking about doing something application-wide, let me remind you to be cautious with any java.text.Format subclass (including DateFormat, SimpleDateFormat, etc.). As noted in the Javadoc, Formats are generally not thread-safe. I know from personal experience that DateFormats are not.
Therefore, if you're considering setting something up for use across your application, I recommend only defining the format String and sharing it around the application. Instances of a Format class are best-defined in a thread-safe manner, such as on the stack of a method call.

Categories

Resources