findByDate returning documents from previous day - spring

I'm trying to fetch a list of objects by date, but the resulted list is always of the day before.
#GetMapping("date")
ResponseEntity findByDate(#RequestParam #DateTimeFormat(pattern = "yyyy-MM-dd") Date date) {
log.info("date is: "+date);
log.info("Delfaul time zone is: "+ TimeZone.getDefault());
return ResponseEntity.ok(consumptionService.findByDate(date));
}
the controller calls the service, which calls HourlyConsumptionRepo:
public interface HourlyConsumptionRepo extends MongoRepository<HourlyConsumption, ObjectId> {
List<HourlyConsumption> findByDate(Date date);
}
Postman results
Postman results
I think it might be an issue of timezones, but I can't figure out how to fix it.

MongoDB uses UTC times by default. See here: https://www.mongodb.com/docs/v3.2/tutorial/model-time-data/. So those results are "valid", I'm assuming you are UTC+2.

Related

Java Date field not shown properly in postman

Any help or hint would be greatly appreciated it!!
I am using Spring Boot 2.56
The date and time show properly for field "transactionDate" field when debugging the code in intellij.
2023-01-15 23:35:05.0
enter image description here
Code:
public List < TransactionEntity > findByFromAccountIdOrToAccountId(Long accountId) {
AccountEntity account = accountRepository.findByAccountId(accountId);
if (account == null) {
throw new AccountException("account cannot be found in account table accountId:" + accountId);
}
List < TransactionEntity > list = transactionRepository.findByFromAccountOrToAccount(account, account);
return list;
}
TransactionEntity.java
private Timestamp transactionDate;
For the transactionDate field I used import java.sql.Timestamp;
In postman it is showing: "transactionDate": 1673843714000,
How can I show the proper date and time in postman result such as "2023-01-15 23:35:05.0".
"transactionDate": 1673843714000
This is how Timestamp looks like. If you want to show like you mention use LocalDateTime instead.
private LocalDateTime transactionDate;
Or convert
transactionDate.toLocalDateTime().toLocalDate()

Spring JPA: Use CriteriaBuilder to filter on a datetime between two instants

I'm setting up a method to filter entries by the "lastupdated" column. I'm trying to filter entries of which the lastupdated value is between a given startTime and endTime.
I'm using the simplified code below:
public List<SomeEntity> getItemsByLastUpdated() {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<SomeEntity> criteriaQuery = cb.createQuery(SomeEntity.class);
var root = criteriaQuery.from(SomeEntity.class);
var predicates = new ArrayList<>();
var startTime = Instant.now();
var endTime = Instant.now().plus(5, MINUTES);
predicates.add(cb.greaterThanOrEqualTo(root.get("lastupdated"), startTime));
predicates.add(cb.lessThan(root.get("lastupdated"), endTime));
criteriaQuery.where(predicates.toArray(new Predicate[0]));
return entityManager.createQuery(criteriaQuery).getResultList();
}
For some reason, the criteria for datetime fields are not (correctly) being applied: All the entities are being returned instead of only the items within the startTime-endTime range.
I'm guessing that I need to explicitly state that the "lastupdated" field is a datetime field; when I set startTime to Instant.MAX, I receive an error that seems to hint on a date filter instead of datetime:
Invalid value for EpochDay (valid values -365243219162 - 365241780471): 365241780838
Would anyone know how I can filter on a datetime field being between two given java Instants?
PS. I'm aware of using derived queries such as findByXGreaterThanOrEqualToAndXLessThan(Instant instant1, Instant instant2); but since there are several other criterias which I have not included, this option is not feasible.
I think you could easily do the same using EntityManager and JPQL instead of Criteria API:
public List<SomeEntity> getItemsByLastUpdated() {
var query = "select e from SomeEntity e
where e.lastupdated >= :from
and e.lastupdated < :to
and your_other_criteria";
return entityManager.createQuery(query)
.setParameter("from", startTime)
.setParameter("to", endTime)
.getResultList();
}
It took me quite some time to figure it out; turned out that the lack of filtering didn't have anything to do with the CriteriaBuilder setup.
I had created a test to verify the method, and prepared some entities before running the test. However, the "lastupdated" field in the entity class was annotated with #UpdateTimestamp, which would result in all the saved entities having pretty much the same 'lastupdated' value.

Spring Mongo: Repository do not return date in order

I am trying to get objects from Mongodb in ascending (or descending) timestamp order.
This is how the document looks like:
{
_id: 5b01ffe3cd8b295aed16d5c0Wed
temperature: 23
timestamp: Dec 13 09:27:00 CET 2017
}
I am using Spring repository:
public interface TemperatureRepo extends MongoRepository<TemperatureObject, String> {
public List<TemperatureObject> findAllByOrderByTimestampDesc();
}
But somehow, Desc and Asc queries never work. I always get the result set in same order (which is not ordered at all)
The attribute temperature is saved as Date not as String
Is this a bug or am I missing something?
try this, it will solve your problem.
List<TemperatureObject> temperatureObjects = temperatureRepo.findAll(new Sort(Sort.Direction.DESC, "timestamp"));

Datastream - TimeWindow for past date

I have dataset with past Event Time
01-12-2015 01:10:10
01-12-2015 01:10:20
01-12-2015 01:10:30
01-12-2015 01:10:40
.... (millions of records)
I want to apply timeWindow for this timeWindow(Time.seconds(30))
I can have a TimeExtractor class to get the EventTime in the data. But how do I implement getCurrentWatermark method. It should get the past date and time
In your case it would be best to use one of the provided TimeStampAssigners see here.
So what I would recommend is something like this:
DataStream<MyEvent> stream = ...
DataStream<MyEvent> withTimestampsAndWatermarks =
stream.assignTimestampsAndWatermarks(new AscendingTimestampExtractor<MyEvent>() {
#Override
public long extractAscendingTimestamp(MyEvent element) {
return element.getCreationTime();
}
});
Also remember to set proper TimestampCharacteristic:
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);

LocalDateTime format after form Submit

I use the following jQuery function to format my datepicker
$(".datepicker").datepicker({
dateFormat : "MM yy"
}).attr('readonly', true);
Upon selection I can see the text field is set correctly to November 2013. Before form is submitted I am using Spring validation to validate the date with
public class LocalMonthEditor extends PropertyEditorSupport {
#Override
public void setAsText(final String text) throws IllegalArgumentException {
if (!StringUtils.hasText(text)) {
// Treat empty String as null value.
setValue(null);
} else {
LocalDateTime localDateTime = LocalDateTime.parse(text,
DateTimeFormat.forPattern("MMMM yyyy"));
setValue(localDateTime);
}
}
#Override
public void setValue(final Object value) {
super.setValue(value == null || value instanceof LocalDateTime ? value
: new LocalDateTime(value));
}
#Override
public LocalDateTime getValue() {
return (LocalDateTime) super.getValue();
}
#Override
public String getAsText() {
return getValue() != null ? getValue().toString() : "";
}
}
However after form being submitted the text field is changed to 2013-11-01T00:00:00.000. How can I maintain the field to November 2013 ?
First of all, if the data you need is simply a month and a year, why are you using Joda-Time at all? That's like getting in your car to drive to your mailbox at the end of the driveway: extra effort and complexity for no benefit.
Instead, I suggest you choose between:
Track a pair of variables (month, year)
Define your own class with a pair of members (month, year), and track an instance.
Use a String as seems to be your intention: "November 2013" as you seem to be thinking, or a simpler schemes such as "2013-11".
Secondly, because you created an instance of LocalDatetime, at some point toString seems to be called. The default output of toString on a LocalDateTime is output in the standard ISO 8601 format you saw: 2013-11-01T00:00:00.000. A LocalDateTime has a date value and a time value (hence the name), even if the time value may be set to zeros (meaning start of day). So this is a feature, not a bug.
I don't know Spring Validatation nor the rest of your class structure. I'm guessing you are storing a LocalDateTime instance where instead you meant to be (or should be) storing a String instance. You may need to read up on the subject of "model" versus "view". Often we track data behind the scenes differently than we present data to the user. In this case, you probably should be holding a pair of ints or Integers (one for month, one for year) in your model with a String in your view ("November 2013").
You are setting your local time object directly to text field, thats why your getting full date string.convert your date object by using parse() method and set it. Do not create new object for date set your value directly.

Resources