How to check if first date is older than second? - java

First I get:
LocalDate today = LocalDate.now();
and second
Date date = new Date();
date.setDate(Integer.valueOf(s[0]));
date.setMonth(Integer.valueOf(s[1]));
date.setYear(Integer.valueOf(s[2]));
LocalDate topicDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
How to check whether the differences between the first date and the second is 7 days?
For example, today is 03-08-2015 and the second date is 20-07-2015 and the difference between is more than 7 days, but how to check this?
Should I convert date to millisecond?

I Believe that is still the best way at the moment.
You can view some insights on the subject here:
Calculate date/time difference in java

You could convert to milliseconds or you could individually check if the year was larger, then if they are the same check to see if the month is larger then check day. Converting to milliseconds would be very easy though.

I believe you are looking for something like this:
Date date = /*your date object you want to compare*/;
Instant now = Instant.now();
Instant sevenDaysFromYourDate = Instant.ofEpochMilli(date.getTime()).plus(Duration.ofDays(7));
if (now.isAfter(sevenDaysFromYourDate)) {
//today is more than seven days past date
}

LocalDate today = LocalDate.now();
if (topicDate.isAfter(today.plusDays(7))) {
System.out.println("Yes");
}
else {
System.out.println("No");
}

Since you are using Java 8 LocalDate, you can use the plusDays or minusDays methods of the LocalDate class.
Furthermore, you shouldn't be using an (old, not recommended for use) java.util.Date object to create your second date. It's better to use LocalDate.of which builds a date from the year, month and day.
Example code:
LocalDate today = LocalDate.now();
LocalDate topicDate = LocalDate.of(
Integer.valueOf(s[2]),
Integer.valueOf(s[1]),
Integer.valueOf(s[0]));
System.out.println(today);
System.out.println(topicDate);
if ( today.minusDays(7).equals(topicDate)) {
System.out.println( "Exactly a week difference between today and topicDate");
} else if ( today.minusDays(7).compareTo(topicDate) > 0 ) {
System.out.println("TopicDate is more than a week before today");
} else {
System.out.println("TopicDate is less than a week before today");
}
Note that you can use the compareTo for exact equality as well - I just wanted to demonstrate that for equality, equals also works.
And of course, there are the isAfter and isBefore methods that also do the comparison in an elegant way.

Related

How to get the exact first date and time of last month?

I wish to get the exact date of first day of last month at 00:00:00Z.
So, here is my current solution:
public static String getStartingDateAndTimeOfLastMonth() {
int dayOfCurrentMonth = ZonedDateTime.now().getDayOfMonth();
return ZonedDateTime.now()
.minusDays(dayOfCurrentMonth - 1)
.minusMonths(1)
.format(DateTimeFormatter.ISO_INSTANT);
}
When i call the moethod:
String startDate = CustomUtilsFunctions.getStartingDateAndTimeOfLastMonth();
System.out.println("startDate: " + startDate);
The output of current solution is:
startDate: 2021-05-01T07:22:10.389Z
As you can see, the time of the output is 07:22:10.389Z but, I don't know the easiest way to turn it to 00:00:00:000Z
So the desired output for is:
startDate: 2021-05-01T00:00:00.000Z
Point:
I know, i can extract the hour, minutes and seconds and millis and then use the minus(), but I believe there must be an easier solution.
Instead of using today as base, you could use a java.time.YearMonth (like this month) and subtract one month to get the last one. Then take the start of its first day. Do all that in UTC and then format as desired:
public static String getStartingDateAndTimeOfLastMonth() {
// get the current month and subtract one to get the last
YearMonth lastMonth = YearMonth.now().minusMonths(1);
// then return its first day
return lastMonth.atDay(1)
// at the beginning of the day in UTC
.atStartOfDay(ZoneOffset.UTC)
// formatted as desired
.format(
DateTimeFormatter.ofPattern(
"uuuu-MM-dd'T'HH:mm:ss.SSSX",
Locale.ENGLISH
)
);
}
This outputs today (10th of June, 2021):
2021-05-01T00:00:00.000Z
Note: The default format of ZonedDateTime omits seconds and fraction-of-second if they are zero.
If you are fine with 2021-05-01T00:00Z, you can replace
.format(
DateTimeFormatter.ofPattern(
"uuuu-MM-dd'T'HH:mm:ss.SSSX",
Locale.ENGLISH
)
);
with simply .toString();.
You could first create the desired day and then use it together with a set time to compose DateTime. Depending on your use case, you could use LocalDateTime or ZonedDateTime.
LocalDate day = LocalDate.now()
.minusMonths(1)
.withDayOfMonth(1);
ZonedDateTime target = ZonedDateTime.of(day, LocalTime.MIDNIGHT, ZoneId.systemDefault());
System.out.println(target);
Another option would be to use turncatedTo (as #Thomas mentioned in comment)
ZonedDateTime target = ZonedDateTime.now()
.minusMonths(1)
.withDayOfMonth(1)
.truncatedTo(ChronoUnit.DAYS)
.withZoneSameLocal(ZoneId.of("UTC")); // optional depending on your case

Java 8 calculate months between two dates

NOTE THIS IS NOT A DUPLICATE OF EITHER OF THE FOLLOWING
Calculating the difference between two Java date instances
calculate months between two dates in java [duplicate]
I have two dates:
Start date: "2016-08-31"
End date: "2016-11-30"
Its 91 days duration between the above two dates, I expected my code to return 3 months duration, but the below methods only returned 2 months. Does anyone have a better suggestion? Or do you guys think this is a bug in Java 8? 91 days the duration only return 2 months.
Thank you very much for the help.
Method 1:
Period diff = Period.between(LocalDate.parse("2016-08-31"),
LocalDate.parse("2016-11-30"));
Method 2:
long daysBetween = ChronoUnit.MONTHS.between(LocalDate.parse("2016-08-31"),
LocalDate.parse("2016-11-30"));
Method 3:
I tried to use Joda library instead of Java 8 APIs, it works. it loos will return 3, It looks like Java duration months calculation also used days value. But in my case, i cannot use the Joda at my project. So still looking for other solutions.
LocalDate dateBefore= LocalDate.parse("2016-08-31");
LocalDate dateAfter = LocalDate.parse("2016-11-30");
int months = Months.monthsBetween(dateBefore, dateAfter).getMonths();
System.out.println(months);
Since you don't care about the days in your case. You only want the number of month between two dates, use the documentation of the period to adapt the dates, it used the days as explain by Jacob. Simply set the days of both instance to the same value (the first day of the month)
Period diff = Period.between(
LocalDate.parse("2016-08-31").withDayOfMonth(1),
LocalDate.parse("2016-11-30").withDayOfMonth(1));
System.out.println(diff); //P3M
Same with the other solution :
long monthsBetween = ChronoUnit.MONTHS.between(
LocalDate.parse("2016-08-31").withDayOfMonth(1),
LocalDate.parse("2016-11-30").withDayOfMonth(1));
System.out.println(monthsBetween); //3
Edit from #Olivier Grégoire comment:
Instead of using a LocalDate and set the day to the first of the month, we can use YearMonth that doesn't use the unit of days.
long monthsBetween = ChronoUnit.MONTHS.between(
YearMonth.from(LocalDate.parse("2016-08-31")),
YearMonth.from(LocalDate.parse("2016-11-30"))
)
System.out.println(monthsBetween); //3
Since Java8:
ChronoUnit.MONTHS.between(startDate, endDate);
//Backward compatible with older Java
public static int monthsBetween(Date d1, Date d2){
if(d2==null || d1==null){
return -1;//Error
}
Calendar m_calendar=Calendar.getInstance();
m_calendar.setTime(d1);
int nMonth1=12*m_calendar.get(Calendar.YEAR)+m_calendar.get(Calendar.MONTH);
m_calendar.setTime(d2);
int nMonth2=12*m_calendar.get(Calendar.YEAR)+m_calendar.get(Calendar.MONTH);
return java.lang.Math.abs(nMonth2-nMonth1);
}
The documentation of Period#between states the following:
The start date is included, but the end date is not.
Furthermore:
A month is considered if the end day-of-month is greater than or equal to the start day-of-month.
Your end day-of-month 30 is not greater than or equal to your start day-of-month 31, so a third month is not considered.
Note the parameter names:
public static Period between​(LocalDate startDateInclusive, LocalDate endDateExclusive)
To return 3 months, you can increment the endDateExclusive by a single day.
In case you want stick to java.time.Period API
As per java.time.Period documentation
Period between(LocalDate startDateInclusive, LocalDate endDateExclusive)
where
#param startDateInclusive the start date, inclusive, not null
#param endDateExclusive the end date, exclusive, not null
So it is better to adjust your implementation to make your end date inclusive and get your desired result
Period diff = Period.between(LocalDate.parse("2016-08-31"),
LocalDate.parse("2016-11-30").plusDays(1));
System.out.println("Months : " + diff.getMonths());
//Output -> Months : 3
You have to be careful, never use LocalDateTime to calculate months between two dates the result is weird and incorrect, always use LocalDate !
here's is some code to prove the above:
package stack.time;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
public class TestMonthsDateTime {
public static void main(String[] args) {
/**------------------Date Time----------------------------*/
LocalDateTime t1 = LocalDateTime.now();
LocalDateTime t2 = LocalDateTime.now().minusMonths(3);
long dateTimeDiff = ChronoUnit.MONTHS.between(t2, t1);
System.out.println("diff dateTime : " + dateTimeDiff); // diff dateTime : 2
/**-------------------------Date----------------------------*/
LocalDate t3 = LocalDate.now();
LocalDate t4 = LocalDate.now().minusMonths(3);
long dateDiff = ChronoUnit.MONTHS.between(t4, t3);
System.out.println("diff date : " + dateDiff); // diff date : 3
}
}
My 2%
This example checks to see if the second date is the end of that month. If it is the end of that month and if the first date of month is greater than the second month date it will know it will need to add 1
LocalDate date1 = LocalDate.parse("2016-08-31");
LocalDate date2 = LocalDate.parse("2016-11-30");
long monthsBetween = ChronoUnit.MONTHS.between(
date1,
date2);
if (date1.isBefore(date2)
&& date2.getDayOfMonth() == date2.lengthOfMonth()
&& date1.getDayOfMonth() > date2.getDayOfMonth()) {
monthsBetween += 1;
}
After the short investigation, still not totally fix my question, But I used a dirty solution to avoid return the incorrect duration. At least, we can get the reasonable duration months.
private static long durationMonths(LocalDate dateBefore, LocalDate dateAfter) {
System.out.println(dateBefore+" "+dateAfter);
if (dateBefore.getDayOfMonth() > 28) {
dateBefore = dateBefore.minusDays(5);
} else if (dateAfter.getDayOfMonth() > 28) {
dateAfter = dateAfter.minusDays(5);
}
return ChronoUnit.MONTHS.between(dateBefore, dateAfter);
}
The Java API response is mathematically accurate according to the calendar. But you need a similar mechanism, such as rounding decimals, to get the number of months between dates that matches the human perception of the approximate number of months between two dates.
Period period = Period.between(LocalDate.parse("2016-08-31"), LocalDate.parse("2016-11-30"));
long months = period.toTotalMonths();
if (period.getDays() >= 15) {
months++;
}

How many instances of a partial date (month & day) appear in a range, and its day of the week

In Java, how would I go about constructing a utility that would take a range of dates (start and end date) and then would see how many times a given partial date ( the month and day-of-month) appears in that range, and will add an entry to a list for each match.
In my instance, I want to give it a range of say 5 years - starting Jan 1st 2014 and going to Dec 31st 2019. My check date is the 2nd August. I want the method to return the full information about each match of any August 2 of any year in the range. So for 2014 is will return Saturday 2nd August 2014, then Sunday 2nd August 2015 etc and so on.
I've been trying to get something working so far with Joda Time and the default date/calendar classes in Java and I'm just getting myself in a mess.
Thanks,
S
Edit: How silly of me, apologies for not adding my code :(
public static List<Date> getDaysInRange(Date startdate,
Date enddate,
Date checkDate) {
SimpleDateFormat sdf = new SimpleDateFormat("MMdd");
List<Date> dates = new ArrayList<>();
Calendar cal = new GregorianCalendar();
cal.setTime(startdate);
while (cal.getTime().before(enddate)) {
if (sdf.format(cal.getTime()).equals(sdf.format(checkDate))) {
Date result = cal.getTime();
dates.add(result);
}
cal.add(Calendar.DATE, 1);
}
return dates;
}
Date-Only
Since you want only a date without time-of-day and without time zone, use a date-only class. The old java.util.Date/.Calendar classes lack such a class. And those old classes are notoriously troublesome and flawed.
Instead use either:
Joda-Time
java.time, built into Java 8, inspired by Joda-Time.
Joda-Time
Here is some untested code using Joda-Time 2.6.
The main idea is to focus on the small set of possible year numbers rather than test every day of year. In the example below, that means six date-time values to compare rather than thousands. Besides efficiency, the purpose of the code becomes more apparent.
The arguments to your routine should be a month number and a day-of-month number, a pair of ints or Integers, rather than a Date. As seen in this examples two int variables, month and day.
LocalDate start = new LocalDate( 2011, 2, 3 );
LocalDate stop = new LocalDate( 2016, 4, 5 );
int yearStart = start.getYear();
int yearStop = stop.getYear();
int month = 11;
int day = 22;
for ( i = yearStart, i <= yearStop, i++ )
{
LocalDate x = new LocalDate( i, month, day );
boolean matchStart = ( x.isEqual( start ) || x.isAfter( start ) );
boolean matchStop = x.isBefore( stop ); // Half-Open approach where beginning of range is inclusive while ending is exclusive.
if ( matchStart && matchStop )
{
// Add to collection of LocalDate objects.
// Later you can ask each LocalDate object for its day-of-week.
{
}
java.time
The java.time package also offers a LocalDate class. The code would be similar to the above Joda-Time example.
I think using SimpleDateFormat is a bad idea. Use Calendar for comparison directly, like this
cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH) && cal1.get(Calendar.DAY_OF_MONTH) == cal2.get(Calendar.DAY_OF_MONTH)

Java - Check whether two Dates are Equal

I am trying to compare dates in two different formats:
Tue Jul 01 00:12:14 EST 2014
which is created using the function:
private Date getDate (int day, int month, int year){
Calendar calendar = Calendar.getInstance();
calendar.setLenient(false);
calendar.set(year, month-1, day);
Date date = calendar.getTime();
return date;
}
and
2014-07-01
After comparing these two dates, I would like the output to show that they are equal. However I BELIEVE, because of the timestamp in the 1st Date, they are not being determined as equal.
Is my assumption correct?
If so, is there a way that I could convert the first date into the second? The second Date is being retrieved from an SQL database where the variable is DATE.
Thank you for your help.
It sounds like you are comparing a java.util.Date (an instant in time) with a java.sql.Date (an instant in time whose time of day is midnight).
Arithmetic rounding must deal with the local timezones, making it more complex than you might first think.
The simplest way to compare the two would be to use a data formatter and compare the output:
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
if (f.format(date1).equals(f.format(date2))) {
// the two dates are on the same "day"
}
java.sql.Date Has Zero Time
The documentation explains that a java.sql.Date has its time portion set to zero (UTC), meaning midnight.
So when comparing to a java.util.Date with a non-zero time-of-day, the two will not be equal.
LocalDate
So much easier using Joda-Time of the new java.time package in Java 8. Both offer a LocalDate class that ignores time-of-day.
LocalDate x = new LocalDate( 2014, 5, 6 );
LocalDate y = new LocalDate( 2014, 5, 6 );
boolean same = x.equals( y );
To convert your java.sql.Date to a Joda-Time LocalDate, pass it to the constructor of New LocalDate. You may need to also pass DateTimeZone.UTC to be sure it is not interpreted by your JVM's default time zone.
Is my assumption correct?
Yes, your assumption is correct. Two Date instances are correct if both their getTime() results are the same
from Date.java
public boolean equals(Object obj) {
return obj instanceof Date && getTime() == ((Date) obj).getTime();
}
Converting just assumes you need to set the hours,minutes and seconds to 0:
calendar.set(Calendar.HOUR_OF_DAY,0);
calendar.set(Calendar.MINUTE,0);
calendar.set(Calendar.SECOND,0);
Assuming that both dates are in the same timezone and also assuming that the date equality criteria here is the day of the year, I believe you can just compare the date as strings.
To do that, you can use SimpleDateFormat to ensure both are in the same format.
I would suggest you convert both of them to one particular format and compare them using a Comparator.
If you need to check whether two dates are equal, the best way is to use compareTo method.
if(yesterday.compareTo(today) == 0) {
System.out.println("Given dates are same");
} else {
System.out.println("Given dates are different ");
}
Read more: https://www.java67.com/2016/09/how-to-compare-two-dates-in-java.html#ixzz6uH5r1xE2

Get integer value of the current year in Java

I need to determine the current year in Java as an integer. I could just use java.util.Date(), but it is deprecated.
For Java 8 onwards:
int year = Year.now().getValue();
For older version of Java:
int year = Calendar.getInstance().get(Calendar.YEAR);
Using Java 8's time API (assuming you are happy to get the year in your system's default time zone), you could use the Year::now method:
int year = Year.now().getValue();
This simplest (using Calendar, sorry) is:
int year = Calendar.getInstance().get(Calendar.YEAR);
There is also the new Date and Time API JSR, as well as Joda Time
You can also use 2 methods from java.time.YearMonth( Since Java 8 ):
import java.time.YearMonth;
...
int year = YearMonth.now().getYear();
int month = YearMonth.now().getMonthValue();
tl;dr
ZonedDateTime.now( ZoneId.of( "Africa/Casablanca" ) )
.getYear()
Time Zone
The answer by Raffi Khatchadourian wisely shows how to use the new java.time package in Java 8. But that answer fails to address the critical issue of time zone in determining a date.
int year = LocalDate.now().getYear();
That code depends on the JVM's current default time zone. The default zone is used in determining what today’s date is. Remember, for example, that in the moment after midnight in Paris the date in Montréal is still 'yesterday'.
So your results may vary by what machine it runs on, a user/admin changing the host OS time zone, or any Java code at any moment changing the JVM's current default. Better to specify the time zone.
By the way, always use proper time zone names as defined by the IANA. Never use the 3-4 letter codes that are neither standardized nor unique.
java.time
Example in java.time of Java 8.
int year = ZonedDateTime.now( ZoneId.of( "Africa/Casablanca" ) ).getYear() ;
Joda-Time
Some idea as above, but using the Joda-Time 2.7 library.
int year = DateTime.now( DateTimeZone.forID( "Africa/Casablanca" ) ).getYear() ;
Incrementing/Decrementing Year
If your goal is to jump a year at a time, no need to extract the year number. Both Joda-Time and java.time have methods for adding/subtracting a year at a time. And those methods are smart, handling Daylight Saving Time and other anomalies.
Example in java.time.
ZonedDateTime zdt =
ZonedDateTime
.now( ZoneId.of( "Africa/Casablanca" ) )
.minusYears( 1 )
;
Example in Joda-Time 2.7.
DateTime oneYearAgo = DateTime.now( DateTimeZone.forID( "Africa/Casablanca" ) ).minusYears( 1 ) ;
The easiest way is to get the year from Calendar.
// year is stored as a static member
int year = Calendar.getInstance().get(Calendar.YEAR);
If you want the year of any date object, I used the following method:
public static int getYearFromDate(Date date) {
int result = -1;
if (date != null) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
result = cal.get(Calendar.YEAR);
}
return result;
}
Use the following code for java 8 :
LocalDate localDate = LocalDate.now();
int year = localDate.getYear();
int month = localDate.getMonthValue();
int date = localDate.getDayOfMonth();
You can also use Java 8's LocalDate:
import java.time.LocalDate;
//...
int year = LocalDate.now().getYear();
If your application is making heavy use of Date and Calendar objects, you really should use Joda Time, because java.util.Date is mutable. java.util.Calendar has performance problems when its fields get updated, and is clunky for datetime arithmetic.
As some people answered above:
If you want to use the variable later, better use:
int year;
year = Calendar.getInstance().get(Calendar.YEAR);
If you need the year for just a condition you better use:
Calendar.getInstance().get(Calendar.YEAR)
For example using it in a do while that checks introduced year is not less than the current year-200 or more than the current year (Could be birth year):
import java.util.Calendar;
import java.util.Scanner;
public static void main (String[] args){
Scanner scannernumber = new Scanner(System.in);
int year;
/*Checks that the year is not higher than the current year, and not less than the current year - 200 years.*/
do{
System.out.print("Year (Between "+((Calendar.getInstance().get(Calendar.YEAR))-200)+" and "+Calendar.getInstance().get(Calendar.YEAR)+") : ");
year = scannernumber.nextInt();
}while(year < ((Calendar.getInstance().get(Calendar.YEAR))-200) || year > Calendar.getInstance().get(Calendar.YEAR));
}
In my case none of the above is worked. So After trying lot of solutions i found below one and it worked for me
import java.util.Scanner;
import java.util.Date;
public class Practice
{
public static void main(String[] args)
{
Date d=new Date();
int year=d.getYear();
int currentYear=year+1900;
System.out.println(currentYear);
}
}
I may add that a simple way to get the current year as an integer is importing
java.time.LocalDate and, then:
import java.time.LocalDate;
int yourVariable = LocalDate.now().getYear()
Hope this helps!
You can do the whole thing using Integer math without needing to instantiate a calendar:
return (System.currentTimeMillis()/1000/3600/24/365.25 +1970);
May be off for an hour or two at new year but I don't get the impression that is an issue?
In Java version 8+ can (advised to) use java.time library. ISO 8601 sets standard way to write dates: YYYY-MM-DD and java.time.Instant uses it, so (for UTC):
import java.time.Instant;
int myYear = Integer.parseInt(Instant.now().toString().substring(0,4));
P.S. just in case (and shorted for getting String, not int), using Calendar looks better and can be made zone-aware.
I use special functions in my library to work with days/month/year ints -
int[] int_dmy( long timestamp ) // remember month is [0..11] !!!
{
Calendar cal = new GregorianCalendar(); cal.setTimeInMillis( timestamp );
return new int[] {
cal.get( Calendar.DATE ), cal.get( Calendar.MONTH ), cal.get( Calendar.YEAR )
};
};
int[] int_dmy( Date d ) {
...
}

Categories

Resources