Converting date from timestamp to human readable in entity constructor - java

Currently, the format of the Date requestDate variable stored looks like: 2017-02-17 00:00:00.0. I want to convert this into, for example: Friday, February 17, 2017. I would like to do the conversion here in my entity and return it so that when it's displayed it is more human readable. This will likely happen in the constructor, at this line: this.setRequestDate(doDateConversion(requestDate));. How can I make this conversion?
My Request entity:
#Entity
#Table(name = "Request")
public class RequestDO implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="request_id")
private Long id;
private Date requestDate;
private String description;
private RequestStatus status;
/*private Boolean read;*/
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="user_id", nullable = false)
private Users users;
public RequestDO() {}
public RequestDO(Users user, Date requestDate) {
this.setUsers(user);
this.setRequestDate(requestDate);
}
#Override
public String toString() {
return String.format(
"RequestDO[id=%d, inital='%s', requestDate='%s']",
getId()
, getUsers().getInitialName()
, getRequestDate());
}
public Date getRequestDate() {
return requestDate;
}
public void setRequestDate(Date requestDate) {
this.requestDate = requestDate;
}
}

You can use SimpleDateFormat to convert your Date to a readable String of your choice.
The time format String for your example is EEEE, MMMM, dd, yyyy. You have to create a new SimpleDateFormat object and format your date to a String. Examples...
But Spring provides some specials out of the box. For example you can use Jackson for date format: #JsonFormat(pattern="yyyy-MM-dd") more. It is also possible to add a data format in application.properties file : spring.jackson.date-format

Using SimpleDateFormat:
java.sql.Date date = new Date(System.currentTimeMillis());
System.out.println(new SimpleDateFormat("EEEE, MMMM dd, YYYY").format(date));
See this for more details.

I solved the problem by changing the dates as they are read in my controller, using SimpleDateFormat:
#RequestMapping(value = "/requests", method = RequestMethod.GET)
public String getAllRequests(Model model, RequestModel requestModel) throws ParseException {
List<RequestDO> requestDOArrayList = new ArrayList<RequestDO>();
for (RequestDO requestDO : requestRepository.findAll()) {
log.info(requestDO.toString());
// Display all dates in Requests list in human-readable form
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse(requestDO.getRequestDate().toString());
log.info(String.valueOf(date));
requestDO.setRequestDate(date);
requestDOArrayList.add(requestDO);
}
model.addAttribute("requests", requestDOArrayList);
log.info(requestDOArrayList.toString());
return "requests";
}

Related

Hibernate - Override output format of date when generating JSON

With a temporal in my entity defined like:
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "start_time", length = 19, nullable = false)
public Date getStartTime() {
return this.startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
And marshaling JSON out put like this (simplified):
#GET
#RestSecure
#Path("/list")
#Produces(MediaType.APPLICATION_JSON)
public Response list(){
return Response.status(Response.Status.OK).entity(myEntityList).build();
}
Is there a simple way of overriding output date format?
What I am getting out is the epoch like this:
"startTime": 1582261711000,
What I need is the date in ISO 8601 format like this:
"startTime": "2020-02-21T05:08:31Z",
You can use jackson's DateFormat annotation:
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ssZ")

Format date in response JSON from controller

I am returning a JSON as a response from the controller. I want to format the date fields in this response.
Controller-
#RequestMapping(value = "/call", method = RequestMethod.GET)
public SampleDTO get()
{
......
return sampleDTO;
}
SampleDTO-
{
"date" : "2020-03-10T08:57:58+0000",
"text" : "abc"
}
I want to format the date field to dd-MM-yyyy
To do this I add the #JsonFormat annotation to the bean class of SampleDTO.
SampleDTO.java -
import java.util.Date;
public class SampleDTO
{
#JsonFormat(pattern = "dd-MM-yyyy")
private Date date;
private String text;
#JsonFormat(pattern = "dd-MM-yyyy")
public void setDate(final Date date)
{
this.date = date;
}
#JsonFormat(pattern = "dd-MM-yyyy")
public Date getDate()
{
return date;
}
public void setText(final String text)
{
this.text = text;
}
public String getText()
{
return text;
}
}
Still, I am getting this format in the response on my browser.
"date" : "2020-03-10T08:57:58+0000"
EDIT 1:
Instead of returning the sampleDTO, converting it to String directly in the code works perfectly fine.
This works like a charm:
SampleDTO sampleDTO = new SampleDTO();
sampleDTO.setCreated(new Date());
ObjectMapper om = new ObjectMapper();
return om.writeValueAsString(sampleDTO);
Please, check that your Date is from java.util and not from java.sql package. Plus try the following:
#JsonSerialize(as = Date.class)
#JsonFormat(shape=JsonFormat.Shape.STRING, pattern="dd-MM-yyyy")
Could you try this on the field level and remove from getDate() method in your DTO.
Something like this,
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
private Date date;
This should work with your current version of jackson-databind:2.9.8.jar.
Here is the small example for you:
public class ExampleMain {
public static void main(String[] args) throws IOException {
Employee employee = new Employee();
employee.setDateOfBirth(Date.from(ZonedDateTime.now().minusYears(30).toInstant()));
System.out.println("-- before serialization --");
System.out.println(employee);
System.out.println("-- after serialization --");
ObjectMapper om = new ObjectMapper();
String jsonString = om.writeValueAsString(employee);
System.out.println(jsonString);
System.out.println("-- after deserialization --");
System.out.println(om.readValue(jsonString, Employee.class));
}
}
public class Employee {
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
private Date dateOfBirth;
public Date getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(Date dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
#Override
public String toString() {
return "Employee{" +
", dateOfBirth=" + dateOfBirth +
'}';
}
}
There are three levels of how you can solve this date format issue with Spring.
1) Using #JsonFormat on your date fields
In this case, you need to use the same annotation in front of all your private date members.
public class MyBean{
#JsonFormat(pattern="yyyy-MM-dd")
private Date birthday;
#JsonFormat(pattern="yyyy-MM-dd")
private LocalDate birthday;
// getters and setters here
}
2) Setting the Default format
If you want to configure the default date format for all dates in your application, add the following line to the application.properties or application.yml config file:
spring.jackson.date-format=yyyy-MM-dd
Unfortunately, this solution doesn't work with the Java 8 date types, like LocalDate and LocalDateTime.
3) Customizing your Jackson ObjectMapper
This solution works like a charm with Java 8 date types as well.
#Configuration
public class ContactAppConfig {
private static final String DATE_FORMAT = "yyyy-MM-dd";
private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
#Bean
public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
return builder -> {
builder.simpleDateFormat(DATE_TIME_FORMAT);
builder.serializers(new LocalDateSerializer(DateTimeFormatter.ofPattern(DATE_FORMAT)));
builder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DATE_TIME_FORMAT)));
};
}
}
I suggest you use the 3rd option.
you can use jstl format to format the date :)
<%# taglib prefix = "fmt" uri = "http://java.sun.com/jsp/jstl/fmt" %>
<fmt:formatDate pattern = "yyyy-MM-dd" value = "${date}" />

Jackson #JsonFormat converting date with incorrect timezone

I have a value coming in from JSON payload as:
"callStartTime" : "2019-03-27 13:00:00"
Entity.java
#JsonProperty("callStartTime")
#Column(name = "call_start_dt", nullable = false)
#JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", lenient = OptBoolean.FALSE)
private Date callStartTime;
When I printed it on console, it says:
Wed Mar 27 08:00:00 CDT 2019
I wanted to be the same as it was in json payload. How I can fix it?
I am just taking date from json and writing it to mysql db in a datetime column.
Simple solution: I solved it by changing the data type to String which completes my aim to capture the value as it is coming from JSON payload. Using Date and other data types were converting the value to some different timezone.
#JsonProperty("callStartTime")
#Column(name = "call_start_dt", nullable = false)
#JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", lenient = OptBoolean.FALSE)
private **String** callStartTime;
Try this
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
private Date callStartTime;
java.util.Date does not capture time zone data. It only knows about number of millis since the epoch.
You could try using one of the modules in jackson-modules-java8 and deserialize into an instance of ZonedDateTime instead, which is time-zone aware.
EDIT: try this as a basis for getting it to work:
public class SoTest {
public static void main(String[] args) throws Exception {
ObjectMapper om = new ObjectMapper().registerModule(new ParameterNamesModule())
.registerModule(new JavaTimeModule());
String s = "{\"callStartTime\" : \"2019-03-27T13:00:00Z\" }";
MyType mt = om.readValue(s, MyType.class);
System.out.println(mt.getCallStartTime());
}
}
class MyType {
#JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssX", lenient = OptBoolean.FALSE)
private ZonedDateTime callStartTime;
public ZonedDateTime getCallStartTime() {
return callStartTime;
}
public void setCallStartTime(ZonedDateTime date) {
this.callStartTime = date;
}
}
There are two possible solutions for this :
1. Define ObjectMapper bean and set date format.
#Bean
public ObjectMapper objectMapper()
{
ObjectMapper objectMapper = new ObjectMapper();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
objectMapper.setDateFormat(df);
return objectMapper;
}
2. Set date format for the particular field using #JsonFormat
#JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", lenient = OptBoolean.FALSE)
private Date createTime;

How to return Date object in ISO format instead of timestamp in Java?

Assuming a java class
public class User(){
String name;
Date dateCreated;
}
and a Spring boot controller:
#RequestMapping(value = "getUser", method=RequestMethod.GET, produces=MediaType.APPLICATION_JSON_VALUE))
public User getUser() {
User newUser = new User();
newUser.dateCreated = new Date();
return newUser;
}
If I have a rest API endpoint that returns that User object in JSON format, as above, the dateCreated will be send in timestamp format instead of ISO. Is there any way to make Java return the date in Iso format other than having to specify a new return object that has Date as a String?
One way to do this would be to convert Date to a String and send that but I'm wondering if there's a more convenient way..
Update your application.properties with the following:
spring.jackson.serialization.write-dates-as-timestamps:false
Now you can specify the format in your bean as follows:
public class User(){
String name;
#JsonFormat(pattern="yyyy-MM-dd")
Date dateCreated;
}

Timestamp invalid hour in Java

I am using JPA with my Java project, and the timestamp is not working very well : it only shows 2015-08-12 00:00:00.0 (the day is correct but the hour is not)
#Entity
public class Session implements Serializable {
..
#Temporal(TemporalType.DATE)
private Date timestamp;
..
public Session(String sessionId) {
super();
this.sessionId = sessionId;
this.timestamp = new Date();
}
public Session() {
super();
this.timestamp = new Date();
}
}
Do you know how to fix this?
You should use TemporalType.TIMESTAMP that will map the field to a java.sql.Timestamp, hence it will contain also time related info, not only regarding date. In comparison, the type you used, TemporalType.DATE are mapped to java.sql.Date, class containing information like day, month year.
So, your code will transform in:
#Entity
public class Session implements Serializable {
..
#Temporal(TemporalType.TIMESTAMP)
private Date timestamp;
..
public Session(String sessionId) {
this.sessionId = sessionId;
this.timestamp = new Date();
}
public Session() {
this.timestamp = new Date();
}
}

Categories

Resources