If I do:
public static void main(String[] args) {
LocalDate d1 = LocalDate.of(2015, Month.MARCH, 12);
LocalDate d2 = LocalDate.of(2015, Month.APRIL, 13);
System.out.println(d1.until(d2).getDays());
// Prints 11
LocalDate d3 = LocalDate.of(2015, Month.APRIL, 25);
// Prints 23.
Both of which are incorrect. The second output makes sense as there is 1 month and 23 days between them.
How do I get the total number of days between?
I would want the first output to be 32 Days and the second to be 44 days (the total number of days between
the two dates).
What am I doing wrong? I don't see a totalDays() method.
You should probably not use a period (which has year and month components) if you are only interested in days. One solution to your question is:
System.out.println(DAYS.between(d1, d2)); //32
or alternatively:
System.out.println(d1.until(d2, DAYS)); //32
Note: I'm using import static java.time.temporal.ChronoUnit.DAYS;
I don't know how much you want to do with dates and possible you don't need it but I really recommend Joda Time and here is how to get number of days between two dates.
In Java 8 we finally have good Dates library but if you don't use Java 8 then you have to get Joda Time
Related
I'm a newbie to Java. I am given 3 times, in the "HH:mm:ss" format. I'm supposed to take an input(in integers(and must be in minutes)) add it to the 3rd time. If the sum of time is less than the 1st and 2nd time(1st time <=2nd time), it must print 1. If it is only less than the 2nd time, it should print 2. If neither is less, it prints false.
However, the values of the double variable I'm mapping the date to are returning
values in the negative sometimes (Please check the output).
Could someone help me understand why? Thanks.
import java.util.*;
import java.text.*;
public class TimeTrial2 {
public static void main(String q[]) throws ParseException
{
Scanner x=new Scanner(System.in);
SimpleDateFormat y=new SimpleDateFormat("HH");
SimpleDateFormat k=new SimpleDateFormat("HH:mm:ss");
String b=x.nextLine();
Date c=k.parse(b);//1st Time
String d=x.nextLine();
Date e=k.parse(d);//2nd Time
String f=x.nextLine();
Date g=k.parse(f);//Time to be added to the input
int a=x.nextInt();//Input time i
a=a/60;
Date z=y.parse(Integer.toString(a));
double p=(z.getTime()+g.getTime());
double r=c.getTime();
double s=e.getTime();
System.out.println(p+"\n"+r+"\n"+s); `//to check the values of p,r and s`
if(r>=p)
{
System.out.println("1");
}
else if(s>=p)
{
System.out.println("2");
}
else
{
System.out.println("FALSE!");
}
}
}
Input:
4:30:00
6:00:00
4:00:00
60
This is my output:
-2.16E7
-3600000.0
1800000.0
1
Edit: Adding 330 minutes (+5:30 GMT) rectifies the issue.
However, I'd recommend using Ole V.V's answer as it is much easier. I was unaware that such a date class and method existed. Thank you all for your help.
Consider how you add the time to the Date. I tried out the following code for adding minutes to the date and it worked.
Calendar calendar = GregorianCalendar.getInstance();
calendar.setTime(g);
calendar.add(GregorianCalendar.MINUTE, a);
Input:
g = 5:00:00
a = 40
Output:
Thu Jan 01 05:00:00 IST 1970
Thu Jan 01 05:40:00 IST 1970
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Scanner;
public class TimeTrial3 {
public static void main(String... commandLineArguments) {
Scanner consoleInput = new Scanner(System.in);
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("H:mm:ss");
String time1String = consoleInput.nextLine();
LocalTime time1 = LocalTime.parse(time1String, timeFormatter);
String time2String = consoleInput.nextLine();
LocalTime time2 = LocalTime.parse(time2String, timeFormatter);
if (time2.isBefore(time1)) {
System.err.println("First time must be before or equal to second time, they were"
+ time1 + " and " + time2);
System.exit(1);
}
String timeToAddString = consoleInput.nextLine();
LocalTime timetoAdd = LocalTime.parse(timeToAddString, timeFormatter);
int minutesToAdd = consoleInput.nextInt();
LocalTime timeToCompare = timetoAdd.plusMinutes(minutesToAdd);
if (timeToCompare.isBefore(time1))
{
System.out.println("1");
}
else if (timeToCompare.isBefore(time2))
{
System.out.println("2");
}
else
{
System.out.println("False");
}
}
}
Issues with your code
The Date class isn’t very well suited for representing a time of day only.
The Date and SimpleDateFormat classes are long outdated and the latter in particular notoriously troublesome. I recommend you don’t use them at all. Instead I am using and warmly recommending java.time, the modern Java date and time API. It is so much nicer to work with.
When you can use library classes for dates and/or times, do that. Don’t use double nor long.
An observation, not really a problem: It seems you are in a time zone at offset -05:30 from UTC (like Sri Lanka or India)? For example, your input of 4:30:00 was parsed into this time on January 1, 1970 (the epoch day) at offset -5:50, which is equal to 1 hour before the epoch, so it came out as -3600000.0 because -3600 seconds equals -1 hour. This is not a problem in itself as long as all your times are at the same offset. Then you can still compare them using before or after as harsha kumar Reddy said in another answer.
The trouble comes when you try to add the milliseconds from two Date objects. The third time, 4:00:00, is parsed into 1 hour 30 min before the epoch, and the 60 minutes into 4 hours 30 minutes before the epoch. When adding the two you expect a time of 5:00:00 (in your time zone). Instead you get 6 hours before the epoch, which is printed as -2.16E7 (on my computer I get a different incorrect result because I am in a different time zone).
By dividing the minutes from input by 60 to obtain hours, you are losing precision. For example, if the input was 90 minutes (one and a half hours), you get just 1 hour after division.
And as mentioned in the comment, you should use explanatory variable names. You may have had an idea behind the names you chose, but I didn’t get it.
Link
Oracle tutorial: Date Time explaining how to use java.time.
Try using equals() , before() , after() methods of Date class .
refer java Api docs
I am trying to obtaining remaining years, months, and days between two dates:
So I have used Joda Time to do so:
DateTime endDate = new DateTime(2018,12,25,0,0);
DateTime startDate = new DateTime();
Period period = new Period(startDate,endDate,PeriodType.yearMonthDay());
PeriodFormatter formatter = new PeriodFormatterBuilder().appendYears().appendSuffix(" Year ").
appendMonths().appendSuffix(" Month ").appendDays().appendSuffix(" Day ").appendHours()..toFormatter();
String time = formatter.print(period);
This gives me string time: 2 Year 4 Month 22 Day
However, I want integer values of each number of remaining years, months, days.
So, Instead of "2 Year 4 Month 22 Day", I want to set my variables:
int year = 2
int month = 4
int day = 22
Is there any way to obtain these values separately instead of obtaining one string? Thank you so much! :)
i had the same requirement once ,here is the code snippet
LocalDate d=LocalDate.of(yy,mm,dd);
LocalDate d2=LocalDate.of(yy, mm, dd);
Period p=Period.between(d, d2);
long day,month,year;
day=p.getDays();
month=p.getMonths();
year=p.getYears();
System.out.println(day+" : "+month+" : "+year);
Invoke the methods provided by the DateTime class and just subtract them. An example for years is below:
int year = (int) dateTime#year#getField() - (int) dateTime2#year#getField()
UNTESTED code!! I'll be looking into it later but the general idea is the same, get the field information then just subtract it to get a value
I noticed a strange behaviour of the TimeUnit class, so I created this minimal example to reproduce it.
long differenceInDays;
Calendar c1 = Calendar.getInstance();
Calendar c2 = Calendar.getInstance();
c1.setTimeInMillis(1466062306000l); // Thu Jun 16 2016 09:31:46 GMT+0200
c2.setTimeInMillis(1466028000000l); // Thu Jun 16 2016 00:00:00 GMT+0200
differenceInDays = TimeUnit.DAYS.convert(c2.getTimeInMillis() - c1.getTimeInMillis(), TimeUnit.MILLISECONDS);
System.out.println(differenceInDays); // obviously zero
c2.add(Calendar.DATE, +1);
differenceInDays = TimeUnit.DAYS.convert(c2.getTimeInMillis() - c1.getTimeInMillis(), TimeUnit.MILLISECONDS);
System.out.println(differenceInDays); // why zero and not one?
c2.add(Calendar.DATE, +1);
differenceInDays = TimeUnit.DAYS.convert(c2.getTimeInMillis() - c1.getTimeInMillis(), TimeUnit.MILLISECONDS);
System.out.println(differenceInDays); // suddenly a 1, but not a 2 like expected
It is obvious that the first time the difference is calculated it is 0, because not a whole day lies between the dates.
But the second time a whole day is added, so how can the difference be still 0?
Output:
001
I don't think this problem is daylight saving time or leap year related because I only do calculations within the same year, even month.
Here is a date to milliseconds calculator for you to check.
You can see better what's going on here with simple math:
c1 = 1466062306000
c2 = 1466028000000
d = 86400000 // one day
c2 - c1 = -34306000 // negative, but less than one day in magnitude
c2 - c1 + d = 52094000 // less than one day
c2 - c1 + d + d = 138494000 // more than one day, less than two days
The correct way to handle this, assuming you're using Java 8, is as follows:
// Decide what time zone you want to work in
ZoneId tz = ZoneId.of("Europe/Berlin");
// If you wanted the local time zone of the system,
// Use this instead:
// ZoneId tz = ZoneId.systemDefault();
// Get instants from the timestamps
Instant i1 = Instant.ofEpochMilli(1466062306000l);
Instant i2 = Instant.ofEpochMilli(1466028000000l);
// Get the calendar date in the specified time zone for each value
LocalDate d1 = i1.atZone(tz).toLocalDate();
LocalDate d2 = i2.atZone(tz).toLocalDate();
// Get the difference in days
long daysBetween = ChronoUnit.DAYS.between(d2, d1);
If your inputs are truly Calendar objects instead of timestamps, I'd suggest Calendar.toInstant() as described in the Legacy Date-Time Code guidance.
If you're using Java 7 or earlier, you will find similar capabilities from the Joda Time library.
if you really don't want to use any of these, and still do things the old (hard) way, then see this example.
Hi I need to calculate the difference between two dates and output can be one of these -- days or months or years and the output calculates all part so it can be in fraction also.
e.g:
24.03.15-14.04.15 (in days)=-21
24.03.15-14.04.15 (in months)=-0.75
24.03.15-14.04.15 (in years)=-1/12
Not able to calculate this.
Please explain it.
Use Joda:
LocalDate d1 = new LocalDate(2015, 3, 15);
LocalDate d2 = new LocalDate(2015, 4, 14);
int days = Days.daysBetween(d1, d2).getDays();
I am trying to check if a given interval is greater than 12 months using the following code:
public void testMonths() throws Exception {
DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-mm");
DateTime from = format.parseDateTime("2010-01");
DateTime until = format.parseDateTime("2011-06");
int months = Months.monthsBetween(from, until).getMonths();
assertTrue(months > 12); // months = 12 for some reason.
}
Whenever the given interval is more then a year it will truncate the remaining months in the last year.
Input I've tried running:
15 months will return 12 months.
25 months will return 24 months.
36 months will return 36 months.
37 months will return 36 months.
The problem is your text pattern. "mm" means "minutes" not "months". If you change your pattern to "yyyy-MM" you'll find it works fine.
As a guiding principle the first thing I would do in a situation like this is try to isolate this to the smallest possible problem. So take text parsing and the complexity of DateTime (time zones etc) out of the equation:
LocalDate from = new LocalDate(2010, 1, 1);
LocalDate to = new LocalDate(2011, 6, 1);
int months = Months.monthsBetween(from, to).getMonths();
Now you'll see it's 17. So then the next step would be to go back to your original code, and print out the values of from and to... and you'll see something like:
2010-01-01T00:01:00.000Z
2011-01-01T00:06:00.000Z
Basically, avoid text parsing unless that's fundamentally part of the problem you're trying to diagnose.