This question already has answers here:
String to Date conversion returning wrong value
(5 answers)
Closed 5 years ago.
I am trying to find the difference between two dates and I did the following:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class test {
public static void main(String[] args) {
Date date = new Date();
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-DD");
String accessioned = "2017-04-27";
System.out.println(date);
try {
date = format.parse(accessioned);
} catch (ParseException e) {
e.printStackTrace();
}
System.out.println(date);
Date now = new Date();
long diff = now.getTime() - date.getTime();
System.out.println(diff);
if ((diff / (1000 * 60 * 60 * 24)) >= 30) {
System.out.println("haha");
}
}
}
This is the output I get:
Fri Jul 21 14:23:59 CEST 2017
Fri Jan 27 00:00:00 CET 2017
15168239705
haha
The Problem is if I change the the String accessioned for e.g to "2017-04-28" the date changes accordingly, same thing for year but whatever value I put for month, It always outputs January. For e.g in my code it should be April but the output says Jan.
What am I doing wrong?
Change D to d (SimpleDateFormat Doc):
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
D is for day in year (1-365)
d is for day in month (1-31)
Also you can now use LocalDate from Java8 more convenient to use DateTimeFormatter Doc / LocalDate Doc
You apparently want to check if the difference of days is >=30 between your date and now or not, so I'll propose another solution with LocalDate :
LocalDate localDate = LocalDate.parse("2017-04-27", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
long daysDiff = localDate.until(LocalDate.now(), ChronoUnit.DAYS);
System.out.println(daysDiff);
if (daysDiff >= 30){
System.out.println("haha");
}
EDIT : You need to use LocalDateTime instead of LocalDate to be able to use hour/minute/sec also
LocalDateTime localDateTime = LocalDateTime.parse("2017-04-21T11:51:36Z", DateTimeFormatter.ISO_DATE_TIME);
The problem is your date format: new SimpleDateFormat("yyyy-MM-DD")
As listed here, M is already a two-digit format - and D stands for "Day in year", not "Day in month", which is d.
Your format should look like this:
SimpleDateFormat("y-M-d")
...which gives me:
Fri Jul 21 14:44:03 CEST 2017
Thu Apr 27 00:00:00 CEST 2017
7397043764
haha
Related
I am currently working on an issue where DateTime.addMonths(iStartDateH, durationAsInt) is adding an extra day. It uses GeorgianCalendar internally.
We are using Java 5 currently in this project
Eg: For 24 months
ExpirationDate=DateTime.addMonths(currentDate, 24)
CurrentDate= 01/02/2021 (dd/mm/yyyy format)
ExpirationDate= 02/02/2023
public static ErrorCode addMonths(DateHolder dateH, int numMonths) {
try {
Calendar c = new GregorianCalendar();
c.setTime(dateH.value);
c.add(Calendar.MONTH, numMonths);
dateH.value = c.getTime();
return ErrorCode.successCN;
}
catch (Exception e) {
IlMessage msg = new IlMessage(Msg.exceptionCaughtCN, e);
IlSession.getSession().getMessageStack().push(msg);
return ErrorCode.errorCN;
}
}
I tried checking the complete date/time difference and its coming as 730.773935185185185
Please help with the same.
I am using Java 8 and I tried the code below and it worked just fine for me (for testing purposes I set the date as Feb 1 as from your example.
public static void main(String...pStrings) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate currentDate = LocalDate.of(2021, 2, 1); //LocalDate.now();
System.out.println("Original Date -" +currentDate.format(formatter));
LocalDate newDate = currentDate.plusMonths(24);
System.out.println("updated date - " + newDate.format(formatter));
}
I received the output: -
Original Date -01/02/2021
updated date - 01/02/2023
Note that m is for minutes. For a month, you need to use M.
The implementation of your class, DateHolder seems to have a problem. There is no such problem with java.util date-time API for this requirement.
Demo:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws ParseException {
Calendar calendar = Calendar.getInstance();
calendar.setTime(new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH).parse("01/02/2021"));
System.out.println(calendar.getTime());
int numMonths = 24;
calendar.add(Calendar.MONTH, numMonths);
System.out.println(calendar.getTime());
}
}
Output:
Mon Feb 01 00:00:00 GMT 2021
Wed Feb 01 00:00:00 GMT 2023
This question already has answers here:
How can I increment a date by one day in Java?
(32 answers)
SimpleDateFormat ignoring month when parsing
(4 answers)
Closed 4 years ago.
I wish to add one day to a given date.If i pass 2018-08-05,the below method returns 2018-08-06 which is expected. But if the pass the last date of the month -2018-08-31,it returns 2018-08-01 instead of expected result 2018-09-01.
DateFormat format = new SimpleDateFormat("yyyy-mm-dd", Locale.ENGLISH);
Date date = null;
try {
date = format.parse("2018-08-31");
} catch (ParseException e) {
}
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DATE ,1);
return format.format(cal.getTime());
You're using the old calendar/date API. This API is quite bad (it does weird things and does not accurately model how dates actually work).
It has been replaced with the new java.time API. I strongly suggest you use that instead. If you're on java7 or below, you can use the 'JSR310-backport' library to your dependency list to use this API. (JSR310 is the name for this addition to java).
In java.time, you'd do:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class Test {
public static void main(String[] args) {
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate date = LocalDate.parse("2018-08-31", fmt);
System.out.println(fmt.format(date.plusDays(1)));
// yyyy-MM-dd so happens to be the default for LocalDate, so...
// we can make it a lot simpler:
date = LocalDate.parse("2018-08-31");
System.out.println(date.plusDays(1));
}
}
The bug is in the pattern of your SimpleDateFormat which you use for input and output. This dual-use masks the error:
public class Main {
public static void main(String[] args) throws Exception {
DateFormat format = new SimpleDateFormat("yyyy-mm-dd", Locale.ENGLISH);
Date date = format.parse("2018-08-31");
System.out.println("format: " + format.format(date) +", real: " + date);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DATE ,1);
System.out.println("format: " + format.format(cal.getTime()) +", real: " + cal.getTime());
}
}
This gives you:
format: 2018-08-31, real: Wed Jan 31 00:08:00 CET 2018
format: 2018-08-01, real: Thu Feb 01 00:08:00 CET 2018
Using the right pattern yyyy-MM-dd produces the right answer:
format: 2018-08-31, real: Fri Aug 31 00:00:00 CEST 2018
format: 2018-09-01, real: Sat Sep 01 00:00:00 CEST 2018
Since the new and the old Java-Time API use the same patterns, simply adopting the new API will not help in this case.
DateFormat format = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH);
Date date = null;
try {
date = format.parse("2018-08-31");
} catch (ParseException e) {
}
Calendar cal = new GregorianCalendar();
cal.setTime(date);
cal.setTimeInMillis(cal.getTimeInMillis() + 86400000); //86400000ms = 1 day
return format.format(cal.getTime());
This question already has answers here:
Convert string dates in java [duplicate]
(3 answers)
Closed 5 years ago.
The string is of the format dd/mm/yyyy
I am parsing using the following code:-
Dateformat dateformatter = new SimpleDateFormat("EEE, MMM d, ''yy");
dateformatter.setLenient(false );
String temp = "7/07/2017"
Date date = null;
try {
date = new SimpleDateFormat("dd/mm/yyyy").parse(temp);
}
catch(ParseException e){
e.printStackTrace();
}
dateformatter.format(date);
The value that I get for date is Sat Jan 07 00:07:00 GMT + 10:00 2017
After formatting I get Sat, Jan 7, '17
The value I expect is FRI Jul 07, '17
The issue is in this line
date = new SimpleDateFormat("dd/mm/yyyy").parse(temp);
In the SimpleDateFormat, Month is denoted with M and not m.
M - Month in year (context sensitive)
m - Minute in hour
Change this to
date = new SimpleDateFormat("dd/MM/yyyy").parse(temp);
For more details, check the official documentation of SimpleDateFormat
Situation: There is an Object AuditLog, which contains the variable java.util.Date date. This Object is saved in a mySQL Database.
#Entity
public class AuditLog implements Persistable<Long> {
...
#Temporal(TemporalType.DATE)
private Date date;
...
}
I am writing some JUnit tests and need to verify that a saved Date equals the actual date. Where date is a local Copy of the value actually passed to the log Object before it got saved and then loaded again.
Assert.assertEquals(date, log.getDate());
Output:
expected:<Wed May 24 15:54:40 CEST 2017> but was:<2017-05-24>
So you can see that the date actually is the right one but only y-m-d
I then tried this (below) to check if the milliseconds get altered.
Assert.assertEquals(date.getTime(), log.getDate().getTime());
Output:
expected:<1495634973799> but was:<1495576800000>
Now i think the best way would be to get the Milliseconds for year month day only.
Question: Can this be achieved relatively simple and should i do this? I think the Date gets altered because of a Database operation of some kind, so adapting the Test is OK right?
There are two ways to do this:
Using local date : You can convert util Date to LocalDate and do assertEquals on both the objects. LocalDate won't have time, e.g.:
Date input = new Date();
LocalDate date = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
System.out.println(date);
Using Apache commons' DateUtils: You can use truncate method to set non date fields to zero, e.g.:
Date input = new Date();
Date truncated = DateUtils.truncate(input, Calendar.DATE);
System.out.println(truncated);
Here's the maven dependency for Apache commons library.
You can get the "just the day, month, year by using the following code:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class Answer {
public static void main(String args[]) throws ParseException {
// parse the date and time
String input = "Wed May 24 15:54:40 CEST 2017";
SimpleDateFormat parser = new SimpleDateFormat("EEE MMM d HH:mm:ss zzz yyyy");
Date date = parser.parse(input);
// parse just the date
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
formatter.setTimeZone(TimeZone.getTimeZone("CEST"));
String formattedDate = formatter.format(date);
Date parsedDate = formatter.parse(formattedDate);
System.out.println(parsedDate);
// use https://currentmillis.com/ to check the milliseconds figures
System.out.println("Wed May 24 15:54:40 CEST 2017 in milliseconds \t" + date.getTime());
System.out.println("Wed May 24 00:00:00 CEST 2017 in milliseconds \t" + parsedDate.getTime());
}
}
The second SimpleDateFormat("yyyy-MM-dd"); parses on the year-month-day.
Use Date.getTime()); to get the milliseconds.
The output is:
Wed May 24 15:54:40 CEST 2017 in milliseconds 1495634080000
Wed May 24 00:00:00 CEST 2017 in milliseconds 1495584000000
1495584000000 = Wed May 24 2017 00:00:00 (using https://currentmillis.com/)
Calendar cal = GregorianCalendar.getInstance();
cal.set(Calendar.YEAR, 2017);
cal.set(Calendar.MONTH, 5 - 1);
cal.set(Calendar.DAY_OF_MONTH, 24);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
Date d = cal.getTime();
System.out.println(d.getTime());
this code creates a new java.util.Date with only year, month and day set. result of this example is 1495576800000 which is what you want.
A shorter way would be this:
Date d = new Date(0l);
d.setYear(117);
d.setMonth(4);
d.setDate(24);
d.setHours(0);
You should format the two dates:
Date date = new Date();
SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd");
dt.format(date);
Then compare each other.
I have taken this date "2016-04-26 12:00:00”, and converted to GMT and CST epochs, using the function below. I got the dates below. Not sure I am doing anything wrong here.
1461672000000 UTC ——> Tue, 26 Apr 2016 12:00:00 GMT
1461690000000 CST —> Tue, 26 Apr 2016 17:00:00 GMT
Code:
long epoch = 0;
String str = "2016-04-26 12:00:00";
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("CST")); //This GMT or CST
Date datenew = df.parse(str); //parsethe date
epoch = datenew.getTime(); //get the epoch time
As eluded to by Erickson in the comments, your expectations seem inverted from the implementation; when you set the TimeZone in the DateFormat, using the DateFormat.parse() method results in the string it's parsing as if it is coming from that TimeZone (and converts it to the local time). So the results you notice are exactly expected.
To fix this, use the DateFormat.format() method instead:
public static void main(String[] args) {
String dateStr = "2016-04-26 12:00:00";
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("GMT"));
Date gmtDate = null;
try {
gmtDate = df.parse(dateStr);
}
catch (ParseException e) {
e.printStackTrace();
}
System.out.println("GMT TIME = " + df.format(gmtDate));
df.setTimeZone(TimeZone.getTimeZone("CST"));
System.out.println("CST TIME = " + df.format(gmtDate));
}
Output:
GMT TIME = 2016-04-26 12:00:00
CST TIME = 2016-04-26 07:00:00