Compare if two dates are within same week in android - java

I have two dates.Got them from something like......
Calendar c=Calendar.getInstance();
year=c.get(c.YEAR);
month=c.get(c.MONTH);
month++;
date=c.get(c.DATE);
and other date is broken into date2,month2
Now I want to see if both of them are in the same week.
It's possible through lots of calculation and logic.Problem occurs when 1st date is suppose 03 March and 2nd date is 28Feb. Both of them are in same week but difficult to compare/check that. So I want to know if there is any built in function or any way to compare them easily.Please help..........

use something like this:
Calendar c = Calendar.getInstance();
Integer year1 = c.get(c.YEAR);
Integer week1 = c.get(c.WEEK_OF_YEAR);
Calendar c = Calendar.getInstance();
c.setTimeInMillis(/*Second date in millis here*/);
Integer year2 = c.get(c.YEAR);
Integer week2 = c.get(c.WEEK_OF_YEAR);
if(year1 == year2) {
if(week1 == week2) {
//Do what you want here
}
}
This should do it :D

You can get the week number for your date using c.get(Calendar.WEEK_OF_YEAR) and compare the results for your two dates.
Also accessing constants via instance variables (c.YEAR) is not recommended - access them using classes (Calendar.YEAR).

Just posting a slightly modified solution based on #FabianCook and as pointed out by #harshal his solution doesn't cater for two dates on different years but in the same week.
The modification is to actually set the DAY_OF_WEEK in both Calendar dates to point to Monday.....in this case both dates will be set to the same day even if they are in different years and then we can compare them.
Calendar cal1 = Calendar.getInstance();
cal1.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
int year1 = cal1.get(Calendar.YEAR);
int week1 = cal1.get(Calendar.WEEK_OF_YEAR);
Calendar cal2 = Calendar.getInstance();
cal2.setTimeInMillis(/*Second date in millis here*/);
cal2.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
int year2 = cal2.get(Calendar.YEAR);
int week2 = cal2.get(Calendar.WEEK_OF_YEAR);
if(year1 == year2 && week1 == week2){
//Do what you want here
}

Use java.time
You can get it available the following ways:
Java 8+ and Android API 26+: directly available
Java 6 and 7: ThreeTenBP
Android 25 and lower: ThreeTenABP
It is not recommended to use java.util.Calendar and java.util.Date anymore.
How to find out if two given dates are in the same calendar week?
Using plain java.time:
public boolean inSameCalendarWeek(LocalDate firstDate, LocalDate secondDate) {
// get a reference to the system of calendar weeks in your defaul locale
WeekFields weekFields = WeekFields.of(Locale.getDefault());
// find out the calendar week for each of the dates
int firstDatesCalendarWeek = firstDate.get(weekFields.weekOfWeekBasedYear());
int secondDatesCalendarWeek = secondDate.get(weekFields.weekOfWeekBasedYear());
/*
* find out the week based year, too,
* two dates might be both in a calendar week number 1 for example,
* but in different years
*/
int firstWeekBasedYear = firstDate.get(weekFields.weekBasedYear());
int secondWeekBasedYear = secondDate.get(weekFields.weekBasedYear());
// return if they are equal or not
return firstDatesCalendarWeek == secondDatesCalendarWeek
&& firstWeekBasedYear == secondWeekBasedYear;
}
You can do that with simple int values, too:
public static boolean inSameCalendarWeek(int firstYear, int firstMonth, int firstDayOfMonth,
int secondYear, int secondMonth, int secondDayOfMonth) {
// create LocalDates using the integers provided
LocalDate firstDate = LocalDate.of(firstYear, firstMonth, firstDayOfMonth);
LocalDate secondDate = LocalDate.of(secondYear, secondMonth, secondDayOfMonth);
// get a reference to the system of calendar weeks in your defaul locale
WeekFields weekFields = WeekFields.of(Locale.getDefault());
// find out the calendar week for each of the dates
int firstDatesCalendarWeek = firstDate.get(weekFields.weekOfWeekBasedYear());
int secondDatesCalendarWeek = secondDate.get(weekFields.weekOfWeekBasedYear());
/*
* find out the week based year, too,
* two dates might be both in a calendar week number 1 for example,
* but in different years
*/
int firstWeekBasedYear = firstDate.get(weekFields.weekBasedYear());
int secondWeekBasedYear = secondDate.get(weekFields.weekBasedYear());
// return if they are equal or not
return firstDatesCalendarWeek == secondDatesCalendarWeek
&& firstWeekBasedYear == secondWeekBasedYear;
}
In case you have to extend or use legacy code:
public static boolean inSameCalendarWeek(Calendar firstCalendar, Calendar secondCalendar) {
// create LocalDates from Instants created from the given Calendars
LocalDate firstDate = LocalDate.from(firstCalendar.toInstant());
LocalDate secondDate = LocalDate.from(secondCalendar.toInstant());
// get a reference to the system of calendar weeks in your defaul locale
WeekFields weekFields = WeekFields.of(Locale.getDefault());
// find out the calendar week for each of the dates
int firstDatesCalendarWeek = firstDate.get(weekFields.weekOfWeekBasedYear());
int secondDatesCalendarWeek = secondDate.get(weekFields.weekOfWeekBasedYear());
/*
* find out the week based year, too,
* two dates might be both in a calendar week number 1 for example,
* but in different years
*/
int firstWeekBasedYear = firstDate.get(weekFields.weekBasedYear());
int secondWeekBasedYear = secondDate.get(weekFields.weekBasedYear());
// return if they are equal or not
return firstDatesCalendarWeek == secondDatesCalendarWeek
&& firstWeekBasedYear == secondWeekBasedYear;
}
The output of the following code
public static void main(String[] args) {
// a date from calendar week 1 in the week based year 2020
LocalDate janFirst2020 = LocalDate.of(2020, 1, 1);
// another date from calendar week 1 in the week based year 2020
LocalDate decThirtyFirst2019 = LocalDate.of(2019, 12, 31);
System.out.println(inSameCalendarWeek(janFirst2020, decThirtyFirst2019));
// then a third date from calendar week 1, but this time in the week based year 2021
LocalDate janSeventh2021 = LocalDate.of(2021, 1, 7);
System.out.println(inSameCalendarWeek(janSeventh2021, decThirtyFirst2019));
}
is therefore
true
false
in my locale.

It's a java solution. Following code segment checks if two dates are within same week. It also covers edge cases, where week starts in one calendar year (December) and ends in next year (January).
Note: Code has a dependency on joda-time:
compile 'joda-time:joda-time:2.3'
public static boolean isSameWeek(final Date d1, final Date d2) {
if ((d1 == null) || (d2 == null))
throw new IllegalArgumentException("The date must not be null");
return isSameWeek(new DateTime(d1), new DateTime(d2));
}
public static boolean isSameWeek(final DateTime d1, final DateTime d2) {
if ((d1 == null) || (d2 == null))
throw new IllegalArgumentException("The date must not be null");
// It is important to use week of week year & week year
final int week1 = d1.getWeekOfWeekyear();
final int week2 = d2.getWeekOfWeekyear();
final int year1 = d1.getWeekyear();
final int year2 = d2.getWeekyear();
final int era1 = d1.getEra();
final int era2 = d2.getEra();
// Return true if week, year and era matches
if ((week1 == week2) && (year1 == year2) && (era1 == era2))
return true;
// Return false if none of the conditions are satisfied
return false;
}
Test case:
public class TestDateUtil {
#Test
public void testIsSameWeek() {
final DateTime d1 = new DateTime(2014, 12, 31, 0, 0);
final DateTime d2 = new DateTime(2015, 1, 1, 0, 0);
final DateTime d3 = new DateTime(2015, 1, 2, 0, 0);
final DateTime d4 = new DateTime(2015, 1, 8, 0, 0);
assertTrue(isSameWeek(d1, d2));
assertTrue(isSameWeek(d2, d1));
assertTrue(isSameWeek(d2, d3));
assertTrue(isSameWeek(d3, d2));
assertFalse(isSameWeek(d2, d4));
assertFalse(isSameWeek(d4, d2));
assertFalse(isSameWeek(d1, d4));
assertFalse(isSameWeek(d4, d1));
}
}

I ended up using
date1.with(previousOrSame(MONDAY)).equals(date2.with(previousOrSame(MONDAY)))
assuming that weeks start on Monday.

private int weeksBetween(Calendar startDate, Calendar endDate) {
startDate.set(Calendar.HOUR_OF_DAY, 0);
startDate.set(Calendar.MINUTE, 0);
startDate.set(Calendar.SECOND, 0);
int start = (int)TimeUnit.MILLISECONDS.toDays(
startDate.getTimeInMillis())
- startDate.get(Calendar.DAY_OF_WEEK);
int end = (int)TimeUnit.MILLISECONDS.toDays(
endDate.getTimeInMillis());
return (end - start) / 7;
}
if this method returns 0 they are in the same week
if this method return 1 endDate is the week after startDate
if this method returns -1 endDate is the week before startDate
you get the idea

Let's say, a week starts one year and ends the next year and we pick 2 dates from this week so that they are in different years. Then, the accepted answer yields the wrong result as it checks that the dates are in the SAME YEAR!.
To improve the solution, one could obtain a date corresponding to some day (it could be Monday) of its week and then check that both dates belong to the same day. However, before doing so make sure that both Calendar objects are in the SAME time zone. So, set the time zone of one to another. Also, the solution below works for every API level as it doesn't require the usage of getWeekOfWeekyear() or getWeekYear() (these work with API 24 and higher.
public boolean isSameWeek(Calendar calendar1, Calendar calendar2) {
Calendar calendar2Copy = (Calendar) calendar2.clone();
calendar2Copy.setTimeZone(calendar1.getTimeZone());
calendar1.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
calendar2Copy.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
return calendar1.get(Calendar.YEAR) == calendar2Copy.get(Calendar.YEAR)
&& calendar1.get(Calendar.DAY_OF_YEAR) == calendar2Copy.get(Calendar.DAY_OF_YEAR);
}

this will give true if two dates from same week
fun isEqualWeek(date1: Long, date2: Long):Boolean{
val cal1 = Calendar.getInstance()
val cal2 = Calendar.getInstance()
cal1.time = Date(date1)
cal2.time = Date(date2)
return (cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)) && (cal1.get(Calendar.WEEK_OF_YEAR) == cal2.get(
Calendar.WEEK_OF_YEAR
))
}

Here in Joda's Library I found that the week starts from Monday, but I wanted the week to start from Sunday, so just used the below function :
public static boolean isSameWeek(final Date initDate, final Date finalDate) {
if (initDate != null && finalDate != null) {
Calendar initCalender = Calendar.getInstance();
Calendar finalCalender = Calendar.getInstance();
initCalender.setTime(initDate);
finalCalender.setTime(finalDate);
if (finalCalender.get(Calendar.YEAR) >= initCalender.get(Calendar.YEAR)) {
//check for same year
if (finalCalender.get(Calendar.YEAR) == initCalender.get(Calendar.YEAR)) {
if (finalCalender.get(Calendar.WEEK_OF_YEAR) == initCalender.get(Calendar.WEEK_OF_YEAR)) {
return true;
}
} else //check whether next corresponding year
if (finalCalender.get(Calendar.YEAR) - initCalender.get(Calendar.YEAR) == 1) {
if (initCalender.get(Calendar.WEEK_OF_YEAR) == 1 || initCalender.get(Calendar.WEEK_OF_YEAR) == 53) {
if (finalCalender.get(Calendar.WEEK_OF_YEAR) == 1) {
if (initCalender.get(Calendar.DAY_OF_WEEK) != Calendar.SATURDAY && finalCalender.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
return true;
}
}
}
}
} else {
throw new IllegalArgumentException("Final Date should be greater or equal to Initial Date");
}
} else {
throw new IllegalArgumentException("The date must not be null");
}
return false;
}

Related

Is their any simplified Java to find palindome dates between year 0000 and 9999?

import java.util.Arrays;
public class PalindromeDates {
static final int STARTINGYEAR = 0000;
static final int ENDINGYEAR = 9999;
public static void main(String[] args) {
int year, month, date;
int dateArray[];
boolean flag;
System.out.println(" Date --> Array Format\n");
for (year = STARTINGYEAR; year <= ENDINGYEAR; year++) {
for (month = 01; month <= 12; month++) {
for (date = 1; date <= 31; date++) {
if (checkValidDate(year, date, month)) {
dateArray = createDateArray(date, month, year);
flag = checkPalindrome(dateArray);
if (flag) {
System.out.print(year + "." + month + "." + date + " --> ");
System.out.println(Arrays.toString(dateArray));
}
}
}
}
}
}
public static int[] createDateArray(int date, int month, int year) { //Inserting the whole date to an array
int dateArray[] = new int[8];
dateArray[0] = year / 1000;
year = year % 1000;
dateArray[1] = year / 100;
year = year % 100;
dateArray[2] = year / 10;
dateArray[3] = year % 10;
dateArray[4] = month / 10;
dateArray[5] = month % 10;
dateArray[6] = date / 10;
dateArray[7] = date % 10;
return dateArray;
}
public static boolean checkPalindrome(int dateArray[]) {
for (int i = 0; i <= 3; i++) {
if (dateArray[i] == dateArray[7 - i]) {
} else {
return false;
}
}
return true;
}
public static boolean checkValidDate(int year, int month, int date) {
if (month == 2 && date == 30)
return false;
if ((month == 2 || month == 4 || month == 6 || month == 9 || month == 11) && (date == 31)) {
return false;
}
if ((month == 2) && (date == 29))
return (checkLeapYear(year));
return true;
}
public static boolean checkLeapYear(int year) {
if (year % 4 == 0) {
if (year % 100 == 0) {
if (year % 400 == 0)
return true;
else
return false;
} else
return true;
} else {
return false;
}
}
}
This program is written by me to find the palindrome dates since 0000 to 9999. Is their any simplifies program to do this?. What are the modifications for this code? And I want to know whether my leap year finding code is correct.
There is a method called createDateArray(). It is used to put the integer digits in year, month, date to an array. Is there any simple method to do that?
I am inferring from your code that a palindrome date is a date that formatted into yyyyMMdd format is a palindrome string. For example the day before yesterday, February 2, 2020, was a palindrome date because it’s formatted into 20200202, a palindrome.
Is their any simplifies program to do this? …
Yes there is. See below.
… And I want to know whether my leap year finding code is correct.
Yes, it is correct. I have tested its result against the result of Year.of(y).isLeap() for y ranging from 0 through 9999.
And the issue you didn’t ask about: as jrook hinted in a comment, beware of octal numbers.
static final int STARTINGYEAR = 0000;
While this works in this case, it works for reasons that I am afraid that you don’t fully understand. You will get surprises if some day you try 0500 for year 500 and get 320, or you use 0008 for year 8 and get a compile time error. When a Java integer literal begins with 0 (and has more digits following it), it is an octal number, not a number in the decimal number system. So in your code you should use 0 for the year that you want printed as 0000:
static final int STARTINGYEAR = 0;
java.time
On one side Andreas is correct in the other answer that this goes a lot more smoothly when using the date classes that are built into Java. On the other side the Calendar class used in that answer is poorly designed and long outdated. So I recommend we don’t use it and instead present a solution using java.time, the modern Java date and time API.
List<LocalDate> palindromeDates = Arrays.stream(Month.values())
.flatMap(m -> IntStream.rangeClosed(1, m.length(true)).mapToObj(d -> MonthDay.of(m, d)))
.map(md -> md.atYear(reverseStringToInt(md.format(monthDayFormatter))))
.sorted()
.collect(Collectors.toList());
palindromeDates.forEach(ld -> System.out.println(ld.format(dateFormatter)));
This code uses a few auxiliaries:
private static DateTimeFormatter monthDayFormatter = DateTimeFormatter.ofPattern("MMdd");
private static DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuuMMdd");
private static int reverseStringToInt(String s) {
StringBuilder buf = new StringBuilder(s);
buf.reverse();
return Integer.parseInt(buf.toString());
}
Excerpt from the output:
01011010
01100110
01111110
01200210
…
20111102
20200202
20211202
…
92800829
92900929
The algorithm idea is stolen from Andreas’ answer since it is so well thought.
Link
Oracle tutorial: Date Time explaining how to use java.time.
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("uuuuMMdd");
for (LocalDate d = LocalDate.of(0, 1, 1); d.isBefore(LocalDate.of(10000, 1, 1)); d = d.plusDays(1)) {
String dateString = dateFormatter.format(d);
if (dateString.equals(new StringBuilder(dateString).reverse().toString())) {
System.out.println(d);
}
}
Since the year can be any 4-digit year, there is no constraint there, so just go through all 3661 MMdd values of a year, reverse it and use as the year.
1) Since the leap date of 0229 reversed is 9220, it is a leap year, and hence a valid palindrome date.
As code, using Calendar, in year order:
List<String> palimdromeDates = new ArrayList<>();
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"/*No DST*/));
cal.clear();
cal.set(2000/*Leap Year*/, Calendar.JANUARY, 1);
for (; cal.get(Calendar.YEAR) == 2000; cal.add(Calendar.DAY_OF_YEAR, 1)) {
int day = cal.get(Calendar.DAY_OF_MONTH);
int month = cal.get(Calendar.MONTH) + 1;
int year = 0; // Calculate: year = reverse(MMdd)
for (int i = 0, n = month * 100 + day; i < 4; i++, n /= 10)
year = year * 10 + n % 10;
palimdromeDates.add(String.format("%04d-%02d-%02d", year, month, day));
}
Collections.sort(palimdromeDates); // Sort by year
for (String date : palimdromeDates)
System.out.println(date);
Note that this code only loops 366 times, and does not create any unnecessary String objects or other type of objects, so it is very fast, and generates minimum garbage.
Output
0101-10-10
0110-01-10
0111-11-10
0120-02-10
0121-12-10
0130-03-10
0140-04-10
0150-05-10
0160-06-10
0170-07-10
0180-08-10
0190-09-10
0201-10-20
0210-01-20
0211-11-20
0220-02-20
0221-12-20
0230-03-20
0240-04-20
0250-05-20
0260-06-20
0270-07-20
0280-08-20
0290-09-20
0301-10-30
0310-01-30
0311-11-30
0321-12-30
0330-03-30
0340-04-30
0350-05-30
0360-06-30
0370-07-30
0380-08-30
0390-09-30
1001-10-01
1010-01-01
1011-11-01
1020-02-01
1021-12-01
1030-03-01
1040-04-01
1050-05-01
1060-06-01
1070-07-01
1080-08-01
1090-09-01
1101-10-11
1110-01-11
1111-11-11
1120-02-11
1121-12-11
1130-03-11
1140-04-11
1150-05-11
1160-06-11
1170-07-11
1180-08-11
1190-09-11
1201-10-21
1210-01-21
1211-11-21
1220-02-21
1221-12-21
1230-03-21
1240-04-21
1250-05-21
1260-06-21
1270-07-21
1280-08-21
1290-09-21
1301-10-31
1310-01-31
1321-12-31
1330-03-31
1350-05-31
1370-07-31
1380-08-31
2001-10-02
2010-01-02
2011-11-02
2020-02-02
2021-12-02
2030-03-02
2040-04-02
2050-05-02
2060-06-02
2070-07-02
2080-08-02
2090-09-02
2101-10-12
2110-01-12
2111-11-12
2120-02-12
2121-12-12
2130-03-12
2140-04-12
2150-05-12
2160-06-12
2170-07-12
2180-08-12
2190-09-12
2201-10-22
2210-01-22
2211-11-22
2220-02-22
2221-12-22
2230-03-22
2240-04-22
2250-05-22
2260-06-22
2270-07-22
2280-08-22
2290-09-22
3001-10-03
3010-01-03
3011-11-03
3020-02-03
3021-12-03
3030-03-03
3040-04-03
3050-05-03
3060-06-03
3070-07-03
3080-08-03
3090-09-03
3101-10-13
3110-01-13
3111-11-13
3120-02-13
3121-12-13
3130-03-13
3140-04-13
3150-05-13
3160-06-13
3170-07-13
3180-08-13
3190-09-13
3201-10-23
3210-01-23
3211-11-23
3220-02-23
3221-12-23
3230-03-23
3240-04-23
3250-05-23
3260-06-23
3270-07-23
3280-08-23
3290-09-23
4001-10-04
4010-01-04
4011-11-04
4020-02-04
4021-12-04
4030-03-04
4040-04-04
4050-05-04
4060-06-04
4070-07-04
4080-08-04
4090-09-04
4101-10-14
4110-01-14
4111-11-14
4120-02-14
4121-12-14
4130-03-14
4140-04-14
4150-05-14
4160-06-14
4170-07-14
4180-08-14
4190-09-14
4201-10-24
4210-01-24
4211-11-24
4220-02-24
4221-12-24
4230-03-24
4240-04-24
4250-05-24
4260-06-24
4270-07-24
4280-08-24
4290-09-24
5001-10-05
5010-01-05
5011-11-05
5020-02-05
5021-12-05
5030-03-05
5040-04-05
5050-05-05
5060-06-05
5070-07-05
5080-08-05
5090-09-05
5101-10-15
5110-01-15
5111-11-15
5120-02-15
5121-12-15
5130-03-15
5140-04-15
5150-05-15
5160-06-15
5170-07-15
5180-08-15
5190-09-15
5201-10-25
5210-01-25
5211-11-25
5220-02-25
5221-12-25
5230-03-25
5240-04-25
5250-05-25
5260-06-25
5270-07-25
5280-08-25
5290-09-25
6001-10-06
6010-01-06
6011-11-06
6020-02-06
6021-12-06
6030-03-06
6040-04-06
6050-05-06
6060-06-06
6070-07-06
6080-08-06
6090-09-06
6101-10-16
6110-01-16
6111-11-16
6120-02-16
6121-12-16
6130-03-16
6140-04-16
6150-05-16
6160-06-16
6170-07-16
6180-08-16
6190-09-16
6201-10-26
6210-01-26
6211-11-26
6220-02-26
6221-12-26
6230-03-26
6240-04-26
6250-05-26
6260-06-26
6270-07-26
6280-08-26
6290-09-26
7001-10-07
7010-01-07
7011-11-07
7020-02-07
7021-12-07
7030-03-07
7040-04-07
7050-05-07
7060-06-07
7070-07-07
7080-08-07
7090-09-07
7101-10-17
7110-01-17
7111-11-17
7120-02-17
7121-12-17
7130-03-17
7140-04-17
7150-05-17
7160-06-17
7170-07-17
7180-08-17
7190-09-17
7201-10-27
7210-01-27
7211-11-27
7220-02-27
7221-12-27
7230-03-27
7240-04-27
7250-05-27
7260-06-27
7270-07-27
7280-08-27
7290-09-27
8001-10-08
8010-01-08
8011-11-08
8020-02-08
8021-12-08
8030-03-08
8040-04-08
8050-05-08
8060-06-08
8070-07-08
8080-08-08
8090-09-08
8101-10-18
8110-01-18
8111-11-18
8120-02-18
8121-12-18
8130-03-18
8140-04-18
8150-05-18
8160-06-18
8170-07-18
8180-08-18
8190-09-18
8201-10-28
8210-01-28
8211-11-28
8220-02-28
8221-12-28
8230-03-28
8240-04-28
8250-05-28
8260-06-28
8270-07-28
8280-08-28
8290-09-28
9001-10-09
9010-01-09
9011-11-09
9020-02-09
9021-12-09
9030-03-09
9040-04-09
9050-05-09
9060-06-09
9070-07-09
9080-08-09
9090-09-09
9101-10-19
9110-01-19
9111-11-19
9120-02-19
9121-12-19
9130-03-19
9140-04-19
9150-05-19
9160-06-19
9170-07-19
9180-08-19
9190-09-19
9201-10-29
9210-01-29
9211-11-29
9220-02-29
9221-12-29
9230-03-29
9240-04-29
9250-05-29
9260-06-29
9270-07-29
9280-08-29
9290-09-29

How to compare dates in Java using comparison operators?

How do I compare dates in Java using comparison operators?
Example:
date1 is 30-10-2017
date2 is 31-10-2017
date3 is 30-10-2018
date2 returns false when it should be true that it is less than date3. How can I return true if the date is less than another date and false otherwise?
This is my code:
return (day < theDate.day) || (month < theDate.month) || (year < theDate.year);
Below is my current solution:
{
boolean check = false;
if(year < theDate.year)
{
return true;
}
if(year > theDate.year)
{
return false;
}
if(month < theDate.month)
{
check = true;
}
if(day < theDate.day)
{
check = true;
}
else
{
return false;
}
return check;
}
LocalDate date1 = LocalDate.of(2017, 10, 30); // Year, month, day.
LocalDate date2 = LocalDate.of(2017, 10, 31);
LocalDate date3 = LocalDate.of(2018, 10, 30);
System.out.printf("%s before %s? %s%n", date1, date2, date1.isBefore(date2));
System.out.printf("%s before %s? %s%n", date2, date3, date3.isBefore(date3));
System.out.printf("%s before %s? %s%n", date3, date1, date3.isBefore(date1));
If you want to know how to do a comparison yourself:
Compare first year, then month, then day: from most significant to least
For this reason the ISO standard of denoting dates (and times) is 2017-09-30T13:05:01,000 where a text comparison with a representation of the same length suffices.
And the pattern goes:
if years not equal then result found
if months not equal then result found
result is comparison of days
You can't use relational operators directly, but date/time types typically implement Comparable.
So you should be able to do date1.compareTo(date2) < 0 for logical date1 < date2.
You should use boolean after(Date date) or boolean before(Date date) for that.
For example, date2.before(date3)

Leapday offset - cleaner solution anyone?

I needed to define start/end dates for a person's given age. This seemed simple:
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(dateOfBirth);
cal.add(Calendar.YEAR, years);
Date start = cal.getTime();
cal.add(Calendar.YEAR, 1);
cal.add(Calendar.DAY_OF_MONTH, -1);
Date end = cal.getTime();
Ah, but then there are those born on Leap Day Feb 29th. If the age is not a multiple of 4 then Calendar will round down to the 28th. In this case, my code above will give a date range ending on Feb 27th, and there'll be a gap.
So, I can easily solve this by checking for this condition, and I can wrap the fix up in some method to avoid duplicating it everywhere. But I'm wondering, is there a better solution I'm not aware of? Something that automatically accounts for this special case for a "day before/after" problem?
Here's my solution:
public static Date getAgeStartEnd(Date d, int age, boolean end) {
if (d == null) return null;
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(d);
int baseDay = cal.get(Calendar.DAY_OF_MONTH);
cal.add(Calendar.YEAR, age + (end ? 1 : 0));
int newDay = cal.get(Calendar.DAY_OF_MONTH);
boolean roundedDown = baseDay != newDay;
if (end && !roundedDown)
cal.add(Calendar.DAY_OF_MONTH, -1);
else if (!end && roundedDown)
cal.add(Calendar.DAY_OF_MONTH, 1);
d = cal.getTime();
return d;
}
Date start = getAgeStartEnd(dateOfBirth, years, false);
Date end = getAgeStartEnd(dateOfBirth, years, true);

Best way to find and return a String of next day's date? [duplicate]

This question already has answers here:
How can I increment a date by one day in Java?
(32 answers)
Closed 7 years ago.
I used a basic technique to implement a method that finds the date of the next day based on the given parameter in the format YYYY-MM-DD and returns the next day in the same format.
Can you please take a look at the code and tell me if it is inefficient or not? It works perfectly fine, but I would prefer to implement a method with more efficiency and fewer lines of code if possible. Keep in mind that any values of the month or day that are single digits numbers have to be formatted with a 0 in the tens place.
public String nextDate(String date){ //ex: 2016-01-31 -returns-> 2016-02-01
int MMrange = 30;
String result = "";
String daystr = date.substring(8,10);
String monthstr = date.substring(5,7);
int day = Integer.parseInt(daystr);
int month = Integer.parseInt(monthstr);
int year = Integer.parseInt(date.substring(0,4));
if(month==1||month==3||month==5||month==7||month==8||month==10||month==12) MMrange = 31;
else if(month==2) MMrange = 28;
if(year%4==0&&month==2) MMrange = 29;
if(day==MMrange){
day =1;
month++;
}else if(month==12&&day==31){
year++;
month = 1;
day = 1;
}else{
day++;
}
result = Integer.toString(year)+"-"+Integer.toString(month)+"-"+Integer.toString(day);
if(month <=9&&day<=9) result = Integer.toString(year)+"-0"+Integer.toString(month)+"-0"+Integer.toString(day);
else if(month <= 9) result = Integer.toString(year)+"-0"+Integer.toString(month)+"-"+Integer.toString(day);
else if(day <= 9) result = Integer.toString(year)+"-"+Integer.toString(month)+"-0"+Integer.toString(day);
return result;
}
Try this...
Updated
// imports...
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public static String getNextdt(String dt) {
try {
final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
final Date date = format.parse(dt);
final Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(Calendar.DAY_OF_YEAR, 1);
System.out.println(format.format(calendar.getTime()));
return format.format(calendar.getTime());
} catch (Exception e) {
}
}
You should use a java.text.DateFormat for format and a java.util.Calendar for calculation like
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DAY_OF_MONTH, 1);
return df.format(cal.getTime());
A shorter way, provided that you use Java 8 is:
LocalDate localDate = LocalDate.now();
localDate.plusDays(1);
System.out.println(localDate.toString());
Hope this works for you.

How can I determine if a date is between two dates in Java? [duplicate]

This question already has answers here:
How do I check if a date is within a certain range?
(17 answers)
Closed 7 years ago.
How can I check if a date is between two other dates, in the case where all three dates are represented by instances of java.util.Date?
This might be a bit more readable:
Date min, max; // assume these are set to something
Date d; // the date in question
return d.after(min) && d.before(max);
If you don't know the order of the min/max values
Date a, b; // assume these are set to something
Date d; // the date in question
return a.compareTo(d) * d.compareTo(b) > 0;
If you want the range to be inclusive
return a.compareTo(d) * d.compareTo(b) >= 0;
You can treat null as unconstrained with
if (a == null) {
return b == null || d.compareTo(b) < 0;
} else if (b == null) {
return a.compareTo(d) < 0;
} else {
return a.compareTo(d) * d.compareTo(b) > 0;
}
Like so:
Date min, max; // assume these are set to something
Date d; // the date in question
return d.compareTo(min) >= 0 && d.compareTo(max) <= 0;
You can use > instead of >= and < instead of <= to exclude the endpoints from the sense of "between."
Between dates Including end points can be written as
public static boolean isDateInBetweenIncludingEndPoints(final Date min, final Date max, final Date date){
return !(date.before(min) || date.after(max));
}
NB: as #Ponmudi pointed out in the comments, this solution may not work if the dates are different at miilliseconds level.
Here's a couple ways to do this using the Joda-Time 2.3 library.
One way is to use the simple isBefore and isAfter methods on DateTime instances. By the way, DateTime in Joda-Time is similar in concept to a java.util.Date (a moment in time on the timeline of the Universe) but includes a time zone.
Another way is to build an Interval in Joda-Time. The contains method tests if a given DateTime occurs within the span of time covered by the Interval. The beginning of the Interval is inclusive, but the endpoint is exclusive. This approach is known as "Half-Open", symbolically [).
See both ways in the following code example.
Convert the java.util.Date instances to Joda-Time DateTime instances. Simply pass the Date instance to constructor of DateTime. In practice you should also pass a specific DateTimeZone object rather than rely on JVM’s default time zone.
DateTime dateTime1 = new DateTime( new java.util.Date() ).minusWeeks( 1 );
DateTime dateTime2 = new DateTime( new java.util.Date() );
DateTime dateTime3 = new DateTime( new java.util.Date() ).plusWeeks( 1 );
Compare by testing for before/after…
boolean is1After2 = dateTime1.isAfter( dateTime2 );
boolean is2Before3 = dateTime2.isBefore( dateTime3 );
boolean is2Between1And3 = ( ( dateTime2.isAfter( dateTime1 ) ) && ( dateTime2.isBefore( dateTime3 ) ) );
Using the Interval approach instead of isAfter/isBefore…
Interval interval = new Interval( dateTime1, dateTime3 );
boolean intervalContainsDateTime2 = interval.contains( dateTime2 );
Dump to console…
System.out.println( "DateTimes: " + dateTime1 + " " + dateTime1 + " " + dateTime1 );
System.out.println( "is1After2 " + is1After2 );
System.out.println( "is2Before3 " + is2Before3 );
System.out.println( "is2Between1And3 " + is2Between1And3 );
System.out.println( "intervalContainsDateTime2 " + intervalContainsDateTime2 );
When run…
DateTimes: 2014-01-22T20:26:14.955-08:00 2014-01-22T20:26:14.955-08:00 2014-01-22T20:26:14.955-08:00
is1After2 false
is2Before3 true
is2Between1And3 true
intervalContainsDateTime2 true
Another option
min.getTime() <= d.getTime() && d.getTime() <= max.getTime()
Here you go:
public static void main(String[] args) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
String oeStartDateStr = "04/01/";
String oeEndDateStr = "11/14/";
Calendar cal = Calendar.getInstance();
Integer year = cal.get(Calendar.YEAR);
oeStartDateStr = oeStartDateStr.concat(year.toString());
oeEndDateStr = oeEndDateStr.concat(year.toString());
Date startDate = sdf.parse(oeStartDateStr);
Date endDate = sdf.parse(oeEndDateStr);
Date d = new Date();
String currDt = sdf.format(d);
if((d.after(startDate) && (d.before(endDate))) || (currDt.equals(sdf.format(startDate)) ||currDt.equals(sdf.format(endDate)))){
System.out.println("Date is between 1st april to 14th nov...");
}
else{
System.out.println("Date is not between 1st april to 14th nov...");
}
}
You might want to take a look at Joda Time which is a really good API for dealing with date/time. Even though if you don't really need it for the solution to your current question it is bound to save you pain in the future.
import java.util.Date;
public class IsDateBetween {
public static void main (String[] args) {
IsDateBetween idb=new IsDateBetween("12/05/2010"); // passing your Date
}
public IsDateBetween(String dd) {
long from=Date.parse("01/01/2000"); // From some date
long to=Date.parse("12/12/2010"); // To Some Date
long check=Date.parse(dd);
int x=0;
if((check-from)>0 && (to-check)>0)
{
x=1;
}
System.out.println ("From Date is greater Than ToDate : "+x);
}
}
you can use getTime() and compare the returned long UTC values.
EDIT if you are sure you'll not have to deal with dates before 1970, not sure how it will behave in that case.
Here's how to find whether today is between 2 months:
private boolean isTodayBetween(int from, int to) {
if (from < 0 || to < 0 || from > Calendar.DECEMBER || to > Calendar.DECEMBER) {
throw new IllegalArgumentException("Invalid month provided: from = " + from + " to = " + to);
}
Date now = new Date();
GregorianCalendar cal = new GregorianCalendar();
cal.setTime(now);
int thisMonth = cal.get(Calendar.MONTH);
if (from > to) {
to = to + Calendar.DECEMBER;
thisMonth = thisMonth + Calendar.DECEMBER;
}
if (thisMonth >= from && thisMonth <= to) {
return true;
}
return false;
}
and call it like:
isTodayBetween(Calendar.OCTOBER, Calendar.MARCH)

Categories