What this code does is print the dates of the current week from Monday to Friday. It works fine, but I want to ask something else: If today is Saturday or Sunday I want it to show the next week. How do I do that?
Here's my working code so far (thanks to StackOverflow!!):
// Get calendar set to current date and time
Calendar c = Calendar.getInstance();
// Set the calendar to monday of the current week
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
// Print dates of the current week starting on Monday to Friday
DateFormat df = new SimpleDateFormat("EEE dd/MM/yyyy");
for (int i = 0; i <= 4; i++) {
System.out.println(df.format(c.getTime()));
c.add(Calendar.DATE, 1);
}
Thanks a lot! I really appreciate it as I've been searching for the solution for hours...
public static void main(String[] args) {
Calendar c = Calendar.getInstance();
// Set the calendar to monday of the current week
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
// Print dates of the current week starting on Monday to Friday
DateFormat df = new SimpleDateFormat("EEE dd/MM/yyyy");
for (int i = 0; i <= 10; i++) {
System.out.println(df.format(c.getTime()));
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK);
if (dayOfWeek == Calendar.FRIDAY) { // If it's Friday so skip to Monday
c.add(Calendar.DATE, 3);
} else if (dayOfWeek == Calendar.SATURDAY) { // If it's Saturday skip to Monday
c.add(Calendar.DATE, 2);
} else {
c.add(Calendar.DATE, 1);
}
// As Cute as a ZuZu pet.
//c.add(Calendar.DATE, dayOfWeek > Calendar.THURSDAY ? (9 - dayOfWeek) : 1);
}
}
Output
Mon 03/01/2011
Tue 04/01/2011
Wed 05/01/2011
Thu 06/01/2011
Fri 07/01/2011
Mon 10/01/2011
Tue 11/01/2011
Wed 12/01/2011
Thu 13/01/2011
Fri 14/01/2011
Mon 17/01/2011
If you want to be cute you can replace the if/then/else with
c.add(Calendar.DATE, dayOfWeek > 5 ? (9 - dayOfWeek) : 1);
but I really wanted something easily understood and readable.
tl;dr
Core code concept:
EnumSet.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY ) // Instantiate a n implementation of `Set` highly optimized in both memory usage and execution speed for collecting enum objects.
.contains( // Ask if our target `DayOfWeek` enum object is in our `Set`.
LocalDate.now( ZoneId.of( "America/Montreal" ) ) // Determine today’s date as seen by the people of a particular region (time zone).
.getDayOfWeek() // Determine the `DayOfWeek` enum constant representing the day-of-week of this date.
)
java.time
The modern way is with the java.time classes.
The DayOfWeek enum provides seven objects, for Monday-Sunday.
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
DayOfWeek dow = today.getDayOfWeek();
Define the weekend as a set of DayOfWeek objects. Note that EnumSet is an especially fast and low-memory implementation of Set designed to hold Enum objects such as DayOfWeek.
Set<DayOfWeek> weekend = EnumSet.of( DayOfWeek.SATURDAY , DayOfWeek.SUNDAY );
Now we can test if today is a weekday or a weekend.
Boolean todayIsWeekend = weekend.contains( dow );
The Question said we want to jump to the start of next week if this is a weekend. To do that, use a TemporalAdjuster which provides for classes that can manipulate date-time objects. In java.time we have immutable objects. This means we produce new instances based on the values within an existing object rather than alter ("mutate") the original. The TemporalAdjusters class (note the plural 's') provides several handy implementations of TemporalAdjuster including next( DayOfWeek ).
DayOfWeek firstDayOfWeek = DayOfWeek.MONDAY ;
LocalDate startOfWeek = null ;
if( todayIsWeekend ) {
startOfWeek = today.with( TemporalAdjusters.next( firstDayOfWeek ) );
} else {
startOfWeek = today.with( TemporalAdjusters.previousOrSame( firstDayOfWeek ) );
}
We soft-code the length of the week in case our definition of weekend ever changes.
LocalDate ld = startOfWeek ;
int countDaysToPrint = ( DayOfWeek.values().length - weekend.size() );
for( int i = 1 ; i <= countDaysToPrint ; i++ ) {
System.out.println( ld );
// Set up the next loop.
ld = ld.plusDays( 1 );
}
See live code in IdeOne.com.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Here is short answer using Java 8, all you need to do is to convert your Calendar instance to LocalDateTime and leverage DayOfWeek enum to check if it's Saturday or Sunday, here you go...
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
DateFormat df = new SimpleDateFormat("EEE dd/MM/yyyy");
for (int i = 0; i <= 20; i++) {
//following line does all magic for you
if(LocalDateTime.ofInstant(c.toInstant(), ZoneId.systemDefault()).getDayOfWeek()!=DayOfWeek.SATURDAY && LocalDateTime.ofInstant(c.toInstant(), ZoneId.systemDefault()).getDayOfWeek()!=DayOfWeek.SUNDAY)
System.out.println(df.format(c.getTime()));
c.add(Calendar.DATE, 1);
}
Related
I have a date in dd/mm (15/07) format, I need to add a single day to this date, so it becomes 16/07.
How can I do this in the easiest way in java?
You can use Calendar.
String dt = "15-07-2016";
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
Calendar c = Calendar.getInstance();
c.setTime(sdf.parse(dt));
c.add(Calendar.DATE, 1); // number of days to add
dt = sdf.format(c.getTime());
You can do this:
public String addDay(String date) {
String[] dateSplit = date.split("/");
String day = "" + (Integer.parseInt(dateSplit[0]) + 1);
return day + "/" + dateSplit[1];
}
But this isn't really a nice solution, because this doesn't handle month or year swaps (This you can add by yourself using the % operator)
Or you use the SimpleDateFormat like here: How can I increment a date by one day in Java?
java.time
The Answer by Goel is correct but outmoded.
The java.time framework is built into Java 8 and later. These classes supplant the old troublesome date-time classes such as java.util.Date, .Calendar, & java.text.SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
MonthDay
The java.time classes include the MonthDay class to represent a month+day without year and without time zone.
String input = "15/07";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "dd/MM" );
MonthDay monthDay = MonthDay.parse( input , formatter );
Cannot increment February 28
As commented by Tom, you cannot reliably increment February 28. In most years you would get March 1 but in leap years you get February 29. This is why the YearMonth class lacks any addDays method.
So you need to (a) assume/supply a year, (b) refuse to increment the one day of February 28, or (c) arbitrarily increment to March 1 from February 28 to ignore any possible 29th.
Let's look at the first option, supplying a year.
To get the current year we need the current date. To get the current date, specify a time zone. For any given moment, the date varies around the globe by zone.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );
int year = today.getYear();
We can apply that year number to change our YearMonth into a LocalDate. From there the LocalDate::plusDays method increments to the next day. From the resulting instance of LocalDate we extract a YearMonth object.
LocalDate ld = monthYear.atYear( year );
LocalDate nextDay = ld.plusDays( 1 );
YearMonth ymNextDay = MonthDay.from( nextDay );
I would like to create a DateHelper class and for that I'm using DateUtils from Apache Commons Lang 2.6.
I'm having problems understanding the result returned when extract field from a date. Here is my test class which extract the day of month after truncate the date :
public class DateTest {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// Date date = createDate(2000, 1, 2, 3, 4, 5, 6);
Calendar calendar = createEmptyUTCCalendar();
calendar.set(Calendar.YEAR, 2000);
calendar.set(Calendar.MONTH, 0); // january
calendar.set(Calendar.DAY_OF_MONTH, 2);
calendar.set(Calendar.HOUR_OF_DAY, 3);
calendar.set(Calendar.MINUTE, 4);
calendar.set(Calendar.SECOND, 5);
calendar.set(Calendar.MILLISECOND, 6);
Date date = calendar.getTime();
System.out.println("Input date\n" + date);
// Truncate from day of month.
Date dateTruncate = getDatePart(date);
System.out.println("Truncate the date\n" + dateTruncate);
System.out.println("\n*** Extract day of month ***");
// Extract the field day of month from the truncated date.
int fieldDayOfMonth = getField(dateTruncate, Calendar.DAY_OF_MONTH);
System.out.println("Expected result is 2\nActual result is " + fieldDayOfMonth);
assert fieldDayOfMonth == 2;
}
public static int getField(Date date, int calendarField) {
Calendar calendar = createEmptyUTCCalendar();
calendar.setTime(date);
int value = calendar.get(calendarField);
if (calendarField == Calendar.MONTH) {
value++;
}
return value;
}
public static Date getDatePart(Date date) {
return DateUtils.truncate(date, Calendar.DAY_OF_MONTH);
}
private static Calendar createEmptyUTCCalendar() {
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
return calendar;
}
}
I expect the result of extracting the field Calendar.DAY_OF_MONTH to be 2 but I got 1.
Input date
Sun Jan 02 04:04:05 CET 2000
Truncate the date
Sun Jan 02 00:00:00 CET 2000
*** Extract day of month ***
Expected result is 2
Actual result is 1
tl;dr
LocalDate.of( 2000 , Month.JANUARY , 2 )
.getDayOfMonth()
2
java.time
You can just use Java now, no need for Apache DateUtils. And truncation is the wrong way to think about it; just interrogate for the day-of-month property.
Specify your date using LocalDate class. Note that java.time uses sane month numbering, 1-12 for January to December.
LocalDate ld = LocalDate.of( 2000 , 1 , 2 ) ; // January 2, 2000.
Or use the Month enum.
LocalDate ld = LocalDate.of( 2000 , Month.JANUARY , 2 ) ; // January 2, 2000.
2000-01-02
Interrogate for day-of-month. You can call getDayOfMonth on a LocalDate, OffsetDateTime, and ZonedDateTime.
int dayOfMonth = ld.getDayOfMonth() ;
2
If receiving a Calendar object, it is likely a GregorianCalendar. If so, you can easily convert to java.time classes.
if( myCalendar instanceOf GregorianCalendar ) {
GregorianCalendar gc = ( GregorianCalendar ) myCalendar ; // Cast.
ZonedDateTime zdt = gc.toZonedDateTime() ; // Convert from legacy class to modern class.
int dayOfMonth = zdt.getDayOfMonth() ;
}
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
It seems that the thing is on the timezones. Your calendar is on UTC and your date on your local zone, if you avoid the line:
calendar.setTimeZone(TimeZone.getTimeZone("UTC"));
the thing should work.
When you pass calendar to Date, the date object gets default time zone CET in your case. Then you truncate and pass again to a UTC calendar, and due to the diffenrence between CET and UTC you day is the previous one.
Been wrestling with this problem for a while, would love some input.
The problem I want to solve collects all of the dates in one specific year which fall on a particular day of the week, for example, every Tuesday in 2014. The dates are stored in an ArrayList<Date>. This list is then returned.
Also have to validate to make sure the year is not 0 and the day of the week submitted must be a number between 1-7.
If there are any issues, I would love to know what I have screwed up.
public List<Date> getDatesforDayOfWeek(int year, int dayOfWeek) throws InvalidDateException, ParseException {
List<Date> dateList = new ArrayList<>();
if (year <= 0 || (1 > dayOfWeek && dayOfWeek > 7)) {
throw new InvalidDateException("Year or day of week is invalid.");
} else {
Calendar newCal = Calendar.getInstance();
newCal.set(YEAR, year);
newCal.set(DAY_OF_YEAR, 1);
while (newCal.get(YEAR) < year + 1) {
int currentDayOfWeek = newCal.get(DAY_OF_WEEK);
Date newDate = null;
if (currentDayOfWeek >= dayOfWeek) {
int dayOfMonth = newCal.get(DAY_OF_MONTH);
String strDayOfMonth = String.valueOf(dayOfMonth);
String strYear = String.valueOf(year);
DateUtility d1 = new DateUtility();
Date passDate = newCal.getTime();
String weekDay = d1.getWeekDayNameAbbreviation(passDate);
String monthAbbreviation = d1.getMonthAbbreviation(passDate);
String finalString = new String();
finalString.concat(weekDay).concat(" ").
concat(monthAbbreviation).concat(" ").
concat(strDayOfMonth).concat(" ").
concat(strYear);
SimpleDateFormat format = new SimpleDateFormat("EEE MMM dd YYYY");
Date theDate = format.parse(finalString);
dateList.add(theDate);
}
newCal.add(Calendar.DATE, 1);
}
}
return (dateList);
}
Your question fails to specify which is first day of the week, but things are further complicated by your method for testing the current day of the week. Let's start with validating days of the week by using the Calendar standard,
private static boolean isValidDayOfWeek(int dayOfWeek) {
switch (dayOfWeek) {
// Seven days of the week.
case Calendar.SUNDAY: case Calendar.MONDAY: case Calendar.TUESDAY:
case Calendar.WEDNESDAY: case Calendar.THURSDAY: case Calendar.FRIDAY:
case Calendar.SATURDAY:
return true;
}
return false;
}
It then follows that we can do something like,
public static List<Date> getDatesforDayOfWeek(int year, int dayOfWeek) {
List<Date> dateList = new ArrayList<>();
if (year <= 0 || !isValidDayOfWeek(dayOfWeek)) {
return null;
} else {
Calendar newCal = Calendar.getInstance();
newCal.set(Calendar.YEAR, year);
newCal.set(Calendar.DAY_OF_YEAR, 1);
// First, let's loop until we're at the correct day of the week.
while (newCal.get(Calendar.DAY_OF_WEEK) != dayOfWeek) {
newCal.add(Calendar.DAY_OF_MONTH, 1);
}
// Now, add the Date to the List. Then add a week and loop (stop
// when the year changes).
do {
dateList.add(newCal.getTime());
newCal.add(Calendar.DAY_OF_MONTH, 7);
} while (newCal.get(Calendar.YEAR) == year);
}
return dateList;
}
Leaving us with main(). So, to get every Tuesday in 2014 you could then use -
public static void main(String[] args) {
List<Date> tuesdays = getDatesforDayOfWeek(2014, Calendar.TUESDAY);
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
for (Date d : tuesdays) {
System.out.println(df.format(d));
}
}
tl;dr
startOfYear // `Year.of( 2019 ).atDay( 1 )` gets the first day of the year.
.datesUntil( startOfYear.plusYears( 1 ) ) // Generate a stream of incrementing `LocalDate` objects.
.filter( // Pull out the dates that are a Tuesday.
t -> t.getDayOfWeek().equals( DayOfWeek.TUESDAY )
)
.collect( Collectors.toList() ) // Return results in a `List` of `LocalDate` objects.
ISO 8601
The ISO 8601 standard for date-time work defines Monday as the first day of week, identified by number 1. Sunday is 7.
Avoid j.u.Date & .Calendar
The java.util.Date and .Calendar classes bundled with java are notoriously troublesome. Avoid them. They have been supplanted in Java 8 by the new java.time package. That package was inspired by Joda-Time, an alternative that remains an active viable project with some advantages.
Both Joda-Time and java.time use ISO 8601 by default.
Date-Only
For this Question, we need only dates, not time-of-day or time zones. Both Joda-Time and java.time offer a LocalDate class for this purpose.
java.time
Use Year.of and LocalDate::plusYears to determine the bounds of a year, yielding a pair of LocalDate objects for each first-day-of-year.
LocalDate startOfYear = Year.of( 2019 ).atDay( 1 ); // Determine first day of the year.
LocalDate startOfFollowingYear = startOfYear.plusYears( 1 );
Loop, incrementing the date one day at a time. If that date happens to be a Tuesday, add it to our collection.
LocalDate localDate = startOfYear;
List < LocalDate > tuesdays = new ArrayList <>( 55 ); // Set initialCapacity to maximum number of tuesdays in a year. Probably 53, but I'll go with 55 for good measure.
while ( localDate.isBefore( startOfFollowingYear ) )
{
if ( localDate.getDayOfWeek().equals( DayOfWeek.TUESDAY ) )
{
tuesdays.add( localDate );
}
// Set up the next loop.
localDate = localDate.plusDays( 1 );
}
System.out.println( tuesdays );
See this code run live at IdeOne.com.
[2019-01-01, 2019-01-08, 2019-01-15, 2019-01-22, 2019-01-29, 2019-02-05, 2019-02-12, 2019-02-19, 2019-02-26, 2019-03-05, 2019-03-12, 2019-03-19, 2019-03-26, 2019-04-02, 2019-04-09, 2019-04-16, 2019-04-23, 2019-04-30, 2019-05-07, 2019-05-14, 2019-05-21, 2019-05-28, 2019-06-04, 2019-06-11, 2019-06-18, 2019-06-25, 2019-07-02, 2019-07-09, 2019-07-16, 2019-07-23, 2019-07-30, 2019-08-06, 2019-08-13, 2019-08-20, 2019-08-27, 2019-09-03, 2019-09-10, 2019-09-17, 2019-09-24, 2019-10-01, 2019-10-08, 2019-10-15, 2019-10-22, 2019-10-29, 2019-11-05, 2019-11-12, 2019-11-19, 2019-11-26, 2019-12-03, 2019-12-10, 2019-12-17, 2019-12-24, 2019-12-31]
Or get fancy with functional lambda syntax. The LocalDate::datesUntil method generates a stream, in Java 9 and later. Then filter the stream by a match on DayOfWeek.TUESDAY.
LocalDate startOfYear = Year.of( 2019 ).atDay( 1 );
Stream < LocalDate > stream = startOfYear.datesUntil( startOfYear.plusYears( 1 ) );
List < LocalDate > tuesdays = stream.filter( t -> t.getDayOfWeek().equals( DayOfWeek.TUESDAY ) ).collect( Collectors.toList() );
Joda-Time
Here is some example code in Joda-Time 2.4 for collecting all the Tuesdays in a year.
int year = 2014;
String input = year + "-01-01";
LocalDate localDateInput = LocalDate.parse( input );
LocalDate firstTuesday = localDateInput.withDayOfWeek ( DateTimeConstants.TUESDAY );
LocalDate tuesday = firstTuesday; // for incrementing by week.
List<LocalDate> list = new ArrayList<>();
while ( tuesday.getYear() == year ) {
list.add( tuesday );
tuesday.plusWeeks( 1 );
}
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
I think your main problem lies in this condition
if (currentDayOfWeek >= dayOfWeek) {
since that will count any day that is "higher" than the day you want. If you pass 3, it will also count any day that is higher than 3, which isn't what you want.
the condition should be
if (currentDayOfWeek == dayOfWeek) {
I also recommend you use Calendar getTime method instead of parsing a String to get your Date.
I am trying to get the date of Monday or Thurday in this format YYYYMMDD
For Monday it should give me this - 20130224 (as an example)
For Thursday it should give me this - 20130227 (as an example)
Now, if I am running my program after Thursday or on Thursday, it should print date for Thursday in this format YYYYMMDD which can be 20130227 (coming thursday in this week).
And If I am running my program after Monday or on Monday, then it should print date for Monday in the same format YYYYMMMDD which can be 20130224 (yesterday Monday date as an example)
How would I do this in Java?
Below is what I have tried -
Calendar cal = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat("EEE");
String text = formatter.format(cal.getTime());
System.out.println(text);
// but how do I check if it is Tuesday but less than Thursday
if(text.equalsIgnoreCase("Tue")) {
// get previous Monday date in YYYYMMDD
}
// and how do I check if it is thursday or greater than Thursday?
else if(text.equalsIgnoreCase("Thur")) {
// get previous Thursday date in YYYYMMDD
}
Update:-
In a particular week, if I am running my program on Thursday or after Thursday then it should return me date for Thursday in the same week in YYYYMMDD format, but if I am running my program on Monday or after Monday, then it should return me date for Monday in the same week in YYYYMMDD format.
For example, In this week, if I am running my program on Thursday or after Thursday, then it should return date for Thursday. But if I am running my program on Monday or Tuesday or Wednesday in this same week, then it should return me date for Monday.
Code:-
Below is my code -
public static void main(String[] args) {
try {
Calendar cal = Calendar.getInstance();
SimpleDateFormat toDateFormat = new SimpleDateFormat("yyyyMMdd");
int dow = cal.get(Calendar.DAY_OF_WEEK);
switch (dow) {
case Calendar.THURSDAY:
case Calendar.FRIDAY:
case Calendar.SATURDAY:
case Calendar.SUNDAY:
while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.THURSDAY) {
cal.add(Calendar.DATE, -1);
}
break;
case Calendar.MONDAY:
case Calendar.TUESDAY:
case Calendar.WEDNESDAY:
while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
cal.add(Calendar.DATE, -1);
}
break;
}
System.out.println(date);
System.out.println(cal.getTime());
System.out.println(toDateFormat.format(cal.getTime()));
} catch (ParseException exp) {
exp.printStackTrace();
}
}
Start by parsing the text value to a Date value...
String dateText = "20130224";
SimpleDateFormat toDateFormat = new SimpleDateFormat("yyyyMMdd");
Date date = toDateFormat.parse(dateText);
This gives you the starting point. Next you need to use a Calendar which will allow you move backwards and forwards, automatically rolling the date internally for you (so if you roll over week, month or year boundaries)
For example...
try {
String dateText = "20130227";
SimpleDateFormat toDateFormat = new SimpleDateFormat("yyyyMMdd");
Date date = toDateFormat.parse(dateText);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int dow = cal.get(Calendar.DAY_OF_WEEK);
switch (dow) {
case Calendar.THURSDAY:
case Calendar.FRIDAY:
case Calendar.SATURDAY:
case Calendar.SUNDAY:
while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.THURSDAY) {
cal.add(Calendar.DATE, -1);
}
break;
case Calendar.MONDAY:
case Calendar.TUESDAY:
case Calendar.WEDNESDAY:
while (cal.get(Calendar.DAY_OF_WEEK) != Calendar.MONDAY) {
cal.add(Calendar.DATE, -1);
}
break;
}
System.out.println(date);
System.out.println(cal.getTime());
} catch (ParseException exp) {
exp.printStackTrace();
}
So, based on this example, it would output...
Wed Feb 27 00:00:00 EST 2013
Mon Feb 25 00:00:00 EST 2013
For 20130224 (which is a Sunday) it will give
Sun Feb 24 00:00:00 EST 2013
Thu Feb 21 00:00:00 EST 2013
I should also add, there's probably a much easier way to do this with JodaTime, but this is what I was able to wipe up quickly. Yes, I know the case statement is little winded, but SUNDAY is equal to 0, which is a little annoying ;)
What? Moving to a new question with the same contents?
String[] weeks = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
DateFormat df = new SimpleDateFormat("yyyyMMdd");
Calendar c = Calendar.getInstance();
c.setTime(new Date()); // Now use today date.
int dayOfWeek = c.get(Calendar.DAY_OF_WEEK); // Sun=1, Mon=2, ... Sat=7
System.out.println("Today " + df.format(c.getTime()) + " is " + weeks[dayOfWeek-1]);
c.add(Calendar.DATE, 7); // Adding 7 days
System.out.println("Next " + weeks[dayOfWeek-1] + " is " + df.format(c.getTime()));
// Should display:
// Today 20140225 is Tuesday
// Next Tuesday is 20140304
I would use the calendar class day to get the day of the week. Calendar.DAY_OF_WEEK function returns 1 - 7 for Sunday - Saturday. This way you can do numeric comparison and not mess around with comparing the strings for the weekdays (which would be a mess if your app needs to support multiple languages).
See:
http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html
If I understood what you're after, then this should work
private static final java.text.SimpleDateFormat sdf =
new java.text.SimpleDateFormat("yyyyMMdd");
public static String calculateCorrectDate(
java.util.Date d) {
java.util.Calendar cal = java.util.Calendar
.getInstance();
cal.setTime(d);
int dayOfWeek = cal
.get(java.util.Calendar.DAY_OF_WEEK);
if (dayOfWeek >= java.util.Calendar.MONDAY
&& dayOfWeek < java.util.Calendar.THURSDAY) {
cal.set(java.util.Calendar.DAY_OF_WEEK,
java.util.Calendar.MONDAY);
} else {
cal.set(java.util.Calendar.DAY_OF_WEEK,
java.util.Calendar.THURSDAY);
}
return sdf.format(cal.getTime());
}
public static void main(String[] args) {
java.util.List<java.util.Date> dates = new java.util.ArrayList<java.util.Date>();
java.util.Calendar cal = java.util.Calendar
.getInstance();
String today = sdf.format(cal.getTime());
cal.add(java.util.Calendar.DAY_OF_WEEK, -10);
for (int i = 0; i < 20; i++) {
dates.add(cal.getTime());
cal.add(java.util.Calendar.DAY_OF_WEEK, 1);
}
for (java.util.Date d : dates) {
if (sdf.format(d).equals(today)) {
System.out.println("TODAY!");
}
System.out.println(calculateCorrectDate(d));
}
}
Which gives the output
20140213
20140220
20140217
20140217
20140217
20140220
20140220
20140220
20140227
20140224
TODAY!
20140224
20140224
20140227
20140227
20140227
20140306
20140303
20140303
20140303
20140306
or with a few import(s),
// Import Static
// This simplifies accessing the Calendar fields. Use sparingly.
import static java.util.Calendar.DAY_OF_WEEK;
import static java.util.Calendar.MONDAY;
import static java.util.Calendar.THURSDAY;
// The other imports.
import java.util.Calendar;
import java.util.Date;
Then you can use,
public static String calculateCorrectDate(Date d) {
Calendar cal = Calendar.getInstance();
cal.setTime(d);
// By using import static this remains concise and correct.
int dayOfWeek = cal.get(DAY_OF_WEEK);
if (dayOfWeek >= MONDAY && dayOfWeek < THURSDAY) {
cal.set(DAY_OF_WEEK, MONDAY);
} else {
cal.set(DAY_OF_WEEK, THURSDAY);
}
return sdf.format(cal.getTime());
}
Joda-Time
UPDATE: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. This Answer is left intact as history. See my modern Answer instead.
Yes, Joda-Time is the solution.
Or the new java.time package in Java 8. Inspired by Joda-Time but re-architected. Defined by JSR 310.
Next Monday/Thursday
Search StackOverflow for getting first or last day of week. That will show you how to get next monday or thursday. I won't cover that part of your question here.
Testing Day Of Week
Testing for the day of week by the English word is prone to break if you ever happen to run where English is not the default locale. Instead, get day of week by number. Joda-Time uses ISO 8601 as its defaults, so Monday = 1, Sunday = 7. Constants are provided, so you needn't memorize the numbers.
Date Without Time
If you truly don't care about time-of-day, only date, then we can use LocalDate rather than DateTime.
Example Code
Some code to get you started, using Joda-Time 2.3.
String input = "20130224";
DateTimeFormatter formatterInput = DateTimeFormat.forPattern( "yyyyMMdd" );
LocalDate localDate = formatterInput.parseLocalDate( input );
int dayOfWeek = localDate.getDayOfWeek();
boolean isMonday = ( localDate.getDayOfWeek() == DateTimeConstants.MONDAY );
boolean isThursday = ( localDate.getDayOfWeek() == DateTimeConstants.THURSDAY );
Dump to console…
System.out.println( "localDate: " + localDate );
System.out.println( "dayOfWeek: " + dayOfWeek );
System.out.println( "isMonday: " + isMonday );
System.out.println( "isThursday: " + isThursday );
When run…
localDate: 2013-02-24
dayOfWeek: 7
isMonday: false
isThursday: false
tl;dr
If:
EnumSet.range( DayOfWeek.MONDAY , DayOfWeek.WEDNESDAY ) // Monday, Tuesday, & Wednesday.
contains( LocalDate.now().getDayOfWeek() ) // If today’s date is a day-of-week that happens to be a member of that `Set`.
…then, apply:
TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY ) // Adjust into an earlier `LocalDate` that is a Monday, unless today already is Monday.
…else apply:
TemporalAdjusters.previousOrSame( DayOfWeek.THURSDAY ) // Otherwise move to a Thursday.
java.time
The modern approach uses the java.time classes. So much easier to solve this Question.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
If no time zone is specified, the JVM implicitly applies its current default time zone. That default may change at any moment, so your results may vary. Better to specify your desired/expected time zone explicitly as an argument.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ;
LocalDate today = LocalDate.now( z ) ;
If you want to use the JVM’s current default time zone, ask for it and pass as an argument. If omitted, the JVM’s current default is applied implicitly. Better to be explicit.
ZoneId z = ZoneId.systemDefault() ; // Get JVM’s current default time zone.
Or specify a date. You may set the month by a number, with sane numbering 1-12 for January-December.
LocalDate ld = LocalDate.of( 1986 , 2 , 23 ) ; // Years use sane direct numbering (1986 means year 1986). Months use sane numbering, 1-12 for January-December.
Or, better, use the Month enum objects pre-defined, one for each month of the year. Tip: Use these Month objects throughout your codebase rather than a mere integer number to make your code more self-documenting, ensure valid values, and provide type-safety.
LocalDate ld = LocalDate.of( 1986 , Month.FEBRUARY , 23 ) ;
DayOfWeek enum
The DayOfWeek enum defines a set of seven objects, one for each day of the week.
An EnumSet is a highly-optimized implementation of Set for collecting enum objects. So we can make a pair of EnumSet objects to hold a collection of DayOfWeek objects to define your two conditions: (Monday & Tuesday) versus (Thursday…Sunday).
Despite mysteriously failing to implement SortedSet, an EnumSet is indeed sorted in the natural order (declared order) of the enum. For DayOfWeek that would be Monday-Sunday, numbered 1-7 though you may never need those numbers.
Set < DayOfWeek > mondayDays = EnumSet.range( DayOfWeek.MONDAY , DayOfWeek.WEDNESDAY ); // Monday, Tuesday, & Wednesday.
Set < DayOfWeek > thursdayDays = EnumSet.range( DayOfWeek.THURSDAY , DayOfWeek.SUNDAY ); // Thursday, Friday, Saturday, Sunday.
Get the day-of-week for our source date. Prepare to match that against our enum sets.
LocalDate ld = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ) ; // Get today’s current date in a particular time zone.
DayOfWeek dow = ld.getDayOfWeek();
LocalDate target = LocalDate.EPOCH; // Or null. The `LocalDate.EPOCH` is first moment of 1970 in UTC, 1970-01-01T00:00:00Z.
See which Set has the day-of-week of our date. From there, adjust into a previous or same date for the desired day-of-week (Monday or Thursday).
if ( mondayDays.contains( dow ) )
{
target = ld.with( TemporalAdjusters.previousOrSame( DayOfWeek.MONDAY ) );
} else if ( thursdayDays.contains( dow ) )
{
target = ld.with( TemporalAdjusters.previousOrSame( DayOfWeek.THURSDAY ) );
} else
{
System.out.println( "ERROR - Unexpectedly reached IF-ELSE. " );
}
Generate string in your desired format. Your chosen format happens to be the “basic” version of standard ISO 8601 format where the use of delimiters is minimized.
String output = target.format( DateTimeFormatter.BASIC_ISO_DATE ) ; // YYYY-MM-DD
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8, Java SE 9, and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and Java SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
Later versions of Android bundle implementations of the java.time classes.
For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
hi i want to make a program in java where days,weekNo is parameter ..Like First Friday of the month or second Monday of the month ..and it returns the date
Here's a utility method that does that, using DateUtils from Apache Commons / Lang:
/**
* Get the n-th x-day of the month in which the specified date lies.
* #param input the specified date
* #param weeks 1-based offset (e.g. 1 means 1st week)
* #param targetWeekDay (the weekday we're looking for, e.g. Calendar.MONDAY
* #return the target date
*/
public static Date getNthXdayInMonth(final Date input,
final int weeks,
final int targetWeekDay){
// strip all date fields below month
final Date startOfMonth = DateUtils.truncate(input, Calendar.MONTH);
final Calendar cal = Calendar.getInstance();
cal.setTime(startOfMonth);
final int weekDay = cal.get(Calendar.DAY_OF_WEEK);
final int modifier = (weeks - 1) * 7 + (targetWeekDay - weekDay);
return modifier > 0
? DateUtils.addDays(startOfMonth, modifier)
: startOfMonth;
}
Test code:
// Get this month's third thursday
System.out.println(getNthXdayInMonth(new Date(), 3, Calendar.THURSDAY));
// Get next month's second wednesday:
System.out.println(getNthXdayInMonth(DateUtils.addMonths(new Date(), 1),
2,
Calendar.WEDNESDAY)
);
Output:
Thu Nov 18 00:00:00 CET 2010
Wed Dec 08 00:00:00 CET 2010
And here's a JodaTime version of the same code (I've never used JodaTime before, so there's probably a simpler way to do it):
/**
* Get the n-th x-day of the month in which the specified date lies.
*
* #param input
* the specified date
* #param weeks
* 1-based offset (e.g. 1 means 1st week)
* #param targetWeekDay
* (the weekday we're looking for, e.g. DateTimeConstants.MONDAY
* #return the target date
*/
public static DateTime getNthXdayInMonthUsingJodaTime(final DateTime input,
final int weeks,
final int targetWeekDay){
final DateTime startOfMonth =
input.withDayOfMonth(1).withMillisOfDay(0);
final int weekDay = startOfMonth.getDayOfWeek();
final int modifier = (weeks - 1) * 7 + (targetWeekDay - weekDay);
return modifier > 0 ? startOfMonth.plusDays(modifier) : startOfMonth;
}
Test Code:
// Get this month's third thursday
System.out.println(getNthXdayInMonthUsingJodaTime(new DateTime(),
3,
DateTimeConstants.THURSDAY));
// Get next month's second wednesday:
System.out.println(getNthXdayInMonthUsingJodaTime(new DateTime().plusMonths(1),
2,
DateTimeConstants.WEDNESDAY));
Output:
2010-11-18T00:00:00.000+01:00
2010-12-08T00:00:00.000+01:00
public static Date getDate(int day, int weekNo, int month, int year) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DATE,1);
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month);
for (int i = 0; i < 31; i++) {
if (cal.get(Calendar.WEEK_OF_MONTH) == weekNo
&& cal.get(Calendar.DAY_OF_WEEK) == day) {
return cal.getTime();
}
cal.add(Calendar.DATE,1);
}
return null;
}
Calling code
System.out.println(""+getDate(Calendar.MONDAY, 2, Calendar.DECEMBER,2010));
Output
Mon Dec 06 15:09:00 IST 2010
Resource
Also look at Joda Time it is better
tl;dr
LocalDate firstFridayThisMonth =
LocalDate.now( ZoneId.of( "America/Montreal" ) )
.with( TemporalAdjusters.firstInMonth( DayOfWeek.FRIDAY ) )
Using java.time
The other Answers are now outdated. The troublesome old date-time classes (Date, Calendar, etc.) are now legacy, supplanted by the java.time classes.
LocalDate
The LocalDate class represents a date-only value without time-of-day and without time zone.
A time zone is crucial in determining a date. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.
Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
TemporalAdjuster
The TemporalAdjuster interface provides for manipulating date-time values. The java.time classes use immutable objects, so the result is always a fresh new object with values based on the original.
The TemporalAdjusters class (note plural name) provides several handy implementations. Amongst those are ones to get ordinal day-of-week within the month: firstInMonth(), lastInMonth(), and dayOfWeekInMonth(). All of these take an argument of a DayOfWeek enum object.
LocalDate firstFridayOfThisMonth =
today.with(
TemporalAdjusters.firstInMonth( DayOfWeek.FRIDAY )
)
;
…and…
LocalDate secondMondayOfThisMonth =
today.with(
TemporalAdjusters.dayOfWeekInMonth( 2 , DayOfWeek.MONDAY )
)
;
…and…
LocalDate thirdWednesdayOfNextMonth =
today.plusMonths( 1 )
.with(
TemporalAdjusters.dayOfWeekInMonth( 3 , DayOfWeek.WEDNESDAY )
)
;
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
Java SE 8 and SE 9 and later
Built-in.
Part of the standard Java API with a bundled implementation.
Java 9 adds some minor features and fixes.
Java SE 6 and SE 7
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
Android
The ThreeTenABP project adapts ThreeTen-Backport (mentioned above) for Android specifically.
See How to use ThreeTenABP….
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.
Calendar cal = Calendar.getInstance();
int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
this should do what you want.
edit:
with some more calculate steps, you could have result :) (sorry for confuse your title)