Deserializing with GSON converting java.sql.Date incorrectly - java

I am using GSON to deserialize a JSON string to a java object. The date in the JSON string is of the format:
yyyy-mm-dd
When the date is read into a java.sql.Date field in my JAVA object, the month always ends up as 01 or january! Very strange.
Here is the code for the JSON String and deserializing with GSON:
public static void main(String[] args)
{
String jsonString = "[{\"date\":\"2015-02-14\"},{\"date\":\"2015-03-15\"},{\"date\":\"2015-04-16\"}]";
Type type = new TypeToken<List<TestObject>>(){}.getType();
Gson gsonReceiver = new GsonBuilder().setDateFormat("yyyy-mm-dd").create();
List<TestObject> objectList = gsonReceiver.fromJson(jsonString, type);
for(int i=0; i < objectList.size(); i++) {
System.out.println("objectList[" + i + "] = " + objectList.get(i).toString());
}
}
And here is the code for the TestObject:
public class TestObject {
private Date date;
public TestObject(Date date) {
this.date = date;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
#Override
public String toString() {
return "TestObject [date=" + date + "]";
}
}
If you run this piece of code, the dates in the new object get printed out as:
objectList[0] = TestObject [date=2015-01-14]
objectList[1] = TestObject [date=2015-01-15]
objectList[2] = TestObject [date=2015-01-16]
Which is just plain weird.
I think I have set the date format like I should - anybody have any idea what is going wrong here?

The right format is
yyyy-MM-dd
mm stay for minutes. Not months.
Here is the javadoc explaining each letter that can be used in date format functions: link
Infact GSonBuilder uses the same conventions of SimpleDateFormat:
Note that this pattern must abide by the convention provided by SimpleDateFormat class. See the documentation in SimpleDateFormat for more information on valid date and time patterns.

Related

How to properly format LocalTime to HH:MM?

I am trying to use a getter to get the LocalTime in HH:mm anytime it is called. As it stands right now it is:
private LocalTime time;
public LocalTime getTime() {
return time;
}
I would like for it to return the time in HH:mm, because as it stands right now it is HH:mm:SS.s. I am trying to mess with date time formatter, but I can't figure it out. Here is what I have:
private LocalTime time;
public LocalTime getTime() {
DateTimeFormatter formatDateTime = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
LocalTime localFormattedTime = LocalTime.parse(time, formatDateTime);
return localFormattedTime;
}
The answer by YCF_L is correct and to-the-point. The reason why I have written this answer is I have seen similar kind of questions (why my date/time is not being printed in a custom way) being asked every now and then.
Note that LocalDate, LocalTime, LocalDateTime etc. each have their own toString()implementation and no matter what you do, whenever you print their object, their toString() method will be called and thus always their default representation will be printed. If you want these objects to be printed in a custom way, you have two options:
You get their elements (e.g. year, month and day from an object of LocalDate) and print them by arranging in your custom way.
Use a formatter class e.g. (the modern DateTimeFormatter or the legacy SimpleDateFormat) and get a string representing the date/time object in a custom way.
To make your code reusable and clean, you prefer the second approach.
The following example illustrates the same:
class Name {
private String firstName;
private String lastName;
public Name() {
firstName = "";
lastName = "";
}
public Name(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
#Override
public String toString() {
return firstName + " " + lastName;
}
}
class NameFormatter {
// Returns a name (e.g. First Last) as F. Last
public static String patternIntialsLast(Name name) {
if (name.getFirstName().length() > 1) {
return name.getFirstName().charAt(0) + ". " + name.getLastName();
}
return name.toString();
}
// Returns a name (e.g. First Last) as Last F.
public static String patternLastInitials(Name name) {
if (name.getFirstName().length() > 1) {
return name.getLastName() + " " + name.getFirstName().charAt(0) + ".";
}
return name.toString();
}
// Returns a name (e.g. First Last) as Last First
public static String patternLastIFirst(Name name) {
return name.getLastName() + ", " + name.getFirstName();
}
}
public class Main {
public static void main(String[] args) {
Name name = new Name("Foo", "Bar");
System.out.println("Default format:");
System.out.println(name);// It will always print what name.toString() returns
// If you want to print name in different formats use NameFormatter e.g.
System.out.println("\nIn custom formats:");
String strName1 = NameFormatter.patternIntialsLast(name);
System.out.println(strName1);
String strName2 = NameFormatter.patternLastIFirst(name);
System.out.println(strName2);
String strName3 = NameFormatter.patternLastInitials(name);
System.out.println(strName3);
}
}
Output:
Default format:
Foo Bar
In custom formats:
F. Bar
Bar, Foo
Bar F.
Now, go through the answer by YCF_L again and this time, you know that you have to implement your method as follows:
public String getTime() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
return formatter.format(ldt);
}
A quick demo:
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class Main {
// Now
static LocalDateTime ldt = LocalDateTime.of(LocalDate.now(), LocalTime.now());
public static void main(String[] args) {
System.out.println(getTime());
}
public static String getTime() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
return formatter.format(ldt);
}
}
Output:
22:23
LocalTime not have date part it have only the time part
You can't have a specific format for LocalDate, LocalTime, LocalDateTime, it use a standard format and you can't change it.
If you want a specific format then you have to use String and not LocalDate, LocalTime, LocalDateTime.
Try with this. I d
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH.mm");
LocalTime today = LocalTime.now();
String timeString = today.format(formatter); //12.38
Try something like this:
String localTimeString = "23:59:59";
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("HH:mm:ss");
try {
TemporalAccessor ta = dtf.parse(localTimeString);
LocalTime lt = LocalTime.from(ta);
LOGGER.info("lt: {}", lt);
} catch (RuntimeException re) {
LOGGER.error("Unable to parse local time string: [{}]", localTimeString, re);
}
Consult the Java documentation on DateTimeFormatter for details on the patterns it supports.
You can also use the DateTimeFormatter to format a LocalTime back into string form, like this:
String localTimeAsString = dtf.format(lt)
LOGGER.info("LocalTime as string: {}", localTimeAsString);

Convert Date format in Java

I have a Date object in DTO object:
public class TopTerminalsDTO {
private Date date;
private int volume;
private int count;
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public int getVolume() {
return volume;
}
public void setVolume(int volume) {
this.volume = volume;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
When I get the response in Angular I get
count: 1
date: "2018-10-06T00:00:00.000+0000"
volume: 111
I want to get this date format YYYY-MM-DD HH:mm:ss in Angular.
What is the proper way to convert the Date into the DTO object? Is it better to use LocalDateTime?
It's better to use LocalDateTime object, but it will return it with a T between the date and hours. You should remove it like in the selected answer here LocalDate - How to remove character 'T' in LocalDate
U can use DateFormat to convert your desire date format.
TopTerminalsDTO tt = new TopTerminalsDTO();
tt.setDate(new Date());
String strDateFormat = "YYYY-MM-DD HH:mm:ss";
DateFormat dateFormat = new SimpleDateFormat(strDateFormat);
String formattedDate= dateFormat.format(tt.getDate());
System.out.println(formattedDate);
As you are sending rest object to angular so u can use string field as date in DTO once covert it in desire date format.
User the Below Code.
Date myDate = new Date();
System.out.println(new SimpleDateFormat("YYYY-MM-DD HH:mm:ss").format(myDate));
LocalDate is the preferred way of many developers since it's been released in Java 8. You can format a LocalDate object the way you want by using the .format(DateTimeFormatter) method of LocalDate.
Like this example from: https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
LocalDate date = LocalDate.now();
String text = date.format(formatter);
LocalDate parsedDate = LocalDate.parse(text, formatter);
Edit:
The LocalDate class doens't provide a time representation. Therefore if you like to also have time, use the LocalDateTime class. The .format() method of LocalDateTime can be used like the .format() method of LocalDate as shown above.

How to reformat a string date in Java

I tacked this problem in VB awhile back, and thought I could easily translate it to Java. The input comes in as a string in the format:
"mm/dd/yyyy"
I want to change this to the following format:
"mm/dd/yy"
where the last two year digits are shown only. I wrote this VB awhile back, which does just that:
Function DateFormat(ByVal myDate As String) As String
Dim reformat As Date
reformat = Date.Parse(myDate, Nothing)
Return Format(reformat, "MM/dd/yy").ToString()
End Function
How can I do this exact same thing in Java, so that the date is reformatted correctly and returned as the string it originally was? I have something like this but it is not working properly:
public static String DateFormat(String myDate){
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
try{
Date formattedDate = formatter.parse(myDate);
return formattedDate.toString();
}catch(Exception e){
e.printStackTrace();
return null;
}
}
I am not sure how to make it the format I need, as I can't find anything similar to the Format() function VB has. Thanks in advance.
Try this :
public static String DateFormat(String myDate) throws ParseException {
SimpleDateFormat inFormat = new SimpleDateFormat("MM/dd/yyyy");
SimpleDateFormat outFormat = new SimpleDateFormat("MM/dd/yy");
Date parsedInDate = inFormat.parse(myDate);
return outFormat.format(parsedInDate);
}
At start, we declare two date formatters, then we create Date object from input String, and at the end we produce String in new format.
If I understand your question, you could use a pair of SimpleDateFormat(s)
private static final String formatIn = "MM/dd/yyyy";
private static final String formatOut = "MM/dd/yy";
private static final DateFormat sdfIn = new SimpleDateFormat(
formatIn);
private static final DateFormat sdfOut = new SimpleDateFormat(
formatOut);
public static String formatDateString(String dateIn)
throws ParseException {
return sdfOut.format(sdfIn.parse(dateIn));
}
public static void main(String[] args) {
try {
System.out.println(formatDateString("07/15/2014"));
} catch (ParseException e) {
e.printStackTrace();
}
}
Output is
07/15/14
SimpleDateFormat takes in a number of different formats. I believe the format you want is already built in and can be accessed like so...
Date date = new Date();
Format formatter = new SimpleDateFormat("MM/dd/yy");
String s = formatter.format(date);
System.out.println(s);
You've basically almost got it, just need to apply the new format.
public static String DateFormat(String myDate){
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
try{
Date date = formatter.parse(myDate);
formatter.applyPattern("MM/dd/yy");
return formatter.format(date);
}catch(Exception e){
e.printStackTrace();
return null;
}
}

How to get UTC time without SimpleDateFormat? [duplicate]

This question already has answers here:
How to handle calendar TimeZones using Java?
(9 answers)
Closed 8 years ago.
I'm currently working on timestamps that are converted from and to UTC. All articles that I found were based on conversion to and from String. Like this one:
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date myDate = simpleDateFormat.parse(rawQuestion.getString("AskDateTime"));
But I wonder if there is a way to simply work with the Date instance/class or the calendar to convert the local Date into UTC and vice versa without converting it to String in between.
Read up on Joda-Time. That is a better API for such things than the java date and calendar classes
maybe this can help you:
Calendar.getInstance(java.util.TimeZone)
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
java.until.Date does not have a timezone, so there's nothing to be converted. You only see a timezone when you format the date to a string explicitly, or implicitly by using its toString method. An implicit conversion uses the local default timezone.
Internally, Date stores the date/time as a long, representing milliseconds since midnight, Jan. 1, 1970, UTC.
So, if you format a date as a string, and then parse the string back to a date, you've changed nothing at all.
So far, I could not find a perfect solution, so I had to stick to the conversion from Date to String and vice versa. Here's a little helper class that I wrote.
public class DateTimeHelper {
public static final String MYSQL_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static final TimeZone timeZoneUTC = TimeZone.getTimeZone("UTC");
private Date date = new Date();
private final SimpleDateFormat format;
public DateTimeHelper(String dateTimeFormat) {
format = new SimpleDateFormat(dateTimeFormat, Locale.US);
}
public DateTimeHelper(String dateTimeFormat, String utcTimeString) {
this(dateTimeFormat);
try {
format.setTimeZone(timeZoneUTC);
Date utc = format.parse(utcTimeString);
format.setTimeZone(TimeZone.getDefault());
String local = format.format(utc);
date = format.parse(local);
} catch (ParseException e) {
// nothing
}
}
public Date getDate() {
return date;
}
public Date toUtc() {
String temp = toString();
format.setTimeZone(timeZoneUTC);
try {
return format.parse(temp);
} catch (ParseException e) {
return date;
}
}
#Override
public String toString() {
format.setTimeZone(TimeZone.getDefault());
return format.format(date);
}
public String toUtcString() {
format.setTimeZone(timeZoneUTC);
return format.format(date);
}
}
And another one that's easier to use:
public class MySqlDateTimeHelper extends DateTimeHelper {
public MySqlDateTimeHelper() {
super(DateTimeHelper.MYSQL_DATE_TIME_FORMAT);
}
public MySqlDateTimeHelper(String utcTimeString) {
super(DateTimeHelper.MYSQL_DATE_TIME_FORMAT, utcTimeString);
}
public static String getCurrentTimestampUtc() {
MySqlDateTimeHelper current = new MySqlDateTimeHelper();
return current.toUtcString();
}
}

String to joda LocalDate in format of "dd-MMM-yy"

I am using JAXB and joda time 2.2. to backup the data from Mysql to XML and restore it back. in my Table I have a Date attribute in format of "16-Mar-05". I successfully store this in XML. but when I want to read it from XML and put it back in Mysql table, I cant get the right format.
this is my XMLAdapter class, here in unmarshal method the input String is "16-Mar-05", but I cant get the localDate variable in the format of "16-Mar-05", although I am setting pattern to "dd-MMM-yy". I posted all the options I tried, how can I get my localDate in "dd-MMM-yy" like 16-Mar-05format?
Thanks!!
public class DateAdapter extends XmlAdapter<String, LocalDate> {
// the desired format
private String pattern = "dd-MMM-yy";
#Override
public String marshal(LocalDate date) throws Exception {
//return new SimpleDateFormat(pattern).format(date);
return date.toString("dd-MMM-yy");
}
#Override
public LocalDate unmarshal(String date) throws Exception {
if (date == null) {
return null;
} else {
//first way
final DateTimeFormatter dtf = DateTimeFormat.forPattern("dd-MMM-yy");
final LocalDate localDate2 = dtf.parseLocalDate(date);
//second way
LocalDate localDate3 = LocalDate.parse(date,DateTimeFormat.forPattern("dd-MMM-yy"));
//third way
DateTimeFormatter FORMATTER = DateTimeFormat.forPattern("dd-MMM-yy");
DateTime dateTime = FORMATTER.parseDateTime(date);
LocalDate localDate4 = dateTime.toLocalDate();
return localDate4;
}
}
So I took your code and ran it and it works fine for me...
The problem, I think, you're having is that you're expecting a LocalDate object to maintain the format that you original parsed the object with, this is not how LocalDate works.
LocalDate is a representation of date or period in time, it is not a format.
LocalDate has a toString method which can be used to dump the value of the object, it, this is a internal format used by the object to provide a human readable representation.
To format the date, you need to use some kind of formater, that will take the pattern you want and a date value and return a String
For example, the following code...
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
String date = "16-Mar-05";
DateTimeFormatter dtf = DateTimeFormat.forPattern("dd-MMM-yy");
LocalDate localDate2 = dtf.parseLocalDate(date);
System.out.println(localDate2 + "/" + dtf.print(localDate2));
//second way
LocalDate localDate3 = LocalDate.parse(date, DateTimeFormat.forPattern("dd-MMM-yy"));
System.out.println(localDate3 + "/" + dtf.print(localDate3));
//third way
DateTimeFormatter FORMATTER = DateTimeFormat.forPattern("dd-MMM-yy");
DateTime dateTime = FORMATTER.parseDateTime(date);
LocalDate localDate4 = dateTime.toLocalDate();
System.out.println(localDate4 + "/" + FORMATTER.print(localDate4));
Produced...
2005-03-16/16-Mar-05
2005-03-16/16-Mar-05
2005-03-16/16-Mar-05
Before you get upset about this, this is how Java Date works as well.

Categories