How to request by date using SolrJ?
I get as a parameter a date in this format '01/10/2014'. Then I convert this format to a Date object and convert the object to a UTC format. Here is a code example of what I am doing :
public class DateHelper {
public static final String DD_MM_YYYY_FORMAT = "dd/MM/yyyy";
public static final String SOLR_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
public static Date getDateFromString(String date, String format) {
if (StringUtils.isNotEmpty(date)) {
try {
return FastDateFormat.getInstance(format).parse(date);
} catch (ParseException e) {
LOGGER.error(e.getMessage());
}
}
return null;
}
public static String getStringFromDate(Date date, String format) {
if (date != null) {
try {
return FastDateFormat.getInstance(format).format(date);
} catch (Exception e) {
LOGGER.error(e.getMessage());
}
}
return "";
}
public static void main(String...args){
Date dateFromString = DateHelper.getDateFromString('01/10/2014', DateHelper.DD_MM_YYYY_FORMAT);
String date = DateHelper.getStringFromDate(dateFromString, DateHelper.SOLR_DATE_FORMAT);
System.out.println(date);
}
}
This small program displays '2014-10-01T00:00:00Z'. When I try to submit this date in Solr using a filter query, I receive this error from Sorl :
org.apache.solr.client.solrj.impl.HttpSolrServer$RemoteSolrException: Invalid Date String:'2014-10-01T00'
Here is my Solr query :
SolrQuery solrQuery = new SolrQuery("*:*");
String date = String.format( "date:%s",dateInput);
query.addFilterQuery(date);
getSolrServer().query(solrQuery, METHOD.POST);
How can I solve this problem? THx for your help.
P.S : The class FastDateFormat is from Apache Commons Lang 3. I am using solr version 4.8.1.
This happens because of the way filterQuery is created:
String date = String.format( "date:%s",dateInput);
query.addFilterQuery(date);
That way the solr gets:
date:2014-10-01T00:00:00Z
And the exception is thrown because of the multiple : symbols that the Query Parser cannot parse correctly.
In order to fix it the special characters that are part of Query Syntax should be escaped.
From the java side it can be done this way (using ClientUtils.escapeQueryChars from SolrJ):
String date = String.format( "date:%s", ClientUtils.escapeQueryChars(dateInput));
query.addFilterQuery(date);
Syntax to query solr date field -- Date:[YYYY-MM-DDTHH:mm:ssZ]
Related
I'm trying to parse a date departureTime:
String departureTime2, departureTime;
departureTime2 = departureTime = "2018-01-01 11:11:11.1";
Using the JUnit when method
when(bookingController.booking( departureTime, departureTime2).thenAnswer(new Answer<MockHttpSession>()
{
#Override
public MockHttpSession answer(InvocationOnMock invocation) throws Throwable
{
Object[] args = invocation.getArguments();
return (MockHttpSession) args[0];
}
});
My booking method in BookingController
#RequestMapping(value = "/bookingsingle", method = RequestMethod.POST)
public String bookingSingle(#RequestParam String departureTime,..)'
formats the date using
Date departureTimeAsDate = null;
DateFormat df = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss.S", Locale.ENGLISH);
try { departureTimeAsDate = df.parse(departureTime); } catch (ParseException e) { e.printStackTrace(); }
However I receive the error
java.text.ParseException: Unparseable date: "2018-01-01 11:11:11.1"
The date appears to be in the perfect format, and upon using the same code in a Java fiddle tool it compiles, however in intellij it runs into the error. Any suggestions would be appreciated.
EDIT:
I believe the problem may lie somewhere in the passing of the String in the when() method. Note that booking() has many irrelevant parameters I have excluded.
Below is my coding:
private final String TIME_ZONE_ID_TRKD_DEFAULT = "Etc/GMT";
private XMLGregorianCalendar getStartDateTime(boolean startFromZeroHour) {
XMLGregorianCalendar xmlCal = null;
try {
xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar();
} catch (DatatypeConfigurationException e) {
e.printStackTrace();
}
Calendar now = Calendar.getInstance(TimeZone.getTimeZone("Asia/Singapore"));
now.setTimeZone(TimeZone.getTimeZone(TIME_ZONE_ID_TRKD_DEFAULT));
xmlCal.setDay(now.get(Calendar.DAY_OF_MONTH));
xmlCal.setMonth(now.get(Calendar.MONTH) + 1);
xmlCal.setYear(now.get(Calendar.YEAR));
xmlCal.setTime(now.get(Calendar.HOUR_OF_DAY), now.get(Calendar.MINUTE), now.get(Calendar.SECOND));
please kindly advice why it can't convert, and how should i do..
The code cannot be compiled because of an error on the line, where you get the instance of the calendar. I believe you wanted to do this (probably just copy/paste error?):
Calendar now = Calendar.getInstance(TimeZone.getTimeZone("Asia/Singapore"));
A better approach might be the following:
private final String TIME_ZONE_ID_TRKD_DEFAULT = "Etc/GMT";
private XMLGregorianCalendar getStartDateTime(boolean startFromZeroHour) {
XMLGregorianCalendar xmlCal = null;
try {
xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(new GregorianCalendar(TimeZone.getTimeZone(TIME_ZONE_ID_TRKD_DEFAULT)));
} catch (DatatypeConfigurationException e) {
e.printStackTrace();
}
xmlCal.setMillisecond(DatatypeConstants.FIELD_UNDEFINED);
xmlCal.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
if(startFromZeroHour){
xmlCal.setHour(0);
}
return xmlCal;
}
public static void main(String[] args) {
Bug b = new Bug();
XMLGregorianCalendar startDateTime = b.getStartDateTime(true);
System.out.println(startDateTime);
XMLGregorianCalendar startDateTime2 = b.getStartDateTime(false);
System.out.println(startDateTime2);
}
First we create a GregorianCalendar instance using your timezone constant. It represents the current time (now) if the default constructor is used.
Then we use it to initialize the XMLGregorianCalendar.
You don't want to have the milliseconds and the timezone part, so we just unset them using DatatypeConstants.FIELD_UNDEFINED as stated in the JavaDoc https://docs.oracle.com/javase/7/docs/api/javax/xml/datatype/XMLGregorianCalendar.html#setMillisecond(int) .
I added a part setting the hour to zero if startFromZeroHour is set to true. It was not part of your code so you might want to remove or change it.
I am trying to change the following code, to be better used in an Android environment as part of an upcoming API.
public class DateFormatter implement JsonDeserializer<Date>,
JsonSerializer<Date> {
private final DateFormat[] formats;
public DateFormatter() {
formats = new DateFormat[3];
formats[0] = new SimpleDateFormat(DATE_FORMAT);
formats[1] = new SimpleDateFormat(DATE_FORMAT_V2_1);
formats[2] = new SimpleDateFormat(DATE_FORMAT_V2_2);
final TimeZone timeZone = TimeZone.getTimeZone("Zulu"); //$NON-NLS-1$
for (DateFormat format : formats)
format.setTimeZone(timeZone);
}
public Date deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
JsonParseException exception = null;
final String value = json.getAsString();
for (DateFormat format : formats)
try {
synchronized (format) {
return format.parse(value);
}
} catch (ParseException e) {
exception = new JsonParseException(e);
}
throw exception;
}
public JsonElement serialize(Date date, Type type,
JsonSerializationContext context) {
final DateFormat primary = formats[0];
String formatted;
synchronized (primary) {
formatted = primary.format(date);
}
return new JsonPrimitive(formatted);
}
}
I do not need to support v2.1 and v2.2. so I've been trying to remove the array, and code it for just a single instance. I'm running into some errors though.
Here is what I have so far:
class DateFormatter implements JsonDeserializer<Date>,
JsonSerializer<Date> {
private DateFormat formats;
DateFormatter() {
formats = new DateFormat;
formats = new SimpleDateFormat(String.valueOf(R.string.date_format), Locale.ENGLISH);
final TimeZone timeZone = TimeZone.getTimeZone("Zulu");
for (DateFormat format : formats)
format.setTimeZone(timeZone);
}
public Date deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
JsonParseException exception = null;
final String value;
value = json.getAsString();
for (DateFormat format : formats)
try {
synchronized (format) {
return format.parse(value);
}
} catch (ParseException e) {
exception = new JsonParseException(e);
}
throw exception;
}
public JsonElement serialize(Date date, Type type,
JsonSerializationContext context) {
final DateFormat primary;
primary = formats;
String formatted;
synchronized (primary) {
formatted = primary.format(date);
}
return new JsonPrimitive(formatted);
}
}
However, once I get it this point, I get errors. The main one I'm currently concerned about is getString.
What am I doing wrong here?
Edit:
#trooper I am not able to build the project, so I can't pull a --stacktrace --debug
I changed the 2nd code block in the post to reflect my current code. I changed;
formats = new SimpleDateFormat(getString(R.string.date_format), Locale.ENGLISH);
to;
formats = new SimpleDateFormat(String.valueOf(R.string.date_format), Locale.ENGLISH);
and that corrected my first question.
So, now that is answered, moving on to my next question. As you can see I'm moving from an array in the first block to a single instance in the second. the line
for (DateFormat format : formats)
the "formats' is throwing a "foreach not applicable to java.text.DateFormat'
I know foreach is used in arrays, what I don't know is how to remove that part of the loop and achieve what i need to... this is where I get really lost.
My end goal is to Convert the current GitHib APIv3 written in Java for the Eclipse Studio which supports API v2 & v3, over to an Android GitHub API v3, seeing as we won't need to cover v2.
I hope this edit is enough information to be able to answer.
Formats is not declared as an array. You need to declare this as an array an initialize it one by one.
try this,
private final DateFormat[] formats
formats = new DateFormat[3];
formats[0] = new SimpleDateFormat(getString(R.string.date_format), Locale.ENGLISH);
to remove the loop just use
formats = new DateFormat;
formats = new SimpleDateFormat(String.valueOf(R.string.date_format), Locale.ENGLISH);
final TimeZone timeZone = TimeZone.getTimeZone("Zulu");
formats.setTimeZone(timeZone);
I am trying to search for date of birth using query
criteria = Criteria.where("dob").lte(new DateTime().toDate());
And spring data mongodb generate below query:
MongoTemplate: find using query:
{ "dob" : { "$lte" : { "$date" : "2015-05-16T07:55:23.257Z"}}}
fields: null for class: class com.temp.model.User in collection: user
But I did not get any result.
My dob field in mongodb:
{"dob" : ISODate("1991-01-23T00:00:00Z")}
How I can search for dob in ISODate format ?
This code should work fine for what you need:
criteria = Criteria.where("dob").lte(new java.util.Date());
My test is with following code, which does work fine:
Lis<User> users = mongoOps.find(query(where("isActive").is(true).and("CreatedDate").lte(new java.util.Date())), User.class);
Query would execute perfect from Spring data mongodb0
{ "dob" : { "$lte" : { "$date" : "2015-05-16T07:55:23.257Z"}}}.
But It will not execute from mongo CLI.
Query to execute on cli.
{dob:ISODate("2015-05-15T07:55:23.257Z")}
Thanks
For IDE use ISODate() for SPRING DAO convert string to Date object
query.addCriteria(Criteria.where("created").ne(null).andOperator(
Criteria.where("created").gte(DateUtils.getDate("2016-04-14 00:00:00", DateUtils.DB_FORMAT_DATETIME)),
Criteria.where("created").lte(DateUtils.getDate("2016-04-14 23:59:59", DateUtils.DB_FORMAT_DATETIME))
));
public final class DateUtils {
public static final String DB_FORMAT_DATETIME = "yyyy-M-d HH:mm:ss";
private DateUtils() {
// not publicly instantiable
}
public static Date getDate(String dateStr, String format) {
final DateFormat formatter = new SimpleDateFormat(format);
try {
return formatter.parse(dateStr);
} catch (ParseException e) {
return null;
}
}
}
val query = Query()
query.addCriteria(
Criteria("info.dob").gte(dob.atStartOfDay())
I'm having some trouble writing properties of a cq:PageContent. releaseDate (type Date) is giving me some trouble. The following method is from a sling-junit test where I'm calling from a #Before method.
private void setNewsReleaseDate(Resource res, int month)
throws InvalidDateException {
String date = "2014-%sT11:31:00.000-04:00"; //07-23
Calendar rd = DateUtil.parseISO8601(String.format(date, "0"+month+"-23")); //iso8601Date
ModifiableValueMap modMap = res.adaptTo(ModifiableValueMap.class);
if (modMap != null) {
modMap.put("releaseDate", rd); // this is a Date property
/* also tried below, which also fails
modMap.put("releaseDate", String.format(date, "0"+month+"-23"));
*/
}
}
I get this error...
Value for key releaseDate can't be put into node:java.util.GregorianCalendar[time=1406129460000,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="GMT-04:00",offset=-14400000,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2014,MONTH=6,WEEK_OF_.... ]
I changed the method by passing in the page, and then get the /jcr:content below the page that I wanted to edit the properties of...
private void setNewsReleaseDate(Page page, int month) throws InvalidDateException{
LOGGER.info("change prop at page path "+page.getPath());
Resource res = rr.getResource(page.getPath()+"/jcr:content");
String date = "2014-%sT11:31:00.000-04:00"; //07-23
Calendar rd = DateUtil.parseISO8601(String.format(date, "0"+month+"-23")); //iso8601Date
ModifiableValueMap modMap = res.adaptTo(ModifiableValueMap.class);
if (modMap != null) {
modMap.put("releaseDate", rd); // this is a Date property
modMap.put("notes", "hello"); // a string property
}
}