Google Endpoint - java.sql.Timestamp - JSON - java

How to pass java.sql.Timestamp as JSON from front-end?
By default, I tried giving like 2015-09-29T12:30:00 in API explored.
It is not working.
Also, if anyone know, how to use #ApiTransformer for in-build java classes. OR is there an option to use this annotation at property level instead of POJO class level.
Answer:
Timestamp timestamp = new Timestamp(new Date().getTime());
ObjectMapper mapper = new ObjectMapper();
try {
String jacksonDate = mapper.writeValueAsString(timestamp);
System.out.println("JSON Timestamp: "+jacksonDate);
System.out.println("JAVA Timestamp: "+mapper.readValue(jacksonDate, Timestamp.class));
} catch (IOException e) {
e.printStackTrace();
}
output:
JSON Timestamp: 1443772585286
JAVA Timestamp: 2015-10-02 11:56:25.286
Even it accepts: yyyy-MM-DD'T'HH:mm:ss

I suggest you to think doing the opposite.
Let's say you get values from database to java beans (POJO) and serialize them to JSON objects. Print them out especially Timestamp values.
Then use the same format values as a short-cut answer.
On the other hand, in Jackson, I know that java.sql.Date accepts "long" values of time measure. Timestamp may use the same approach. "time in milliseconds" is a long value though.
On the other hand if you look for handling marshalling and unmarshalling of types in Rest systems you can check this out.
http://www.developerscrappad.com/2308/java/java-ee/rest-jax-rs/java-rest-jax-rs-2-0-how-to-handle-date-time-and-timestamp-data-types/

Related

Using JDBC with MongoDB to query Dates that are stored in String

So, as in the title, I have the following example Document in my MongoDB database:
{"_id":{"$oid":"5fcf541b466a3d10f55f8241"}, "dateOfBirth":"1992-11-02T12:05:17"}
As you can see, the date is stored as a String and not as an ISODate object. As far as I know, MongoDB should be able to still handle and query it as a Date. (source)
Thus, I am trying to query it in my java app with JDBC in the following way:
java.util.Date queryDate = new GregorianCalendar(1980, Calendar.JANUARY, 1).getTime();
Bson query = Filters.gte("dateOfBirth", queryDate);
FindIterable<Document> result = collection.find(query);
However, this does not work. My thought process was, if I pass in a java.util.Date, then the Filters.gte() method will know i mean to query a Date and it will work as intended in MongoDB. However, I get 0 matches.
I also tried putting a formatter on my queryDate (for a different purpose, before):
DateFormat dformat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
Bson query = Filters.gte("dateOfBirth", dformat.format(queryDate));
However, this caused the Filters.gte() to query it as Strings, according to String-Comparison, so alphabetical order roughly. This made me think initially that the original java.util.Date version did/should indeed know then, that I queried a Date and not a String, it just somehow failed to convert the one in the database to a date-type? I'm unsure how it should work.
I understand this is a niche case usage, and that I really should insert dates as ISODate in mongoDB, however in my special case right now, this is not an option.
Is there a way to query dates stored as Strings in MongoDB if I am using JDBC?
Minor point: You are using the Java connector for MongoDB. JDBC drivers are for relational databases which use the SQL query language. I therefore changed the JDBC tag to Java in your question.
Working with Dates as Strings
Regarding the datetime format in your documents: Because of the format you are using, and because it is stored as a string, it is OK to use string comparisons when running your queries. Lexical ordering will ensure your string comparisons will be equivalent to datetime comparisons. This is what is being used by the code in the question you linked to.
Obviously this assumption will break if you have any data stored in other string formats, such as "dd-MM-yyyy", where the string ordering would not match the datetime ordering.
However you proceed, you should avoid the old and problematic Java Date and Calendar classes. Instead, use the modern java.time classes. More background here.
In your case, your documents are storing datetime data without any timezone or offset information. You can use java.time.LocalDateTime for this. The word "local" in this name actually means "no specific locality or timezone" - which matches what you have in your Mongo documents.
The Java imports:
import java.time.LocalDateTime;
import java.time.Month;
import java.time.format.DateTimeFormatter;
And an example local datetime:
LocalDateTime ldt = LocalDateTime.of(1980, Month.JANUARY, 1, 0, 0);
DateTimeFormatter dtf = DateTimeFormatter.ISO_DATE_TIME;
String s = ldt.format(dtf); // "1980-01-01T00:00:00"
Working with Dates as Objects
If you want to use a Java LocalDate object directly in your query, instead of using string comparisons, you can use a projection to create a date object in your query results, and then use the Java LocalDate object directly in your filter:
Bson resultsWithDate = Aggregates.project(Projections.fields(
Projections.include("dateOfBirth"),
Projections.computed("birthDate", Projections.computed("$toDate", "$dateOfBirth"))
));
The above projection adds a new dateOfBirth field to each retrieved document, and populates it via the $toDate operator.
Then we can apply our filter:
collection.aggregate(
Arrays.asList(
resultsWithDate,
Aggregates.match(Filters.gte("birthDate", ldt)))
).forEach(printConsumer);
The filter now uses our ldt object, from above.
I am using the following helper method to print each results document as a JSON string in my console:
Consumer<Document> printConsumer = (final Document document) -> {
System.out.println(document.toJson());
};
There may be a more compact or efficient way to build this MongoDB aggregate - I am not a regular Mongo user.
Also, as a final note: My use of the Mongo $toDate operator does not specify a timezone - so it defaults to Zulu time (UT timezone), as shown in the sample output below:
{
"_id": {
"$oid": "5fcf541b466a3d10f55f8241"
},
"dateOfBirth": "1992-11-02T12:05:17",
"birthDate": {
"$date": "1992-11-02T12:05:17Z"
}
}

How to format date field in JSON POST request to insert into SQL database?

I need to send a POST request with the following JSON body:
{
"date": "2020-08-21"
}
The date field has java.sql.Date type. This request results in an error which says that it could not deserialize the given string "2020-08-21" to sql.Date. If I change the JSON by adding some kind of time:
{
"date": "2020-08-21 00:00:00"
}
It works fine. However, I would like to be able to send only Date values without the time, and be able to convert it to sql.Date. Any ideas on how to work around this? I would really not like to use a String for date and then map it to Date. Are there better ways to do this?

Converting java.util.Date to Java.sql.Date using Javalin

I am creating a web app using Java (Javalin and Maven) for university.
We have to make a website for movie bookings and I am struggling to find out how to properly convert dates so that they are readable by SQL and Java.
I have to store date values in a database and to this point I have just been storing them as a string but I want it to have a more specific date meaning. It is built using the MVC model.
This is the code in my sessions model.
public void setSessionDate(Date sessionDate) {
java.sql.Date date = new java.sql.Date(sessionDate.getTime() );
this.sessionDate = sessionDate;
That is the code in my SessionsDao file.
stm.setDate(3, new java.sql.Date(sessions.getSessionDate().getTime()));
And finally this is the code in my SQL create field.
sessionDate DATE not null,
When I try to create a new movie session this is the error the console prints.
[qtp198903030-30] WARN io.javalin.Javalin - Uncaught exception
io.javalin.core.validation.MissingConverterException: Can't convert to Date. Register a converter using JavalinValidation#register.
at io.javalin.core.validation.Validator$Companion.create(Validator.kt:35)
I am unsure how to convert the date properties correctly.
Any help or other methods on how to proceed would be greatly helpful!

How do I cast FieldValue.serverTimestamp() to Kotlin/Java Date Class

I want to save the date that a post was created in Firestore but I do not want to use the System time. Rather I want to use the server timestamp for accuracy sake. So I am using FieldValue.serverTimestamp() to get the server timestamp but the data type of my variable that holds this is Date. So How can I cast FieldValue.serverTimestamp() to Date?
Below is how my data class looks
data class MyModel( var timeStamp: Date,
constructor(): this(Calendar.getInstance().time, "")
}
PS: When I declare the timestamp as FieldValue in the data class, I get the error below:
java.lang.RuntimeException: No properties to serialize found on class
com.google.firebase.firestore.FieldValue
You get the following error:
java.lang.RuntimeException: No properties to serialize found on class com.google.firebase.firestore.FieldValue
Because FieldValue is not a supported data type. You should use the Date class or any other class that extends Date class, for example Timestamp class.
How do I cast FieldValue.serverTimestamp() to Kotlin/Java Date Class
There is no need to do any cast. In Java there is even no need to initialize the timeStamp field. To make it work, you should only use an annotation, as explained in my answer from the following post:
ServerTimestamp is always null on Firebase Firestore
Edit:
In Kotlin, you should initialize your timeStamp field in the constructor with a null value like this:
data class MyModel(
#ServerTimestamp
val timeStamp: Date? = null)
You can make use of an object to hold this value and later while using this value check the type of the object and make use of it. As of my knowledge the datatype returned is Long and you have to convert it manually to Data if you need.
The code for this will look like this,
replace this
data class MyModel( var timeStamp: Date,
with
data class MyModel( var timeStamp: Object,
And when using this timeStamp anywhere check it's type.
In java it will look like
if (timeStamp instanceof Long) {
// change Long to Date
//do this
}else{
//do something else
}
set the value for timeStamp as FieldValue.serverTimestamp() itself.
model class
data class MyModel(
#get: PropertyName("timestamp") #set: PropertyName("timestamp") var timestamp: Date= Date()
)
when initialize it;
val model = MyModel().apply{
this.timestamp to FieldValue.serverTimestamp()
}

Converting (.net) BsonDocument string into a (java) DBObject

In a publishing flow I need to insert a DBObject into a mongo db collection using Java.
I receive the object as a String, and this has been passed to me from a .NET application that used article.ToBsonDocument().ToJson() on a POCO.
On my side of the flow, in Java, I tried just using BasicDBObject doc = (BasicDBObject) JSON.parse(content); but I get a com.mongo.util.JSONParseException on a Date:
"CreationDate" : ISODate("2013-03-18T08:50:53Z")
I can change how the content is generated in C#, and I can change how to write to the DB in java, my only constraint is that it must be passed as a string between the two systems.
Any suggestions?
EDIT Thanks to the tip from #Jim Dagg below, some googling for ISODate and BsonDocument turned out this gem. Changing the c# code to use
article.ToBsonDocument().ToJson(new JsonWriterSettings{OutputMode = JsonOutputMode.Strict});
fixed it.
The ISODate constructor call is what's causing the issue. From an issue on the MongoDB JIRA:
The parser accepts these two date formats: seconds ->
"yyyy-MM-dd'T'HH:mm:ss'Z'" or seconds.milleseconds ->
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" Just add seconds to your $date value
and the aggregation command should work. Here's the JSON doc that I
had success with: { "aggregate" : "test", pipeline : [ {$match : {
date : { $date : "2012-05-01T12:30:00Z" } } } ] }
If you remove the ISODate constructor and simply render your date as (for example) "2013-03-18T08:50:53Z", you should be in business.

Categories

Resources