Java find weekdays for a given date - java

i need to find weekdays for a given date.
The given date is = 2080-03-20
Now i need to find a weekday after 5 days from the given date.
It should return:
2080-03-25
I tried this:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util;
Date date=new Date();
Calendar calendar = Calendar.getInstance();
date = calendar.getTime()
SimpleDateFormat s
s= new SimpleDateFormat("yyyy-MM-dd")
Date today = new Date();
SimpleDateFormat formatedDate = new SimpleDateFormat ("yyyy-MM-dd")
Calendar c = Calendar.getInstance();
c.add(Calendar.DATE, 21916);
String after60years = (String)(formattedDate.format(c.getTime()))
int days = 5;
for (int i=0;i<days;)
{
calendar.add(Calendar.DAY_OF_MONTH, 1)
if(calendar.get(Calendar.DAY_OF_WEEK)<-5)
{
i++;
}
}
date = calendar.getTime();
s=new SimpleDateFormat("yyyy=MM-dd");
System.println(s.format(date+21916));
It returns:
2080-03-19
2080-03-26
Is this solution is correct ?
Will it return always weekday after 5 days from the given date.
Any help, thank you

tl;dr
LocalDate
.now(
ZoneId.of( "America/Montreal" )
)
.plusDays( 5 )
.with(
org.threeten.extra.Temporals.nextWorkingDayOrSame()
)
java.time
You are using terrible date-time classes that were supplanted years ago by the modern java.time classes defined in JSR 310.
TemporalAdjuster
Apparently you want to move a certain number of days into the future, but not counting weekend days of Saturday and Sunday.
In java.time, we move to another date by way of a TemporalAdjuster.
ThreeTen-Extra
Your could write your own adjuster for skipping the weekend.
nextWorkingDay
But no need, we have an implementation available to us in the ThreeTen-Extra library: org.threeten.extra.Temporals.nextWorkingDay
TemporalAdjuster ta = org.threeten.extra.Temporals.nextWorkingDay() ;
Use that adjuster in a loop for your count of days.
LocalDate today = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ) ;
LocalDate date = today ;
int daysAhead = 5 ;
List< LocalDate > dates = new ArrayList<>( daysAhead ) ;
for( int i = 1 ; i <= daysAhead ; i ++ )
{
date = date.with( ta ) ;
dates.add( date ) ;
}
nextWorkingDayOrSame
If by your Question you meant skip five days later, then determine if that date is a weekday, if not move to the next weekday, then we use the temporal adjuster nextWorkingDayOrSame.
LocalDate today = LocalDate.now( ZoneId.of( "Asia/Tokyo" ) ) ;
int daysAhead = 5 ;
LocalDate later = today.plusDays( daysAhead ) ;
LocalDate date = later.with( org.threeten.extra.Temporals.nextWorkingDayOrSame() ) ;

Using java.time:
public LocalDate weekdayAfter5Days(LocalDate date) {
var target = date.plusDays(5);
var weekday = target.getDayOfWeek();
if (weekday == DayOfWeek.SATURDAY || weekday == DayOfWeek.SUNDAY) {
var nextMonday = TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY);
target = target.with(nextMonday);
}
return target;
}
If date is given as a string with format yyyy-MM-dd just create a LocalDate:
var date = LocalDate.parse(text);
or, for a different format (e.g. dd/MM/yyyy):
var date = LocalDate.parse(text, DateTimeFormatter.ofPattern("dd/MM/yyyy"));

Java8 provides java.time library with rich features. You may try the following sample code.
public class TimeTest {
private static TemporalAdjuster TEMPORAL_ADJUSTER = TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY);
private static List<DayOfWeek> OFF_DAYS = Arrays.asList(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY);
public static void main(String[] args) {
LocalDate localDate = LocalDate.parse("2080-03-20");
long daysToPlus = 5l;
for (int day = 1; day <= daysToPlus; day++) {
localDate = localDate.plusDays(1);
if (OFF_DAYS.contains(localDate.getDayOfWeek())) {
localDate = localDate.with(TEMPORAL_ADJUSTER);
}
}
System.out.println(localDate);
System.out.println(localDate.getDayOfWeek());
}
}

Related

how to compare date without time using calendar in java?

I want to compare two date type only date not time.
date1 = 2022.10.10 16:30:40
date2 = 2022.10.10 13:30:40
these dates are same date so I want to return true.
below is my code. is there clean code?
public Boolean a0160(HashMap<String, Object> params){
Date accessRecord;
Date now = new Date();
accessRecord = userMapper.a0170(params);
Calendar calAccessRecord = Calendar.getInstance();
Calendar calOneHourBefore = Calendar.getInstance();
calAccessRecord.setTime(accessRecord);
calOneHourBefore.setTime(now);
calOneHourBefore.add(Calendar.HOUR, -1);
int calOneHourBeforeYear = calOneHourBefore.get(Calendar.YEAR);
int calOneHourBeforeMonth = calOneHourBefore.get(Calendar.MONTH);
int calOneHourBeforeDate = calOneHourBefore.get(Calendar.DATE);
int calAccessRecordYear = calAccessRecord.get(Calendar.YEAR);
int calAccessRecordMonth = calAccessRecord.get(Calendar.MONTH);
int calAccessRecordDate = calAccessRecord.get(Calendar.DATE);
if(calOneHourBeforeYear == calAccessRecordYear && calAccessRecordMonth == calOneHourBeforeMonth && calAccessRecordDate == calOneHourBeforeDate){
return true;
} else {
return false;
}
}
tl;dr
myJavaUtilDate
.toInstant()
.atZone(
ZoneId.of( "Pacific/Auckland" )
)
.toLocalDate()
.isEqual(
ZonedDateTime
.now( ZoneId.of( "Pacific/Auckland" ) )
.minusHours( 1 )
.toLocalDate()
)
java.time
You are using terrible date-time classes that were years ago supplanted by the modern java.time classes defined in JSR 310.
Apparently you are handed a java.util.Date object. The first thing to do is convert from the flawed legacy to its modern replacement, java.time.Instant. Use new conversion methods added to the old classes.
Instant instant = myJavaUtilDate.toInstant() ;
Both the legacy and modern classes represent a moment as seen with an offset from UTC of zero hours-minutes-seconds.
Understand that for any given moment, the date varies around the globe by time zone. So determining a date requires the context of a time zone.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Extract the date portion.
LocalDate ld = zdt.toLocalDate() ;
Apparently you want to compare that to the current date as of one hour ago.
LocalDate dateAnHourAgo = ZonedDateTime.now( z ).minusHours( 1 ).toLocalDate() ;
Compare with isEqual, isBefore, and isAfter methods.
They aren't dates; they're strings:
return date2.startsWith(date1.substring(0, 10));

Java - how do I take date as input and be able to add/subtract its days/months/years

I'm currently using this code and I don't know if there is a way to add or subtract the date that I input with Scanner(System.in)
Scanner scanner = new Scanner(System.in);
System.out.println("Date: ");
String date = scanner.next();
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
Date date2=null;
try {
date2 = dateFormat.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
java.time
Never use the legacy classes Date and SimpleDateFormat. Use only java.time classes.
DateTimeFormatter f = DateTimeFormatter.ofPattern( "MM/dd/uuuu" ) ;
LocalDate ld = LocalDate.parse( input , f ) ;
To add and subtract, call the plus… and minus… methods.
LocalDate later = ld.plusDays( 3 ) ;
LocalDate earlier = ld.minusYears( 7 ) ;
You can convert Date to LocalDate. Its has plus methods, like plusYears(),plusMonths(),plusDays().
// Date -> LocalDate
private static LocalDate of(Date date) {
Instant instant = date.toInstant();
return instant.atZone(ZoneId.systemDefault()).toLocalDate();
}
// LocalDate -> Date
private static Date of(LocalDate localDate) {
Instant instant = localDate.atStartOfDay(ZoneId.systemDefault()).toInstant();
return Date.from(instant);
}

How do I compare any date with the current date, without taking the year into account

I want to compare the date with the current date, without taking the year into account, and I want to change the text for each day
Here is my code
TextView textView = (TextView)findViewById(R.id.textView);
String valid_until = "7/3";
String valid_until1 = "8/3";
String valid_until2 = "9/3";
String valid_until3 = "10/3";
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM");
Date strDate = null;
Date strDate1 = null;
Date strDate2 = null;
Date strDate3 = null;
try {
strDate = sdf.parse(valid_until);
strDate1 = sdf.parse(valid_until1);
strDate2 = sdf.parse(valid_until2);
strDate3 = sdf.parse(valid_until3);
} catch (ParseException e) {
e.printStackTrace();
}
if (new Date() == (strDate)) {
textView.setText("7 m");
}
if (new Date() == (strDate1)) {
textView.setText("8 m");
}
if (new Date() == (strDate2)) {
textView.setText("9 m");
}
if (new Date() == (strDate3)) {
textView.setText("10 m");
}
How do I compare any date with the current date, without taking the year into account
One option, you could use a Calendar object. Set the date on each, and then simply compare the "DAY_OF_YEAR" value.
https://developer.android.com/reference/java/util/Calendar.html#DAY_OF_YEAR
tl;dr
MonthDay.now( ZoneId.of( "America/Montreal" ) )
.equals( MonthDay.of( Month.JULY , 3 ) )
Details
See my Answer on a duplicate question for details. Briefly recapped here…
Avoid the troublesome old legacy classes Date & SimpleDateFormat like the plague. They have been supplanted by the java.time classes. Much of java.time has been back-ported to Android in the ThreeTenABP project.
Do not capture the current date repeatedly. If your code were to run over midnight, you would get inconsistent results as the date changed.
The java.time.MonthDay class solves your problem, along with LocalDate and ZoneId.
ZoneId z = ZoneId.of( "America/Montreal" ); // Zone in which you want the current date.
LocalDate today = LocalDate.now( z ); // Current date for your zone.
MonthDay mdCurrent = MonthDay.of( today );
MonthDay mdJulyThird = MonthDay.of( Month.JULY , 3 );
if( mdCurrent.equals( mdJulyThird) ) { … }
To address your specific problem, I would make a collection of Month enum objects and loop. Search Stack Overflow for much more info on EnumSet.
EnumSet<Month> months = EnumSet.range( Month.JULY , Month.OCTOBER );
for ( Month month : months ) {
MonthDay md = MonthDay.of( month , 3 ) ;
if( md.equals( mdCurrent ) {
…
break; // Break out of the 'for' loop. No need to continue looping.
}
}
For generating strings, call MonthDay::format and pass a DateTimeFormatter object. Search Stack Overflow for much more info on DateTimeFormatter on many hundreds of questions & answers.

Subtract time in date value

I actually have found the last three dates and what I want to do is subtract 5 hours and 45 minutes from each date. How can implement it?
The code I have done so far is:
public static List<Date> getPastThreeDays() {
List<Date> pDates = new ArrayList<Date>();
for (int i = 1; i <= 3; i++) {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, -i);
Date date = cal.getTime();
String pastDate = sdf.format(date);
Date pstThreesDates;
try {
pstThreesDates = sdf.parse(pastDate);
pDates.add(pstThreesDates);
} catch (ParseException e) {
e.printStackTrace();
}
}
return pDates;
}
public static void main(String[] args) throws ParseException {
// for getting past three dates
System.out.println("-----Formatted Past Three Days-----");
List<Date> pastThreeDatesList = getPastThreeDays();
for (Date date : pastThreeDatesList) {
System.out.println("Orignal:" + date);
}
You can use the API DateTime from JodaTime and make something like this:
Date date = new Date();
DateTime dateTime = new DateTime(date);
DateTime newDateTime = dateTime.minusHours(5).minusMinutes(45);
How about stay out of dependencies?
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, -i);
Calendar calLess5_45 = Calendar.getInstance();
calLess5_45.setTimeInMillis(cal.getTimeInMillis() - (1000*60*45) - (1000*60*60*5));
or with Date:
Date initialDate = cal.getTime();
Date dateLess5_45 = new Date(initialDate.getTime() - (1000*60*45) - (1000*60*60*5));
convert the date into milliseconds then substract the 5hr 45min from it as follows:
public static void main(String[] args) {
System.out.println("-----Formatted Past Three Days-----");
List<Date> pastThreeDatesList = getPastThreeDays();
for (Date date : pastThreeDatesList) {
System.out.println("Orignal:"+date);
long mDateMills= date.getTime() - ((5*3600 *1000)+ 45*60*1000); //you convert your date to millisecond then subtract 5h45min( in milliseconds from it)
String mNewDate= millsToDateFormat(mDateMills);
System.out.println("new Date:"+mNewDate);
}
}
public static String millsToDateFormat(long mills) {
Date date = new Date(mills);
DateFormat formatter = new SimpleDateFormat("HH:mm:ss");
String dateFormatted = formatter.format(date);
return dateFormatted;
}
java.time
The troublesome old date-time classes are now legacy, supplanted by the java.time classes.
A time zone is crucial in determining a date and in adding subtracting days. The date, and length of day, varies around the globe by zone.
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdtNow = ZonedDateTime.now( z );
Subtract a day. Accounts for anomalies such as Daylight Saving Time.
ZonedDateTime zdtYesterday = zdtNow.minusDays( 1 );
Subtract a duration of five hours and forty-five minutes.
Duration d = Duration.ofHours( 5 ).plusMinutes( 45 ); // or Duration.parse( "PT5H45M" ) in standard ISO 8601 string format.
ZonedDateTime zdtEarlier = zdtYesterday.minus( d ) ;

How to detect if a date is within this or next week in java?

If I have a date of an event, such as 2011-01-03, how to detect if it is within this or next week in java ? Any sample code ?
Edit :
I thought it was a simple question, it turned out more complex than I thought, what I meat this week is : from this past Sun to this Sat, next week is from next Sun to the Sat after that.
It partly depends on what you mean by "this week" and "next week"... but with Joda Time it's certainly easy to find out whether it's in "today or the next 7 days" as it were:
LocalDate event = getDateFromSomewhere();
LocalDate today = new LocalDate();
LocalDate weekToday = today.plusWeeks(1);
LocalDate fortnightToday = weekToday.plusWeeks(1);
if (today.compareTo(event) <= 0 && event.compareTo(weekToday) < 0)
{
// It's within the next 7 days
}
else if (weekToday.compareTo(event) <= 0 && event.compareTo(fornightToday) < 0)
{
// It's next week
}
EDIT: To get the Sunday to Saturday week, you'd probably want:
LocalDate startOfWeek = new LocalDate().withDayOfWeek(DateTimeConstants.SUNDAY);
then do the same code as the above, but relative to startOfWeek.
How about this :
Calendar c=Calendar.getInstance();
c.set(Calendar.DAY_OF_WEEK,Calendar.SUNDAY);
c.set(Calendar.HOUR_OF_DAY,0);
c.set(Calendar.MINUTE,0);
c.set(Calendar.SECOND,0);
DateFormat df=new SimpleDateFormat("EEE yyyy/MM/dd HH:mm:ss");
System.out.println(df.format(c.getTime())); // This past Sunday [ May include today ]
c.add(Calendar.DATE,7);
System.out.println(df.format(c.getTime())); // Next Sunday
c.add(Calendar.DATE,7);
System.out.println(df.format(c.getTime())); // Sunday after next
The result :
Sun 2010/12/26 00:00:00
Sun 2011/01/02 00:00:00
Sun 2011/01/09 00:00:00
Any day between the first two is this week, anything between the last two is next week.
Although old question - is still relevant. The most upvoted answer here is correct wrt to Joda-time and wrt to JDK8 as well with some syntax changes. Here's one that might help those who are looking around in JDK8 world.
public static boolean isLocalDateInTheSameWeek(LocalDate date1, LocalDate date2) {
LocalDate sundayBeforeDate1 = date1.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY));
LocalDate saturdayAfterDate1 = date1.with(TemporalAdjusters.nextOrSame(DayOfWeek.SATURDAY));
return ((date2.isEqual(sundayBeforeDate1) || date2.isAfter(sundayBeforeDate1))
&& (date2.isEqual(saturdayAfterDate1) || date2.isBefore(saturdayAfterDate1)));
}
Most answers here do not satisfy me. They either use the outdated Calendar-API (excusable in old answers given in times before Java 8, and it is hence not fair to criticize such answers), or they are even partially wrong or unnecessarily complex. For example, the most upvoted answer by Jon Skeet suggests to determine the first day of week by the Joda-expression new LocalDate().withDayOfWeek(DateTimeConstants.SUNDAY). But such code uses the ISO-definition of a week starting on Monday with the consequence that if the current date is not on Sunday the code would produce next Sunday and not previous Sunday as desired by the OP. Joda-Time is incapable of handling non-ISO weeks.
Another minor flaw of other answers is not to care about if the current AND NEXT week contains a given date - as requested by the OP. So here my improved suggestion in modern Java:
LocalDate today = LocalDate.now(); // involves the system time zone and clock of system
LocalDate startOfCurrentWeek =
today.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY));
LocalDate endOfNextWeek =
startOfCurrentWeek.plusDays(13);
LocalDate event = LocalDate.of(2011, 1, 3); // input of example given by OP
boolean matchingResult =
!(event.isBefore(startOfCurrentWeek) || event.isAfter(endOfNextWeek));
Side note: The question has inspired me to add a small enhancement to the class DateInterval in my library Time4J how to determine the current calendar week in a very generic way.
Hint: use Calendar. Create new instance of it for your sample event date. Then, compare WEEK_OF_YEAR for current date, and the date of your event.
for those that has to stick to JDK 7 and can't use joda.time, I wrote this method and tested.
public static boolean inSameWeek(Date date1, Date date2) {
if (null == date1 || null == date2) {
return false;
}
Calendar earlier = Calendar.getInstance();
Calendar later = Calendar.getInstance();
if (date1.before(date2)) {
earlier.setTime(date1);
later.setTime(date2);
} else {
earlier.setTime(date2);
later.setTime(date1);
}
if (inSameYear(date1, date2)) {
int week1 = earlier.get(Calendar.WEEK_OF_YEAR);
int week2 = later.get(Calendar.WEEK_OF_YEAR);
if (week1 == week2) {
return true;
}
} else {
int dayOfWeek = earlier.get(Calendar.DAY_OF_WEEK);
earlier.add(Calendar.DATE, 7 - dayOfWeek);
if (inSameYear(earlier.getTime(), later.getTime())) {
int week1 = earlier.get(Calendar.WEEK_OF_YEAR);
int week2 = later.get(Calendar.WEEK_OF_YEAR);
if (week1 == week2) {
return true;
}
}
}
return false;
}
public static boolean inSameYear(Date date1, Date date2) {
if (null == date1 || null == date2) {
return false;
}
Calendar cal1 = Calendar.getInstance();
cal1.setTime(date1);
int year1 = cal1.get(Calendar.YEAR);
Calendar cal2 = Calendar.getInstance();
cal2.setTime(date2);
int year2 = cal2.get(Calendar.YEAR);
if (year1 == year2)
return true;
return false;
}
You can use the Calendar API to retrieve the week for a given day.
Calendar cal = Calendar.getInstance();
cal.setTime(somedate);
int week = cal.get(Calendar.WEEK_OF_YEAR);
tl;dr
Testing a pair of LocalDate objects by using org.threeten.extra.LocalDateRange class with a TemporalAdjuster named ta that determines the first day of the week.
LocalDateRange.of(
localDate1.with( ta ) ,
localDate1.with( ta ).plusWeeks( 1 )
)
.contains(
localDate2
)
ThreeTen-Extra
The ThreeTen-Extra project adds additional functionality to the java.time classes built into Java (defined by JSR 310).
Among the added classes is LocalDateRange. This class represents a span-of-time attached to the timeline. In other words, a pair of LocalDate objects. This class offers handy methods for comparing, such as overlaps, contains, and abuts. Here we need equals.
Define a method where you pass your two dates plus the first day of the week (a DayOfWeek enum object).
We use a TemporalAdjuster found in the TemporalAdjusters class to determine the date of the first day of the week. Then add a week to get the end of the week (per Half-Open definition of a span-of-time).
We could be cute and check to see if both dates are the same. A worthy check if such a case is likely often in your app.
For week 2, let's use a one-liner as alternative syntax.
public boolean inSameWeek ( LocalDate localDate1 , LocalDate localDate2 , DayOfWeek firstDayOfWeek ) {
Objects.requireNonNull( localDate1 ) ; // … ditto for other arguments.
if( localDate1.isEqual( localDate2 ) ) { return true ; }
TemporalAdjuster ta = TemporalAdjusters.previousOrSame( firstDayOfWeek ) ;
LocalDate weekStart1 = localDate1.with( ta ) ;
LocalDate weekStop1 = weekStart1.plusWeeks( 1 ) ;
LocalDateRange week1 = LocalDateRange.of( weekStart1 , weekStop1 ) ;
LocalDateRange week2 =
LocalDateRange.of(
localDate2.with( ta ) ,
localDate2.with( ta ).plusWeeks( 1 )
)
;
// Compare the weeks.
return week1.equals( week2 ) ;
}
Or even more compact.
public boolean inSameWeek ( LocalDate localDate1 , LocalDate localDate2 , DayOfWeek firstDayOfWeek ) {
Objects.requireNonNull( localDate1 ) ; // … ditto for other arguments.
if( localDate1.isEqual( localDate2 ) ) { return true ; }
TemporalAdjuster ta = TemporalAdjusters.previousOrSame( firstDayOfWeek ) ;
return
LocalDateRange.of(
localDate1.with( ta ) ,
localDate1.with( ta ).plusWeeks( 1 )
)
.equals(
LocalDateRange.of(
localDate2.with( ta ) ,
localDate2.with( ta ).plusWeeks( 1 )
)
)
;
}
We really do not need that second week. We only care if the first determined week contains the second passed date argument.
public boolean inSameWeek ( LocalDate localDate1 , LocalDate localDate2 , DayOfWeek firstDayOfWeek ) {
Objects.requireNonNull( localDate1 ) ; // … ditto for other arguments.
if( localDate1.isEqual( localDate2 ) ) { return true ; }
TemporalAdjuster ta = TemporalAdjusters.previousOrSame( firstDayOfWeek ) ;
return
LocalDateRange.of(
localDate1.with( ta ) ,
localDate1.with( ta ).plusWeeks( 1 )
)
.contains(
localDate2
)
;
}
Use it.
LocalDate localDate = LocalDate.of( 2019 , Month.JANUARY , 23 ) ;
LocalDate today = LocalDate.now( ZoneId.of( "Africa/Tunis") ) ;
boolean sameWeek = this.inSameWeek( localDate , today , DayOfWeek.SUNDAY ) ;
Caveat: I ran none of this code.
This is what worked for me in Java 8
import java.time.LocalDate;
LocalDate today = LocalDate.now();
LocalDate twoWeeksBefore = today.minusWeeks(2);
LocalDate checkDate = someObject.getSomeDate();
if(checkDate.compareTo(twoWeeksBefore) > 0) {
// do something if checkDate is within last two weeks
} else {
// do something if checkDate is on or before last two weeks
}

Categories

Resources