Compare dates with Spring Data neo4j - date

When querying for relationships on a java.util.Date property, what syntax should I use? I tried just using a query like (this is just an example to show what I'm trying to do, so please don't pay attention to variable names there):
#Query("start n1=node({0}) match n1-[r:TYPE]->n2 where r.dateCreated>={1} return r")
Page<Relationship> findAll(Node node, long date, Pageable pager);
But it throws the following error:
Caused by: Don't know how to compare that. Left: 1339845862883; Right: 1339827156836
at org.neo4j.cypher.internal.Comparer$class.compareValuesOfDifferentTypes(Comparer.scala:45)
at org.neo4j.cypher.internal.Comparer$class.compare(Comparer.scala:67)
at org.neo4j.cypher.commands.ComparablePredicate.compare(ComparablePredicate.scala:30)
at org.neo4j.cypher.commands.ComparablePredicate.isMatch(ComparablePredicate.scala:41)
at org.neo4j.cypher.internal.pipes.matching.PatternMatcher$$anonfun$isMatchSoFar$1.apply(PatternMatcher.scala:148)
at org.neo4j.cypher.internal.pipes.matching.PatternMatcher$$anonfun$isMatchSoFar$1.apply(PatternMatcher.scala:148)
I also tried by passing a Date but it just throws the same error but trying to compare a Long and a Date.
I am using spring-data-neo4j version 2.0.1.RELEASE

So the date property's long value is stored as a string in the graph (in newer versions of SDN you can define a #GraphProperty(targetType=long.class) on date fields.
So comparison will work if you pass in the parameter value as String.valueOf(longValue)

Related

How do you parse basic (short/compact) ISO:8601 string with Joda?

I have a time string, which looks like this: 20170822T194135+00. This is called basic ISO:8601 format, if I understood correctly.
When I try to parse it using ZonedDateTime, it throws exception, complaining that it can't parse it.
SO, how do I convert this string to a valid Joda datetime object?
Do I need to build manual "format" to parse it (this would be silly, considering it's a standard format)?
Desperately, I've actually tried to implement custom format:
const time = ZonedDateTime.parse(timeString, DateTimeFormatter.ofPattern(`yyyyMMdd'T'HHmmssZ`));
But, it throws error on column 15. Looks like it fails to parse the timezone. Is my implementation correct? How do I make it work?
I could do it using the pattern x as described in the docs (this pattern accepts offsets like +00).
Then I parsed directly to a ZonedDateTime:
const formatter = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmssx");
const time = ZonedDateTime.parse("20170822T194135+00", formatter);
The resulting time variable has the value equivalent to 2017-08-22T19:41:35Z.
The built-in formatters (such as ISO_LOCAL_DATE_TIME) can't parse this format, so the only way seems to be creating a formatter.

Get a DateTime with an specific pattern with nscala-time

I am trying to get this pattern 'dd-MM-yyyy' with a variable of type DateTime
#{DateTimeFormat.forPattern("dd-MM-YYYY").parseDateTime(user.birthday.toString)}
But I am getting this error
java.lang.IllegalArgumentException: Invalid format: "2015-12-10T00:00:00.000Z" is malformed at "15-12-10T00:00:00.000Z"
Is there a way to do this with nscala-time?
makes a difference if I am using UTC?
UPDATE
For the moment I am casting to Date and doing this
#{Dates.format(user.birthday.toDate, "dd-MM-YYYY")}
But maybe is a better way without casting
thank you
So, if I understood your question correctly, you are trying to achieve the following:
Parse date from a string using a date format
Print/Display the date in another format.
Try the below:
#{Dates.format(DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ").parseDateTime(user.birthday.toString), "dd-MM-YYYY")}

Talend Context variable

I am a newbie Talend developer, need a help with context variables. I searched here if there is a solution for similar approach, didnt find it.
In my query I have to use this date range function:
Date BETWEEN to_char((add_months(TRUNC(SYSDATE,'MM'),-2)),'YYYYMMDD')
AND to_char(LAST_DAY(TRUNC(SYSDATE,'MM')),'YYYYMMDD')
We need to use context variable to take advantage to run different date range during runtime. Above function, I replaced in the query with (date between ="+context.daterange+") and trying to plug these functions to Context - value as tree as below:
to_char((add_months(TRUNC(SYSDATE,'MM'),-5)),'YYYYMMDD')'AND'to_char(LAST_DAY(TRUNC(SYSDATE,'MM')),'YYYYMMDD'), I get below error:
java.sql.SQLException: ORA-00905: missing keyword
If I use hard coded value on "Value as tree" context as below then works
"'20150301'and'20150831'"
Trying to replace this with the function. How can I combine that function with AND.
My tJavacode has
context.DATE = (String)row1.NDate;
Can you please help?
Thanks
Date cannot be between two texts. Since your context variables is a String then use to_date function:
"select ... where my_date between to_date("
+TalendDate.formatDate("ddMMyyyy",TalendDate.addDate(new Date(), 2, "MM"))+
",'DDMMYYYY') and
+TalendDate.formatDate("ddMMyyyy",TalendDate.addDate(new Date(), 5, "MM"))+
");"

Problems with query using timespan

I am doing a manual query to my postgresql database (using OrmLiteReadConnectionExtensions.SqlList<T>) that has a TimeSpan argument.
SericeStack.Ormlite is converting TimeSpan to ::time instead of ::interval as I would expect it.
More specifically: TimeSpan.FromDays(3) is converted to ((E'00:00:00.000000')::time)(taken form pg logs).
Is there a work around for this?
My current work-around is to use the C# string.Format for this problematic parameter instead of the safe and recommended™ #paramname supported by SqlList<T>.
This could be considered dangerous, but since the parameter is a double, I'm probably Okay.
The relevant part of the string is:
string.Format(CultureInfo.InvariantCulture, "RESTOFTHEQUERY ('{0:0.####} seconds'::interval) RESTOFTHEQUERY", timespan.TotalSeconds);
Don't forget to use CultureInfo.InvariantCulture.
For what it's worth, you can just cast a time value to interval. Demo
SELECT now()::time::interval
So append ::interval in your manual query and you should be fine - except for intervals > 24 hours of course.

Why do I need to parse dates in Grails?

I am in the unfortunate position that I need to use a composite id in a Grails app where I work with legacy data. This means I have to override some actions in the controller, but as I did this I was struck by the fact that I could not use use a date argument directly as a parameter to a dynamic method.
Instead of just doing MyLegacyObj.findBySystemIdAndLogDate(params.systemId, params.logDate), I first needed to parse the date string before giving it to the dynamic method. To further complicate matters I had no idea what format the date string had (until I added lots of log.debug() string to the output). So now I have a bit of code looking like this
def formatter = new SimpleDateFormat("EEE MMM d HH:mm:ss z yyyy")
MyLegacyObj.findBySystemIdAndLogDate(params.systemId, formatter.parse(params.logDate));
This feels unoptimal, no to say dangerous (what if the date format changes with the locale?)? What would be a recommended way of doing this, and do I really need to parse dates at all?
Date is a pretty complex object and params are just Strings, so Date is submitted in parts. It is "magically" assembled from the parts when assigning x.properties = params.
Command object will do the work for you, if you add a Date field to it.
It has nothing to do with methods' dynamic or static invocation. Your GSP that renders Date editor might interfere too.