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
Related
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:
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
According to the following website daylight saving time in UK starts from 27 Mar-2016 1:00:00 (24 hours time format)
http://www.timeanddate.com/time/change/uk/london?year=2016
Then why the following code prints false?
import java.text.ParseException;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.TimeZone;
public class BSTGMTDetector
{
public static void main(String[] args) throws ParseException
{
TimeZone def = TimeZone.getTimeZone("Europe/London");
Calendar cal = new GregorianCalendar();
cal.clear();
cal.set(2016, 2, 27,2,01,01);
boolean isInDaylight = def.inDaylightTime(cal.getTime());
System.out.println("Date[" + cal.getTime() + "] is in DST[" + isInDaylight + "]");
}
}
Output : Date[Sun Mar 27 02:01:01 IST 2016] is in DST[false]
It seems that your system maintain IST.When you define,
Calendar cal = new GregorianCalendar();
Timezone for cal variable is IST.So,when call
def.inDaylightTime(cal.getTime());
Date is passed to this method in IST timezone.So,DST start for UK at 27th MAR,06:30:00 IST.
Hence.your O/P behaviour.
I have the following code:
import java.util.Date;
import java.util.Calendar;
import java.text.SimpleDateFormat;
import org.junit.Test;
public class DateCalendarTest {
#Test
public void test1() {
private final DateFormat df1 = new SimpleDateFormat("MM/dd/yyyy");
String batchdt = "2015/09/23";
System.out.println("Date & Calendar Test: " + batchdt);
Calendar cal = Calendar.getInstance();
Date date1 = df1.parse(batchdt);
cal.setTime(date1);
System.out.println("Date & Calendar Test: " + cal.getTime());
}
}
Output:
Date Calendar Test: 2015/09/23
Date Calendar Test: Mon Nov 09 00:00:00 EST 190
Can someone please explain why this behaves in this manner?
Your intended data doesn't match the format specified in your SimpleDateFormat. However, by default, it is lenient in how it parses the data. For example, September 31st would be interpreted as October 1st.
Here, it's interpreted as day 9 of month 2,015 of year 23. 2,015 months is 167 years, 11 months, which when added to the year 23 yields the year 190. In this case, it is very lenient.
The output format is what is expected when printing out a Date directly.
I thought I'd be able to create a GregorianCalendar using the constructor that takes the year, month, and day, but I can't reliably get those fields from an instance of the java.sql.Date class. The methods that get those values from java.sql.Date are deprecated, and the following code shows why they can't be used:
import java.sql.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class DateTester {
public static void main(String[] args) {
Date date = Date.valueOf("2011-12-25");
System.out.println("Year: " + date.getYear());
System.out.println("Month: " + date.getMonth());
System.out.println("Day: " + date.getDate());
System.out.println(date);
Calendar cal = new GregorianCalendar(date.getYear(), date.getMonth(), date.getDate());
System.out.println(cal.getTime());
}
}
Here's the output, showing that the month and year are not returned correctly from the deprecated getYear() and getMonth() methods of Date:
Year: 111
Month: 11
Day: 25
2011-12-25
Thu Dec 25 00:00:00 EST 111
Since I can't use the constructor that I tried above, and there's no GregorianCalendar constructor that just takes a Date, how can I convert a java.sql.Date object into a GregorianCalendar?
You have to do this in two steps. First create a GregorianCalendar using the default constructor, then set the date using the (confusingly named) setTime method.
import java.sql.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class DateTester {
public static void main(String[] args) {
Date date = Date.valueOf("2011-12-25");
System.out.println(date);
Calendar cal = new GregorianCalendar();
cal.setTime(date);
System.out.println(cal.getTime());
}
}
Here's the output:
2011-12-25
Sun Dec 25 00:00:00 EST 2011
I'm going from memory, but have you tried
Calendar cal = GregorianCalendar.getInstance();
cal.setTime(rs.getDate());
Try this.
import java.sql.Date;
import java.util.Calendar;
import java.util.GregorianCalendar;
public class DateTester {
public static void main(String[] args) {
Date date = Date.valueOf("2011-12-25");
System.out.println(date);
Calendar cal = new GregorianCalendar();
cal.setTime(date);
System.out.println(cal.getTime());
}
}
Use setTimeInMillis():
java.sql.Date date = new java.sql.Date(System.currentTimeMillis());
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(date.getTime());
I think this is the simplest way.