json formatting datetime, date and time - java

I have a Class with the following
class MyClass {
private Date datetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2018-01-01 11:32:15");
private Time time = new Time(System.currentTimeMillis());
private Date date = new Date(System.currentTimeMillis());
// getters and setters
}
Gson
Gson gson = new Gson();
System.out.println(gson.toJson(myClass));
Gson gsonBuilder = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
System.out.println(gsonBuilder.toJson(myClass));
I get
{"datetime":"Jan 1, 2018 11:32:15 AM","time":"04:51:23 PM","date":"Jan 1, 2018 4:51:23 PM"}
{"datetime":"2018-01-01 11:32:15","time":"04:51:23 PM","date":"2018-01-01 16:51:23"}
Jackson
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(myClass));
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
System.out.println(mapper.writeValueAsString(myClass));
I get
{"datetime":1514806335000,"time":"17:01:18","date":1514826078776}
{"datetime":"2018-01-01T11:32:15.000+0000","time":"17:13:52","date":"2018-01-01T17:13:52.224+0000"}
How can I get
{"datetime":"2018-01-01 11:32:15","time":"16:51:23","date":"2018-01-01"}
I am not tied to any library so if there is a more appropriate JSON library that can do the job, please comment.

With Jackson, annotate your dateTime and date fields with
#JsonFormat
(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")

Found the answer:
Using Jackson you can annotate each Field
class MyClass {
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
public Date datetime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2018-01-01 11:32:15");
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "HH:mm:ss")
public Time time = new Time(System.currentTimeMillis());
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
public Date date = new Date(System.currentTimeMillis());
MyClass() throws ParseException { }
}
MyClass myClass = new MyClass();
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writeValueAsString(myClass));
Gives you
{"datetime":"2018-01-01 11:32:15","time":"17:21:22","date":"2018-01-01"}

Related

How to form date and time in Java

I'm using LocalDateTime.now() and OffSetDateTime.now() to retrieve the date and time but it's not the desired format.
Does anyone know how to format this format? "2022-05-20T11:22:10"
I'm using MapStruct to do request and response conversions:
#Mapper
public interface ParesMapper {
ParesMapper INSTANCE = Mappers.getMapper(ParesMapper.class);
#Mapping(target = "data", source = "data")
DataParesResponse toResponse(DataPares domain);
#Mapping(target = "data", source = "data")
List<DataParesResponse> toResponseList(List<DataPares> domain);
DataPares toDomain(DataParesRequest dto);
default OffsetDateTime map(LocalDateTime value) {
return OffsetDateTime.now();
}
default LocalDateTime map(OffsetDateTime value) {
return LocalDateTime.now();
}
}
I look forward to helping you find a solution.
You can use DateTimeFormatter method
import java.time.format.DateTimeFormatter;
import java.time.LocalDateTime;
public class DateTimeFormatter {
public static void main(String[] args) {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
LocalDateTime now = LocalDateTime.now();
System.out.println(dtf.format(now));
}
}

How do I use different date formats for serialization & deserialization?

I'm getting an object with the date field in the format 2022-02-11 which I'm mapping into an object as follows:
{ "dateTimeField": "2022-02-11" }
#Data
class MyPojo {
#JsonFormat(pattern = "yyyy-MM-dd")
private Date dateTimeField;
}
Now I need to send this object as a json response, but I need it to be in a different format:
{ "dateTimeField": "2022-02-11 00:00:00" }
If I change the pattern field, deserialization fails:
#Data
class MyPojo {
// com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.util.Date` from String "2022-02-11": expected format "yyyy-MM-dd HH:mm:ss"
#JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date dateTimeField;
}
How do I use different patterns for serialization & deserialization?
This can be accomplished using separate annotations on the getter and setter of the field:
#Data
class MyPojo {
private Date dateTimeField;
// Used during serialization
#JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
public Date getDateTimeField() {
return dateTimeField;
}
// Used during deserialization
#JsonFormat(pattern = "yyyy-MM-dd")
public void setDateTimeField(Date dateTimeField) {
this.dateTimeField = dateTimeField;
}
}
Alternatively, using Lombok's (experimental as of 11 Feb 2022) onX feature:
#Data
class MyPojo {
#Getter(onMethod_ = {#JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")}) // Used during serialization
#Setter(onMethod_ = {#JsonFormat(pattern = "yyyy-MM-dd")}) // Used during deserialization
private Date dateTimeField;
}

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;

Converting date from timestamp to human readable in entity constructor

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";
}

Categories

Resources