How to compare Date in criteriaBuilder.greaterThan()? - jpa

I'm fixing a bug in JAVA/Angular Project, I'm getting a Date in Millisecodes from the front End, then I change the date from Millisecondes to "yyyy MM dd HH:mm:ss" format using SimpleDateFormat class in JAVA.
I want to compare the date that I'm getting from the front end with a field in a Table in my DataBase using criteriaBuilder.greaterThan().
The type of the field is bigInit(20).
I proposed as a solution to compare the dates using TimesTamp type, but the request from the client is a comparaison using Date in JAVA
public Specification<T> greater(Object value, String field, String type) {
return (root, criteriaQuery, criteriaBuilder) -> {
Path tuple = getPath(root, field);
System.out.println("type" + tuple.getJavaType());
if (tuple.getJavaType().isAssignableFrom(Date.class)) {
return criteriaBuilder.greaterThan(tuple, convertFilterDateToDate(value.toString()));
}
return criteriaBuilder.greaterThan(getPath(root,field),Double.valueOf(value.toString()));
};
}
This method takes 3 parametrs :
Object value : its type is Long in my case, it is the value of the date taken from the front End, I wrote a method to convert the value from Long to Date using SimpleDateFormat.
String field: its the field in my table, it contains dates with type Long.
String Type: it contains the value 'endDate' in my case.
Below, the definition of getPath Method :
public Path getPath(Root<T> root, String field){
String fiedls[] = field.split("\\.");
if(!field.contains(".")){
System.out.print(root.get(field));
return root.get(field);
}
else if (fiedls.length==2){
Join<Operation,Object> join = root.join(fiedls[0]);
return join.get(fiedls[1]);
}
else if(fiedls.length==3){
Join<Operation,Object> join = root.join(fiedls[0]);
Join<Object,Object> join1 = join.join(fiedls[1]);
return join1.get(fiedls[2]);
}
return null;
}
The request is to compare date using Date type in java and criteriaBuilder.greaterThan() , any Idea ?

Related

Nuget.Versioning.SemanticVersion.ToString(format) examples?

I can't seem to find any documentation anywhere on what formats one can pass in to .ToString() on NuGet.Versioning.SemanticVersion. The value seems to be indexing into a list of _formatters but there's no docs on what values are available by default, what the default behavior is, how to tweak it, etc.
e.g. this is all that's in the source code:
//
// Summary:
// Gives a normalized representation of the version. This string is unique to the
// identity of the version and does not contain metadata.
public virtual string ToNormalizedString()
{
return ToString("N", VersionFormatter.Instance);
}
//
// Summary:
// Gives a full representation of the version include metadata. This string is not
// unique to the identity of the version. Other versions that differ on metadata
// will have a different full string representation.
public virtual string ToFullString()
{
return ToString("F", VersionFormatter.Instance);
}
//
// Summary:
// Get the normalized string.
public override string ToString()
{
return ToNormalizedString();
}
//
// Summary:
// Custom string format.
public virtual string ToString(string format, IFormatProvider formatProvider)
{
string formattedString = null;
if (formatProvider == null || !TryFormatter(format, formatProvider, out formattedString))
{
formattedString = ToString();
}
return formattedString;
}
Anybody know where I can find this?
You were so close to finding the list of format characters yourself!
The first two methods you copied into your question reference a property VersionFormatter.Instance. Looking at the VersionFormatter class, the Format method enumerates the list of characters it handles: https://github.com/NuGet/NuGet.Client/blob/08a7a7bd17e504d808329dcc1ffc866d9f59d040/src/NuGet.Core/NuGet.Versioning/VersionFormatter.cs#L65-L101
character
method
N
AppendNormalized(builder, version);
V
AppendVersion(builder, version);
F
AppendFull(builder, version);
R
builder.Append(version.Release);
M
builder.Append(version.Metadata);
x
builder.Append(version.Major);
y
builder.Append(version.Minor);
z
builder.Append(version.Patch);
r
builder.Append(version is NuGetVersion nuGetVersion && nuGetVersion.IsLegacyVersion ? nuGetVersion.Version.Revision : 0);

How to get the latest date time from the 2 dates | Flutter

I have 2 dates with time. I want to get the latest date from these 2 dates.
for example, 1st date and time is "2021-07-14 11:13:02" and 2nd is "2021-04-25 10:24:08". From these i want to find the latest date. How can i get this in Flutter and Dart.
You can do by using DateTime.parse and isAfter(), isBefore() method.
void main() {
print(getLatestDate('2021-07-14 11:13:02', '2021-04-25 10:24:08'));
}
DateTime getLatestDate(String a, String b) {
DateTime dateA = DateTime.parse(a);
DateTime dateB = DateTime.parse(b);
if (dateA.isBefore(dateB)) {
return dateB; // If you want String, return b
} else {
return dateA; // If you want String, return a
}
}

Build dynamic LINQ queries from a string - Use Reflection?

I have some word templates(maybe thousands). Each template has merge fields which will be filled from database. I don`t like writing separate code for every template and then build the application and deploy it whenever a template is changed or a field on the template is added!
Instead, I'm trying to define all merge fields in a separate xml file and for each field I want to write the "query" which will be called when needed. EX:
mergefield1 will call query "Case.Parties.FirstOrDefault.NameEn"
mergefield2 will call query "Case.CaseNumber"
mergefield3 will call query "Case.Documents.FirstOrDefault.DocumentContent.DocumentType"
Etc,
So, for a particular template I scan its merge fields, and for each merge field I take it`s "query definition" and make that request to database using EntityFramework and LINQ. Ex. it works for these queries: "TimeSlots.FirstOrDefault.StartDateTime" or
"Case.CaseNumber"
This will be an engine which will generate word documents and fill it with merge fields from xml. In addition, it will work for any new template or new merge field.
Now, I have worked a version using reflection.
public string GetColumnValueByObjectByName(Expression<Func<TEntity, bool>> filter = null, string objectName = "", string dllName = "", string objectID = "", string propertyName = "")
{
string objectDllName = objectName + ", " + dllName;
Type type = Type.GetType(objectDllName);
Guid oID = new Guid(objectID);
dynamic Entity = context.Set(type).Find(oID); // get Object by Type and ObjectID
string value = ""; //the value which will be filled with data from database
IEnumerable<string> linqMethods = typeof(System.Linq.Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).Select(s => s.Name).ToList(); //get all linq methods and save them as list of strings
if (propertyName.Contains('.'))
{
string[] properies = propertyName.Split('.');
dynamic object1 = Entity;
IEnumerable<dynamic> Child = new List<dynamic>();
for (int i = 0; i < properies.Length; i++)
{
if (i < properies.Length - 1 && linqMethods.Contains(properies[i + 1]))
{
Child = type.GetProperty(properies[i]).GetValue(object1, null);
}
else if (linqMethods.Contains(properies[i]))
{
object1 = Child.Cast<object>().FirstOrDefault(); //for now works only with FirstOrDefault - Later it will be changed to work with ToList or other linq methods
type = object1.GetType();
}
else
{
if (linqMethods.Contains(properies[i]))
{
object1 = type.GetProperty(properies[i + 1]).GetValue(object1, null);
}
else
{
object1 = type.GetProperty(properies[i]).GetValue(object1, null);
}
type = object1.GetType();
}
}
value = object1.ToString(); //.StartDateTime.ToString();
}
return value;
}
I`m not sure if this is the best approach. Does anyone have a better suggestion, or maybe someone has already done something like this?
To shorten it: The idea is to make generic linq queries to database from a string like: "Case.Parties.FirstOrDefault.NameEn".
Your approach is very good. I have no doubt that it already works.
Another approach is using Expression Tree like #Egorikas have suggested.
Disclaimer: I'm the owner of the project Eval-Expression.NET
In short, this library allows you to evaluate almost any C# code at runtime (What you exactly want to do).
I would suggest you use my library instead. To keep the code:
More readable
Easier to support
Add some flexibility
Example
public string GetColumnValueByObjectByName(Expression<Func<TEntity, bool>> filter = null, string objectName = "", string dllName = "", string objectID = "", string propertyName = "")
{
string objectDllName = objectName + ", " + dllName;
Type type = Type.GetType(objectDllName);
Guid oID = new Guid(objectID);
object Entity = context.Set(type).Find(oID); // get Object by Type and ObjectID
var value = Eval.Execute("x." + propertyName, new { x = entity });
return value.ToString();
}
The library also allow you to use dynamic string with IQueryable
Wiki: LINQ-Dynamic

How can the ToDate be kept after the FromDate in a table record?

I have a table with two fields: FromDate and ToDate. I want to make sure that the ToDate value is always later than the FromDate value.
To do this, I want to set the ToDate value to the FromDate value + 1. To do this I have implemented the following code in the validateField method of the table:
boolean ret;
ret = super(_fieldIdToCheck);
if (ret)
{
switch (_fieldIdToCheck)
{
case fieldNum(MyTable, FromDate):
this.ToDate = this.FromDate + 1;
}
}
return ret;
This implementation works well, but the value of ToDate can be changed to a value before FromDate. How can this be prevented?
As Alex said, use the table method modifiedField to do field dependant modifications.
If you change the field by code remember to call the method yourself.
Maybe you should make the assignment conditional to avoid overwriting user entered date. This will also work well if ToDate is initially null.
public void modifiedField(FieldId _fieldId)
{
super(_fieldId);
switch(_fieldId)
{
case fieldNum(MyTable, FromDate):
case fieldNum(MyTable, ToDate):
if (this.ToDate < this.FromDate) // mostly first time
this.ToDate = this.FromDate + 1;
break; // don't forget the break
}
}

MongoDB DateTime Format

In mongodb adhoc query, before executing the query, how to format the date type element to dd\mm\yyyy format and then execute the query?
I solved this by inserting the datetime as integer using the getTime() method in java.
EG:
Date dt=new Date();
long integer_date=dt.getTime();
I used the above line of code to insert date as integer.With this it was easy to fetch records between a particular date.
I asked a similar question a little while back...this might be what you're looking for: What is the syntax for Dates in MongoDB running on MongoLab?
If you are using Java, you can create Date objects from strings using the parse method of the DateFormat class.
The Java documentation on the DateFormat Class may be found here:
http://docs.oracle.com/javase/1.4.2/docs/api/java/text/DateFormat.html
The specific section on the parse method is here:
http://docs.oracle.com/javase/1.4.2/docs/api/java/text/DateFormat.html#parse%28java.lang.String%29
The Java documentation on the Date object may be found here:
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Date.html
As per the "Constructor Summary" section, the ability to pass a string into the constructor is "Deprecated. As of JDK version 1.1, replaced by DateFormat.parse(String s)."
While I was researching the above, I also came across the Calendar class, which may be used for converting a Date object and a set of integers. It may not be necessary for this application, but I thought it might be useful to include a link to the documentation:
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Calendar.html
Integers for year, month, day, hour, etcetera may be passed in via the set method:
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Calendar.html#set%28int,%20int,%20int,%20int,%20int%29
By way of example, here is a short Java Program that creates a number of Date objects, stores them in a Mongo collection, and then executes a query similar to what you have described. Hopefully it will help you to accomplish your goal. NOTE: This program drops a collection named "dates", so be sure to change the collection name if you already have such a collection in your database!
public static void main(String[] args) throws UnknownHostException, MongoException {
Mongo m = new Mongo( "localhost:27017" );
DB db = m.getDB("test");
DBCollection coll = db.getCollection("dates");
coll.drop();
DateFormat df = DateFormat.getInstance();
String dateString = new String();
Date myDate = new Date();
// Save some test documents
for(int i=1; i<11; i++){
dateString = "04/" + String.valueOf(i) + "/12 11:00 AM, EST";
BasicDBObject myObj = new BasicDBObject("_id", i);
try {
myDate = df.parse(dateString);
} catch (ParseException e) {
e.printStackTrace();
}
myObj.put("date", myDate);
System.out.println(myDate);
coll.save(myObj);
}
// Build the query
Date startDate = new Date();
Date endDate = new Date();
try {
startDate = df.parse("04/4/12 11:00 AM, EST");
endDate = df.parse("04/6/12 11:00 AM, EST");
} catch (ParseException e) {
e.printStackTrace();
}
BasicDBObject dateQuery = new BasicDBObject();
dateQuery.put("$gte", startDate);
dateQuery.put("$lte", endDate);
System.out.println("---------------");
//Execute the query
DBCursor myCursor = coll.find(new BasicDBObject("date", dateQuery));
//Print the results
while(myCursor.hasNext()){
System.out.println(myCursor.next().toString());
}
}
This is use full to format code to date format from simple date time format and the reverse steps also supporting this way to retrieve date from MongoDB.
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date fDate = formatter.parse((String) metaData.getValue());
newMeta.setValue(fDate);[![In this image you can see how is the save scenario process in mongoDB][1]][1]
Date class has a before(date) or after(date) method... It is easy to use: no conversion to seconds/milliseconds.
public void execute(Tuple input) {
try {
date=(Date) input.getValueByField("date");
boolean before = date.before(myDate); // compare the data retrieved with your date.
if (before) {
...
} else {
...
}
} catch (Exception e) {
logger.error("Error...", e);
}
This approach is easier than the accepted answer..