Hibernate Criteria for Dates - java

In oracle I have dates in format
17-April-2011 19:20:23.707000000
I would like to retrieve all orders for 17-04-2011.
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-YYYY");
String myDate = "17-04-2011";
Date date = formatter.parse(myDate);
Criteria criteria =
session.createCriteria(Order.class);
Criterion restrictDate = Restrictions.like("orderDate",date);
but it brings me empty result:

Why do you use Restrictions.like(...)?
You should use Restrictions.eq(...).
Note you can also use .le, .lt, .ge, .gt on date objects as comparison operators. LIKE operator is not appropriate for this case since LIKE is useful when you want to match results according to partial content of a column.
Please see http://www.sql-tutorial.net/SQL-LIKE.asp for the reference.
For example if you have a name column with some people's full name, you can do where name like 'robert %' so that you will return all entries with name starting with 'robert ' (% can replace any character).
In your case you know the full content of the date you're trying to match so you shouldn't use LIKE but equality. I guess Hibernate doesn't give you any exception in this case, but anyway you will probably have the same problem with the Restrictions.eq(...).
Your date object you got with the code:
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-YYYY");
String myDate = "17-04-2011";
Date date = formatter.parse(myDate);
This date object is equals to the 17-04-2011 at 0h, 0 minutes, 0 seconds and 0 nanoseconds.
This means that your entries in database must have exactly that date. What i mean is that if your database entry has a date "17-April-2011 19:20:23.707000000", then it won't be retrieved because you just ask for that date: "17-April-2011 00:00:00.0000000000".
If you want to retrieve all entries of your database from a given day, you will have to use the following code:
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-YYYY");
String myDate = "17-04-2011";
// Create date 17-04-2011 - 00h00
Date minDate = formatter.parse(myDate);
// Create date 18-04-2011 - 00h00
// -> We take the 1st date and add it 1 day in millisecond thanks to a useful and not so known class
Date maxDate = new Date(minDate.getTime() + TimeUnit.DAYS.toMillis(1));
Conjunction and = Restrictions.conjunction();
// The order date must be >= 17-04-2011 - 00h00
and.add( Restrictions.ge("orderDate", minDate) );
// And the order date must be < 18-04-2011 - 00h00
and.add( Restrictions.lt("orderDate", maxDate) );

By using this way you can get the list of selected records.
GregorianCalendar gregorianCalendar = new GregorianCalendar();
Criteria cri = session.createCriteria(ProjectActivities.class);
cri.add(Restrictions.ge("EffectiveFrom", gregorianCalendar.getTime()));
List list = cri.list();
All the Records will be generated into list which are greater than or equal to '08-Oct-2012' or else pass the date of user acceptance date at 2nd parameter of Restrictions (gregorianCalendar.getTime()) of criteria to get the records.

If the column is a timestamp you can do the following:
if(fromDate!=null){
criteria.add(Restrictions.sqlRestriction("TRUNC(COLUMN) >= TO_DATE('" + dataFrom + "','dd/mm/yyyy')"));
}
if(toDate!=null){
criteria.add(Restrictions.sqlRestriction("TRUNC(COLUMN) <= TO_DATE('" + dataTo + "','dd/mm/yyyy')"));
}
resultDB = criteria.list();

try this,
String dateStr = "17-April-2011 19:20:23.707000000 ";
Date dateForm = new SimpleDateFormat("dd-MMMM-yyyy HH:mm:ss").parse(dateStr);
SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
String newDate = format.format(dateForm);
Calendar today = Calendar.getInstance();
Date fromDate = format.parse(newDate);
today.setTime(fromDate);
today.add(Calendar.DAY_OF_YEAR, 1);
Date toDate= new SimpleDateFormat("dd-MM-yyyy").parse(format.format(today.getTime()));
Criteria crit = sessionFactory.getCurrentSession().createCriteria(Model.class);
crit.add(Restrictions.ge("dateFieldName", fromDate));
crit.add(Restrictions.le("dateFieldName", toDate));
return crit.list();

Related

JPA Criteria add one day to the selected date

I have a JPA criteria that selects the max date from a table and I want to select the following day, e.g. if the query result is 1/20/17 I want the result to be 1/21/17
Here is my code:
CriteriaQuery<Date> maxDateCriteriaQuery = criteriaBuilder.createQuery(Date.class);
Root<DatesClass> datesClassRoot = maxDateCriteriaQuery.from(DatesClass.class);
maxDateCriteriaQuery.select(criteriaBuilder.greatest(datesClassRoot));
TypedQuery<Date> maxDateTypedQuery = entityManager.createQuery(amortizationsQuery);
Date maxDate = maxDateTypedQuery.getSingleResult();
I want to change the criteria to return the max date + 1
In oracle I will do it:
SELECT MAX(MY_DATE) + 1 FROM DATES_TABLE;
I will appreciate any help!
I assume you want to keep the original Date object in the database?
Than I would add 1 day to the day you retrieved from your DB:
Calendar c = Calendar.getInstance();
c.setTime(maxDate);
c.add(Calendar.DATE, 1);
Date newMaxDate = c.getTime();

java date and time from timestamp

I am working on android app with achartengine where I am making a TimeSeries linegraph. I have stored all my variables inside an Arraylist. Since I need correct date object to insert in the time axis of my chart I am using,
int count = list.size();
Date[] dt = new Date[count];
for(int i=0;i<count;i++){
long a = Long.parseLong(list.get(i).get("time"));
dt[i] = new Date(a);
}
Here long a has the timestamp . With above piece of code. I am able to get dt as 09-Apr-2014 but I need the date to be shown as 09-Apr 12:55 . How can I do that,
I tried using the folllowing
SimpleDateFormat sdfDate = new SimpleDateFormat("MM-dd HH:mm");
Date now = new Date();
String strDate = sdfDate.format(now);
But Since strDate is a string I cannot use it as dt[i] = strDate which will throws an error as one is Date and another is String.
How can I solve this ?
Thanks
You can solve it this way:
dt[i] = sdfDate.parse(strDate);
If you really just need the date strings, you can do this:
int count = list.size();
String[] dt = new String[count];
for (int i = 0; i < count; i++) {
long a = Long.parseLong(list.get(i).get("time"));
Date d = new Date(a);
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd HH:mm");
dt[i] = dateFormat.format(d);
}
Or, if you actually need the Date array, just format the dates on the fly as you need them.
Your question is misguided - you are showing how you create Date objects in the code, yet what you want to fix is how you show them.
The Date array will have dates precisely to the millisecond. The default toString() method of the Date objects shows only the day, that's why you're not seeing the time.
It is inherently the UIs responsibility to decide on the format of time that it is going to print, hence you should pass the Date array to the UI (or up to the point of printing) and format them there.
The DateFormat can do both (date to string representation and back):
DateFormat formatter = new SimpleDateFormat( "dd-MM-yyyy HH:mm:ss" );
Date to String:
Date date = new Date();
String sDate = formatter.format( time );
String to Date:
Date date = formatter.parse(sDate );
When you store the date, you should store it as precise as possible (milliseconds). For displaying it as a string, you can use whatever format you want.

MongoDB find query with date comparison

In mongodb collection I saved date as a string.
I want to fetch documents which were inserted in last 24 hours. Below is my code-
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date yest = new Date();
Date now = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(now);
cal.add(Calendar.MINUTE, -1440);
yest = cal.getTime();
String dToN = sdf.format(now);
String dToY = sdf.format(yest);
System.out.println("Yest:"+dToY);
System.out.println("Now:"+dToN)
BasicDBObject find = new BasicDBObject("retryCount", new BasicDBObject("$gt", 0));
find.append("status",1);
find.append("deliveryTime",new BasicDBObject("$gte", dToY));
find.append("deliveryTime",new BasicDBObject("$lte", dToN));
cursor = coll.find(find);
int misCount = cursor.count();
But my date comparison code is not working. I am getting count 0 everytime.
What's wrong in this code ?
Update date comparison code as follows :
DBObject dateQuery = BasicDBObjectBuilder.start("$gte", yest).add("$lte", now).get();
find.put("deliveryTime", dateQuery);
So from the conversation chain the problem is that documents in the collection actually have strings in the deliveryTime field. You may have this in a number of places if your code on inserts and updates has been doing similar conversions. Also the internal format is UTC which is probably not what your strings are. The driver is meant to handle this for you.
It is advised that you get your dates converted in your collections and look at all the areas writing or reading as strings.
The following will show how to use date objects and how they will serialize:
Date now = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(now);
cal.add(Calendar.DAY_OF_MONTH, -1);
Date yest = cal.getTime();
BasicDBObject timeNow = new BasicDBObject("now", now );
BasicDBObject timeThen = new BasicDBObject("then" yest)
System.out.println( timeNow );
System.out.println( timeThen );
Note: Though the output displays as below. It's still not passing in a string, but an epoch timstamp on a BSON timestamp type.
{ "this" : { "$date" : "2014-02-06T10:50:05.873Z"}}

How to convert and compare a date string post value with a createcritera filed date in grails?

I use Grails 2.0.3
and am comparing a a date string post value using creatCriteria and i have used below methods to convert the string into date but it always empty ? when i try , i can use params.date() method since i pass only one string ,for searching it can be date in one time ,or it can be number and so on ...
println Date.parse('2013-02-05')
my creatCriteria
def vDate = new Date().parse(query.toString())
{
eq('dateCreated',vDate)
}
what am missing or any alternative ? i still believe that this trivial issue has to be resolved enough for future use?
First of all convert your String to date using this method.
def date = Date.parse('yyyy-MM-dd','2013-02-05')
Now use today start and today end method.
Date getTodayStart( Date inDate){
Calendar cal = Calendar.getInstance()
cal.set(inDate[Calendar.YEAR], inDate[Calendar.MONTH], inDate[Calendar.DATE], 0, 0, 0)
Date todayStart = cal.getTime()
return todayStart
}
Date getTodayEnd(Date inDate){
Calendar cal = Calendar.getInstance()
cal.set(inDate[Calendar.YEAR], inDate[Calendar.MONTH], inDate[Calendar.DATE], 0, 0, -1)
Date todayEnd = cal.getTime() + 1
return todayEnd
}
It will give you object from day start to day end.
Date startDate = getTodayStart(date)
Date endDate = getTodayEnd(date)
Now you can create criteria for date.
{
between('dateCreated',startDate.toString(),endDate.toString())
}
It will give you all date for that day.
you can use
Date vDate = new java.text.SimpleDateFormat("yyyy-MM-dd").parse(query.toString())
If your database column is of type Date then you should not have problem using the way #Kamil has suggested. Although, there is a groovier way of parsing the date string to date.
def date = Date.parse('yyyy-MM-dd','2013-02-05')
assert date instanceof java.util.Date

String to Date Conversion and Date arithmetic

I have a list of strings in my java application that represent dates. The format is yyyy/MM/dd. I want to be able to take all of these strings and convert them to actual date objects so arithmetic can be performed on them.
Basically I want to go through the list and remove dates that have already occurred. I have attached the code.
List<String> datesList = new ArrayList<String>();
datesList.add("2011-11-01");
datesList.add("2015-11-01");
//Get todays date and format it
Calendar currentDate = Calendar.getInstance();
SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd");
//This string will also need to be converted to a date object so the loop arithmetic can be performed.
String today = formatter.format(currentDate.getTime());
System.out.println(today);
for(String date: datesList) {
//The list cannot change from a list of strings.
//So the conversion will probably have to take place in this loop.
System.out.println(date);
//if(date < today) ...
//datesList.remove(date);
}
Updating to include solution:
List<String> datesList = new ArrayList<String>();
datesList.add("2013-11-01");
datesList.add("2011-11-01");
datesList.add("2013-04-29");
datesList.add("2001-05-19");
SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd");
List<String> validDatesList = new ArrayList<String>();
for(String date: datesList) {
Date listItem = formatter.parse(date);
Date todayDate = new Date();
if(todayDate.after(listItem)) {
System.out.println(listItem+" has already happened because today is "+todayDate);
} else{
validDatesList.add(date);
}
}
for(String validDate: validDatesList) {
System.out.println("Valid date: "+validDate);
}
Thanks.
Parse your Date's with this, and then you can compare the date with today's date
Date newDate = formatter.parse(date);
Date todayDate = new Date();
if(todayDate.after(newDate)) {
}
You can use a SimpleDateFormat object to parse a string into a Date object as well:
Date d = formatter.parse(today);, where today is your date in String format.
Then to check if the dare is after today, having gotten the current date as follows:
Date today = currentDate.getTime();
, your if statement would look like:
(if d.after(today)) {
datesList.remove(date);
A quite different and less efficient approach: add today's date to the list, sort the list, and remove all list items whose index is greater/smaller (depending on sort order) than today. Note that this will only work for the date format you specified ("yyyy-MM-dd") (with leading zeroes!) and only makes sense if removing previous dates is the only operation you'd like to do.
I would suggest you to convert date into long, then your work would be much easier.
Date d1 = new Date();//current time
d1.getTime()/1000;//will give you current time as a long value in second.
See epoch/unix time

Categories