I write a controller like this and it just return the current timestamp
#GetMapping(value = "/i/testTime")
Timestamp testTime(HttpServletRequest req) throws IOException {
return new Timestamp(System.currentTimeMillis());
}
I access the url and it returns:
"2022-02-25T08:23:32.690+00:00"
Is there a way to configure this format?
Any answer will be helpful
I would suggest using java.time package's LocalDateTime class.
LocalDateTime now = LocalDateTime.now();
// LocalDateTime cvDate = Instant.ofEpochMilli(milliseconds).atZone(ZoneId.systemDefault()).toLocalDateTime();
// LocalDateTime utcDate = Instant.ofEpochMilli(milliseconds).atZone(ZoneId.of("UTC")).toLocalDateTime();
System.out.println("Before Formatting: " + now);
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
String formatDateTime = now.format(format);
Output
Before Formatting: 2017-01-13T17:09:42.411
After Formatting: 13-01-2017 17:09:42
SO in your case, it would be something like this:
#GetMapping(value = "/i/testTime")
String testTime(HttpServletRequest req) throws IOException {
LocalDateTime currentDateTime = LocalDateTime.now();
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
return currentDateTime.format(format);
}
You can even do it with annotations without having logic in your controller.
public class DateDto {
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
private LocalDateTime date;
public DateDto(LocalDateTime date){
this.date = date;
}
public LocalDateTime getDate(){
return this.date;
}
}
And your controller like:
#GetMapping(value = "/i/testTime")
DateDto testTime(HttpServletRequest req) throws IOException {
return new DateDto(LocalDateTime.now());
}
Related
The following code works
public #ResponseBody
Map<String, Object> test(#RequestParam #DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime startDate,
#RequestParam #DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime endDate) {
return null;
}
with this request
https://localhost:8080/api/v1/test?startDate=2000-10-31T01:30:00.000-00:00&endDate=2000-10-31T01:30:00.000-00:00
But the following code throws exception
public #ResponseBody
Map<String, Object> test(#RequestBody #DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime startDate,
#RequestBody #DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) ZonedDateTime endDate) {
return null;
}
with this body
{
"endDate":"2000-10-31T01:30:00.000-00:00",
"startDate":"2000-10-31T01:30:00.000-00:00"
}
has this exception
[org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected token (START_OBJECT), expected one of [VALUE_STRING, VALUE_NUMBER_INT, VALUE_NUMBER_FLOAT] for java.time.ZonedDateTime value; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (START_OBJECT), expected one of [VALUE_STRING, VALUE_NUMBER_INT, VALUE_NUMBER_FLOAT] for java.time.ZonedDateTime value
You must use #ModelAttribute or make object or map for mapping body, because Reflection utils not have opportunity for reading function parameter names (you cant specify property name for mapping).
public class User {
private String name;
private String occupation;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
#RestController
public class MyController {
#ResponseStatus(value = HttpStatus.OK)
#PostMapping(value="/myfoo")
public void process2(#ModelAttribute("email") String email) {
}
#ResponseStatus(value = HttpStatus.OK)
#PostMapping(value="/vals")
public void process(#RequestBody MultiValueMap<String, String> values) {
}
#ResponseStatus(value = HttpStatus.OK)
#PostMapping(value="/user", consumes = MediaType.APPLICATION_JSON_VALUE)
public void process2(#RequestBody User user) {
}
}
ATTENTION
always set name of property for #RequestParam, else you can take error if somebody add not only this parameter or changed function signature
My Feign client is defined as follow :
#FeignClient(name = "${feign.name}",url = "${feign.url}",
configuration = {DateFormatConfiguration.class})
public interface MyFeignClient {
#GetMapping(value = "/test")
ResponseEntity<MyResponse> getResponse(#RequestParam(value = "date") Date date);
}
Where :
class DateFormatConfiguration {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
#Bean
public FeignFormatterRegistrar dateFeignFormatterRegistrar() {
return formatterRegistry -> formatterRegistry.addFormatter(new Formatter<Date>() {
#Override
public Date parse(String text, Locale locale) throws ParseException {
return df.parse(text);
}
#Override
public String print(Date object, Locale locale) {
return df.format(object);
}
});
}
}
However when I run this test :
#Test
public void test(){
Date date= new GregorianCalendar(2000, 12, 31).getTime();
myFeignClient.getResponse(date);
}
the request is sent into this format :
---> GET https:xxx/test?date=Wed%20Jan%2031%2000%3A00%3A00%20EST%202001
What I'm trying to have is :
---> GET https:xxx/test?date=2000-12-31
Where the date is formatter as I need.
I've tried also this solution, but not working neither:
class DateFormatConfiguration {
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
#Bean
public JacksonEncoder feignEncoder() {
return new JacksonEncoder(customObjectMapper());
}
#Bean
public JacksonDecoder feignDecoder() {
return new JacksonDecoder(customObjectMapper());
}
private ObjectMapper customObjectMapper(){
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setDateFormat(df);
return objectMapper;
}
}
Any Ideas ?
You should consider trying replace necessary lines with something like this:
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate date= LocalDate.ofInstant(new GregorianCalendar(2000, 12, 31).getTime().toInstant(), ZoneId.of(TimeZone.getDefault().getID()));
String dateFormatted = date.format(dtf);
I have this DTO in Spring Boot that reference a collection on MongoDB.
#Document(collection = "his")
#AllArgsConstructor
#Getter
#Setter
public class His{
#Id
private String internalId;
private String person;
private String type;
private Date date;
}
And i want to find all objects that the date is between two dates. I already have this (Only with 2 months of difference):
#Override
public ResponseEntity<List<His>> getHisByDate(String dateTo, String dateFrom) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Period diff = Period.between(LocalDate.parse(dateFrom), LocalDate.parse(dateTo));
if(diff.getYears() == 0 && diff.getMonths() <= 2 && diff.getMonths() >= -2) {
// Here the query
} else {
//Throw Error
}
return null;
}
How i do that with Query?
SOLUTION:
#Override
public ResponseEntity<List<His>> getPagosByFechaPago(String dateTo, String dateFrom) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date dateHasta = null, dateDesde = null;
try {
dateHasta = formatter.parse(dateTo);
dateDesde = formatter.parse(dateFrom);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Period diff = Period.between(LocalDate.parse(dateFrom), LocalDate.parse(dateTo));
if(diff.getYears() == 0 && diff.getMonths() <= 2 && diff.getMonths() >= -2) {
Query query = new Query();
query.addCriteria(Criteria.where("date").gte(dateHasta).lt(dateDesde));
List<His> response = mongoTemplate.find(query, His.class);
log.info(response.toString());
return new ResponseEntity<>(response, HttpStatus.OK);
} else {
return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
}
}
Try something like that
public interface HisRepository extends MongoRepository<His, String> {
#Query("{ date: { $gte: ?0, $lte: ?1 } }")
List<His> findObjects(Date dateFrom, Date dateTo);
List<His> findAllByDateGreaterThanEqualAndDateLessThanEqual(Date dateFrom, Date dateTo);
}
Please note to the condition of your boundaries: $gte or $gt, $lte or $lt.
https://docs.mongodb.com/manual/reference/operator/query-comparison/
#Controller
#RequestMapping(value="/reservations")
public class ReservationController {
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
#Autowired
private ReservationService reservationService;
#RequestMapping(method = RequestMethod.GET)
public String getReservation(#RequestParam(value="date", required=false) String dateString, Model model){
Date date = null;
if(dateString != null){
try {
date = DATE_FORMAT.parse(dateString);
} catch (ParseException pe) {
date = new Date();
}
}else{
date = new Date();
}
List<RoomReservation> roomReservationList = this.reservationService.getRoomReservationsForDate(date);
model.addAttribute("roomReservations", roomReservationList);
return "reservations";
}
}
I understand that the #RequestParam annotation is used to bind parameter values of query string to the controller method parameters. So for example, http://localhost:8080/reservations?date=2017-01-01. However, where does the value="date" come from? I dont see any value "date" inside my html page.
if you submit a form as method:"GET" (not POST) and form contains a input field named date then submitting this form will hit this handler method.
#RequestMapping(value = "/getSettlements", method = RequestMethod.GET, headers = "Accept=application/json")
public #ResponseBody
Collection<Settlement> getSettlements
(#RequestParam(value = "startDate") String startDate,
#RequestParam(value = "endDate") String endDate,
#RequestParam(value = "merchantIds", defaultValue = "null") String merchantIds)
How to give today's date in defaultValue ? It only takes constant.
#InitBinder
public void initBinder(WebDataBinder binder) throws Exception {
final DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
final CustomDateEditor dateEditor = new CustomDateEditor(df, true) {
#Override
public void setAsText(String text) throws IllegalArgumentException {
if ("today".equals(text)) {
setValue(new Date());
} else {
super.setAsText(text);
}
}
};
binder.registerCustomEditor(Date.class, dateEditor);
}
#RequestParam(required = false, defaultValue = "today") Date startDate
If you are using LocalDate, you can create a default value like this:
#RequestParam(name = "d", defaultValue = "#{T(java.time.LocalDate).now()}", required = true) LocalDate d)
I tried pretty much every option, even using interceptors. But from far the easiest solution was to use SpEL. For Example: defaultValue = "#{new java.util.Date()}"
Since you receive a string you can any date format you want and later on use formatting to extract the date