Wrong output for date format in Grails - java

I'm trying to format a Date in Grails, here is my code in the controller:
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
empRefInstance.startDate=sdf.parse(params.startDate)
empRefInstance.endDate=sdf.parse(params.endDate)
println ("dates " + empRefInstance.startDate +" "+empRefInstance.endDate)
the output supposed to be 01-05-2016 as per the format i defined but the output of the both date in this format
Sun May 01 00:00:00 EEST 2016
is there something wrong in the formater?

There is nothing wrong with the formatter. You're not using one for the output. Something like this will give you the expected output:
println empRefInstance.startDate.format('dd-MM-yyyy')

You are not formatting the output instead you have only parsed.
Formatting: Converting the Date to String (the format method)
Parsing: Converting the String to Date (the parse method)
To format, you need to do like this:
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
// First you are converting the incoming date string to a date
empRefInstance.startDate = sdf.parse(params.startDate)
empRefInstance.endDate=sdf.parse(params.endDate)
// Now we have to conert the date object to string and print it
println ("dates " + sdf.format(empRefInstance.startDate) + " "+sdf.format(empRefInstance.endDate))
When you print a Date object in Groovy/Java, it's default implementation of toString() will be invoked hence you were getting output like Sun May 01 00:00:00 EEST 2016
Also, Groovy adds a format method in Date class to direct allow formatting. You can even use that as well.
println("dates " + empRefInstance.startDate.format("dd-MM-yyyy") + " " + empRefInstance.endDate.format("dd-MM-yyyy"))

Related

Formatting a Date from an Excel Sheet

I am reading a date column from an Excel Sheet in my Java program via Apache POI that returns the string Fri Jan 16 00:00:00 EST 2015. I need to format this string to 01/16/2016.
I try the following using the SimpleDateFormat to parse the String to a Date Object, then back to the formatted String I need
String inputDate = excelData.get(20).toString(); // Returns Fri Jan 16 00:00:00 EST 201
Date date = new SimpleDateFormat("MM/dd/yyyy").parse(inputDate);
String outputDate = new SimpleDateFormat("MM/dd/yyyy").format(date);
However the following is returned when trying to parse inputDate
Unparseable date: "Fri Jan 16 00:00:00 EST 2015"
Is my inputDate unreadable or am I missing something here? I've also thought of formatting the cell itself to the proper date format instead - thoughts?
Your problem is on this line:
Date date = new SimpleDateFormat(**"MM/dd/yyyy"**).parse(inputDate);
The date format you've described looks more like:
"DDD MMM DD HH:mm:ss tz yyyy" or something like that.
Use https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html to find the right formatter in order to read the date.
The output looks fine, given you can read the input string format as the right format into a Date.
Your code tells SimpleDateFormat to use MM/dd/yyyy format to PARSE the date, so of course it can't work, since this is not the format of the string you get.
The POI FAQ at https://poi.apache.org/faq.html#faq-N1008D gives a snippet of code to read a date:
case HSSFCell.CELL_TYPE_NUMERIC:
double d = cell.getNumericCellValue();
// test if a date!
if (HSSFDateUtil.isCellDateFormatted(cell)) {
// format in form of M/D/YY
cal.setTime(HSSFDateUtil.getJavaDate(d));
cellText =
(String.valueOf(cal.get(Calendar.YEAR))).substring(2);
cellText = cal.get(Calendar.MONTH)+1 + "/" +
cal.get(Calendar.DAY_OF_MONTH) + "/" +
cellText;
}
Have you tried that?
Change
Date date = new SimpleDateFormat("MM/dd/yyyy").parse(inputDate);
to
Date date = new SimpleDateFormat("EEE MMM DD HH:mm:ss zzz yyyy").parse(inputDate);
zzz Time zone EST
EEE Day name in week Tuesday
MMM Month in year July
Reference: SimpleDateFormat doc

Does the java.util.Date object verifies the date validity?

I just wrote this unit tests :
#Test
public void testGetDateFromString() throws ParseException{
String date = "52/29/2500";
Date dateFromString = DateHelper.getDateFromString(date, DateHelper.DD_MM_YYYY_FORMAT);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DateHelper.DD_MM_YYYY_FORMAT);
Date dateWithSimpleFormat = simpleDateFormat.parse(date);
Assert.assertNotNull(dateFromString);
Assert.assertNotNull(dateWithSimpleFormat);
Assert.assertTrue(dateFromString.equals(dateWithSimpleFormat));
System.out.println("dateFromString " + dateFromString);
System.out.println("dateWithSimpleFormat " + dateWithSimpleFormat);
}
And the output is :
dateFromString Wed Jun 21 00:00:00 CEST 2502
dateWithSimpleFormat Wed Jun 21 00:00:00 CEST 2502
The DateHelper.DD_MM_YYYY_FORMAT pattern is dd/MM/yyyy and getDateFromString is a method that parses a String date to a Date object using commons-lang library.
Why des the java.util.Date object verifies the date validity?
You need to set simpleDateFormat.setLenient(false); to make the SimpleDateFormat to validate your input strictly.
You can refer the setLenient documentation for further understanding. By the definition,
Specify whether or not date/time parsing is to be lenient. With lenient parsing,
the parser may use heuristics to interpret inputs that do not precisely match this
object's format. With strict parsing, inputs must match this object's format.
Use simpleDateFormat.setLenient(false); to enable strict parsing.
java.time
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd/MM/uuuu");
String date = "52/29/2500";
try {
LocalDate dateWithJavaTime = LocalDate.parse(date, dateFormatter);
System.out.println("dateWithJavaTime " + dateWithJavaTime);
} catch (DateTimeParseException dtpe) {
System.out.println("Invalid date. " + dtpe);
}
The output from this code is:
Invalid date. java.time.format.DateTimeParseException: Text
'52/29/2500' could not be parsed: Invalid value for MonthOfYear (valid
values 1 - 12): 29
Please enjoy not only that the validation works, but also the precision of the error message.
Other results:
For the string 52/11/2500 the result is “Invalid date. java.time.format.DateTimeParseException: Text '52/11/2500' could not be parsed: Invalid value for DayOfMonth (valid values 1 - 28/31): 52”.
For the string 29/02/2019 we get “dateWithJavaTime 2019-02-28”, which may surprise. To have this string rejected use
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("dd/MM/uuuu")
.withResolverStyle(ResolverStyle.STRICT);
Now we get
Invalid date. java.time.format.DateTimeParseException: Text
'29/02/2019' could not be parsed: Invalid date 'February 29' as '2019'
is not a leap year
Again enjoy how precise the message is.

date is saving in different format when saving to database

Iam saving date in below format EEE MMM dd HH:mm:ss z yyyy, but it is saving in this format 2013-05-03 00:38:20.0. But when i print same date on console before saving to database, it is as expected INFO: Fri May 03 00:38:20 IST 2013
Please can anyone explain why it is saving as above mentioned.
Below is the code:
Date now = new Date();
String datetimeStr = now.toString();
SimpleDateFormat format = new SimpleDateFormat(
"EEE MMM dd HH:mm:ss z yyyy");
Date parseDate = format.parse(datetimeStr);
Datebase column
date_order_created date
I hope you're not actually saving your dates as text in the database in the first place. Assuming you're not (and I don't think you are), you're not really "saving date in below format" at all... you're just saving the date.
The value of a date doesn't have a format - June 19th 1976 is the same date whether I represent it that way, or as 1976-06-19 or 19/06/1976 or 06/19/1976 (assuming I know how to interpret any of those formats). That's what you're seeing here - you're saving the date, and when you look at it "in the database" (e.g. via some SQL console) you're seeing one representation... but when you fetch it from the database and print it from Java, you're seeing the results of calling Date.toString(). That doesn't change the value at all.
If you want to format a Date value in one particular way, use SimpleDateFormat - but be very aware that a Date object itself has no format (or time zone, or calendar) and your database probably doesn't either. (The exact details of what goes in the database will depend on the database and the column type.)
It's very important to distinguish between a value and string representations of that value.
For example, if I write:
int x = 0xff;
int y = 255;
System.out.println(x == y);
then that prints "true" - because both x and y have the same value. The fact that in one case I used a hexadecimal representation doesn't affect the value as a number at all.
From here
The following code formats a date and time according to the pattern String passed to the SimpleDateFormat constructor. The String returned by the format method contains the formatted date and time that are to be displayed.
Date today;
String output;
SimpleDateFormat formatter;
formatter = new SimpleDateFormat(pattern, currentLocale);
today = new Date();
output = formatter.format(today);
System.out.println(pattern + " " + output);
The following table shows the output generated by the previous code ex
Pattern Output
EEE, MMM d, ''yy Tue, Jun 30, '09
When you save a Date objet in a database, this is generally not its String representation which is saved. This depends of the field type used in the database.
And :
Fri May 03 00:38:20 IST 2013
looks like a date.toString()

DateFormat does not work?

String selectedDate = "2012-" + createdMonth + "-" + createdDay;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
createdDate = dateFormat.parse(selectedDate);
} catch (ParseException e1) {
e1.printStackTrace();
}
System.out.println(createdDate);
Basically when I print createdDate, it will display something like this :
Thu Mar 08 00:00:00 CST 2012
Instead of something of this format "yyyy-MM-dd". Thanks a bunch!
The parse method returns a java.util.Date and that is the what the Date implementation of toString() returns.
You need to print as below. Point is that you need to use the formatter object you have created while printing as well.
System.out.println(dateFormat.format(createdDate));
use dateFormat.format(createdDate)
You seem to think that createdDate, which is a Date object, has the format yyyy-MM-dd. It doesn't. Date objects don't have a format - they just contain a timestamp, just like numbers are just numbers, which don't have a format by themselves.
A SimpleDateFormat object is used to parse a String into a Date object, or format a Date object into a String.
If you have a Date object and you want to display the date in a particular format, then convert it to a String with the appropriate format using a SimpleDateFormat object:
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
String text = fmt.format(createdDate);
System.out.println("Created: " + text);
If you print a Date object without explicitly formatting it, it will be formatted using a default format, which is why you see Thu Mar 08 00:00:00 CST 2012.
A Date object does not somehow remember what the format was of the String that you parsed it from.

Jackrabbit dateformat for comparison

I am using Jackrabbit to store my documents.
Now I would like to search for documents that were created e.g. after a specific date using XPATH. To do so, I tried something like:
String dateString = date.toString();
//element(*,nt:file)[#jcr:created >= xs:dateTime(dateString)]
date is an object of class java.util.Date
dateString gets formatted as: Wed Mar 16 00:00:00 CET 2011
But this is giving me an InvalidQueryException, indicating that the dateString is wrong:
Invalid query: Lexical error at line
1, column 136. Encountered: "0" (48),
after : ":" for statement
So the question is: What is the correct format of a date for xs:dateTime ?
Thanks in advance
For Jackrabbit this worked for me:yyyy-MM-dd'T'HH:mm:ss.SSSX
(2015-12-16T15:16:50.465-02:00) when some previous code had taken a Calendar and done:prop.getValue().getString()
Couldn't get Z to work ("Unparseable date").
Just for the sake of completeness:
I found another (Jackrabbit/JCR dependend) way to get a correctly formatted date string:
Calendar cal = Calendar.getInstance();
cal.setTime(date);
String dateString = ValueFactoryImpl.getInstance().createValue(cal).getString();
This dateString can be used with the single arg constructor of xs:dateTime
xs:dateTime uses a specific pattern - see here and here. So instead of using date.toString(), to produce that format, you would need to use a suitable DateFormat. Something like this:
DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
String dateString = format.format(date);
However, it appears that the constructor for xs:dateTime in fact requires two args: one for date and one for time. See here.
So I would guess you could use this:
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
DateFormat tf = new SimpleDateFormat("HH:mm:ss");
String dateString = df.format(date);
String timeString = tf.format(date);
Also I have some problems with JAckRabbit date format and I needed to get some entities between two dates :
#createdDate >= xs:dateTime(startDate)
#createdDate <= xs:dateTime(endDate)
What I noticed is :
using format yyyy-MM-dd'T'HH:mm:ss.SSS'Z' to parse the date gave incorrect results( also it should be yyyy-MM-dd'T'HH:mm:ss.SSSZ) but you get for example :
2012-01-04T23:59:59.999+0200 instead of
2012-01-04T23:59:59.999+02:00 (saved in JCR)
Solution with ValueFactoryImpl.getInstance().createValue(cal).getString() works.

Categories

Resources