Reputation: 131
This is homework.
I am trying to find every occurrence of a Sunday landing on the first of a month between Jan 1 1900 (which we are assuming was a Monday) and Dec 31 of a year that the user inputs. The calendar extension is off-limits.
I am returning dates in the correct format, but they do not match up with the example code our instructor provided.
In the given example, an input of 1902 should return:
1 Apr 1900
1 Jul 1900
1 Sep 1901
1 Dec 1901
1 Jun 1902
For 1902, my code returns:
1 Mar 1900
1 Jan 1901
1 Apr 1901
1 May 1901
1 Feb 1902
1 Jun 1902
1 Jul 1902
import java.util.Scanner;
public class Sundays {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.print("Enter the ending year: ");
int userInputYear = reader.nextInt();
int[] orderedLengthOfMonthsArray = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
String[] orderedNamesOfMonthsArray = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
int month = 0;
int dayOfWeek = 1; // initialized to MONDAY Jan 1, 1900 -- Sunday would be #7
int dayOfMonth = 1;
for (int year = 1900; year <= userInputYear; year++) {
for (month = 0; month < orderedLengthOfMonthsArray.length; month++) {
for (dayOfMonth = 1; dayOfMonth <= orderedLengthOfMonthsArray[month]; dayOfMonth++) {
dayOfWeek++;
if (dayOfMonth == 1 && dayOfWeek == 7) {
System.out.println(dayOfMonth + " " + orderedNamesOfMonthsArray[month] + " " + year);
}
if (dayOfWeek == 8) {
dayOfWeek = 1;
}
}
}
}
}
}
Upvotes: 1
Views: 1297
Reputation: 22471
Just for fun, while you have explicitly mentioned not to use Calendar
, here is how we could do it:
public static List<Date> mondaysFirst(int firstYear, int lastYear) {
final List<Date> dates = new ArrayList<>();
final Calendar c1 = Calendar.getInstance(Locale.US);
c1.set(firstYear, 0, 1, 0, 0, 0);
final Calendar c2 = Calendar.getInstance(Locale.US);
c2.set(lastYear, 11, 31, 23, 59, 59);
while (c1.before(c2)) {
final int dayOfTheWeek = c1.get(Calendar.DAY_OF_WEEK);
// is sunday
if (dayOfTheWeek == 1) {
dates.add(c1.getTime());
}
c1.add(Calendar.MONTH, 1);
}
return dates;
}
And to print the results:
final List<Date> dates = mondaysFirst(1900, 1902);
final SimpleDateFormat sf = new SimpleDateFormat("dd MMM yyyy");
for (Date date: dates) {
System.out.println(sf.format(date));
}
I'm sure that there is some Joda-Time magic to make this even shorter.
Upvotes: 0
Reputation: 339332
Someone mentioned Joda-Time magic… So here's my solution using Joda-Time 2.3.
While the question (a homework assignment) forbade the use of added libraries…
My example code uses LocalDate
which should only be used if your are absolutely certain that you don't care about (a) time of day, and (b) time zones. I do not usually recommend this approach as naïve programmers who believe they need neither time nor zone often turn out to be mistaken.
// Start
LocalDate start = new LocalDate( 1900, 1, 1 );
// Stop
// Using "half-open" comparison. We care about December 31 of specified year, but we will test for January 1 of year after.
String input = "1930";
int year = Integer.valueOf( input );
year = ( year + 1 ); // Add one to get to next year, for "half-open" approach.
LocalDate stop = new LocalDate( year, 1, 1 );
// Collect each LocalDate where the first of the month is a Sunday.
java.util.List<LocalDate> localDates = new java.util.ArrayList<LocalDate>();
LocalDate localDate = start;
do {
if ( localDate.getDayOfWeek() == DateTimeConstants.SUNDAY ) { // Comparing 'int' primitive values.
localDates.add( localDate ); // Collect this LocalDate instance.
}
localDate = localDate.plusMonths( 1 ); // Move on to next month. Joda-Time is smart about various month-ends and leap-year.
} while ( localDate.isBefore( stop ) ); // "Half-Open" means test "<" rather than "<=".
Dump to console…
System.out.println( "The First-Of-The-Month days that are Sundays from " + start + " (inclusive) to " + stop + " (exclusive):" );
System.out.println( localDates );
The First-Of-The-Month days that are Sundays from 1900-01-01 (inclusive) to 1931-01-01 (exclusive):
[1900-04-01, 1900-07-01, 1901-09-01, 1901-12-01, 1902-06-01, 1903-02-01, 1903-03-01, 1903-11-01, 1904-05-01, 1905-01-01, 1905-10-01, 1906-04-01, 1906-07-01, 1907-09-01, 1907-12-01, 1908-03-01, 1908-11-01, 1909-08-01, 1910-05-01, 1911-01-01, 1911-10-01, 1912-09-01, 1912-12-01, 1913-06-01, 1914-02-01, 1914-03-01, 1914-11-01, 1915-08-01, 1916-10-01, 1917-04-01, 1917-07-01, 1918-09-01, 1918-12-01, 1919-06-01, 1920-02-01, 1920-08-01, 1921-05-01, 1922-01-01, 1922-10-01, 1923-04-01, 1923-07-01, 1924-06-01, 1925-02-01, 1925-03-01, 1925-11-01, 1926-08-01, 1927-05-01, 1928-01-01, 1928-04-01, 1928-07-01, 1929-09-01, 1929-12-01, 1930-06-01]
Upvotes: 1
Reputation: 1260
Swap the if statement and the increase of dayOfWeek
.
for (dayOfMonth = 1; dayOfMonth <= orderedLengthOfMonthsArray[month]; dayOfMonth++) {
if (dayOfMonth == 1 && dayOfWeek == 7) {
System.out.println(dayOfMonth + " " + orderedNamesOfMonthsArray[month] + " " + year);
}
dayOfWeek++;
if (dayOfWeek == 8) {
dayOfWeek = 1;
}
}
When you are in the dayOfMonth for
loop, you already have the correct day of the week (initially Monday, Jan 1st, 1900), so if you first increase it, then the check afterwards would be incorrect.
Upvotes: 3
Reputation: 1249
if (dayOfWeek == 7) {
dayOfWeek = 1;
}
So your week has 6 days? I think you should either reset to zero or reset when dayOfWeek
is 8.
Upvotes: 1