1   /*
2    * JodaFriday13th - Searching Friday the 13th dates with Joda-Time
3    * Copyright (C) 2009 Christian Schenk
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    * 
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   * 
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18   */
19  package org.christianschenk.friday13th;
20  
21  import java.util.ArrayList;
22  import java.util.HashMap;
23  import java.util.List;
24  import java.util.Map;
25  
26  import org.joda.time.DateTime;
27  import org.joda.time.DateTimeConstants;
28  import org.joda.time.format.DateTimeFormat;
29  import org.joda.time.format.DateTimeFormatter;
30  
31  /**
32   * Searching Friday the 13th dates with Joda-Time
33   * 
34   * @author Christian Schenk
35   */
36  public class Friday13th {
37  
38  	/**
39  	 * Gets the next <em>n</em> days of Friday the 13th.
40  	 */
41  	public static List<DateTime> getNextNthFriday13th(final int n) {
42  		final List<DateTime> fridays = new ArrayList<DateTime>();
43  
44  		DateTime dt = new DateTime();
45  		int curN = 0;
46  		while (curN < n) {
47  			dt = dt.plusDays(1);
48  
49  			if (dt.getDayOfMonth() != 13) continue;
50  			if (dt.getDayOfWeek() != DateTimeConstants.FRIDAY) continue;
51  
52  			fridays.add(new DateTime(dt.toInstant()));
53  			curN++;
54  		}
55  
56  		return fridays;
57  	}
58  
59  	/**
60  	 * Returns the next year with the most days of Friday the 13th dates.
61  	 */
62  	public static YearCount getYearWithLotsOfFriday13th() {
63  		final int MAX_YEARS = 20;
64  
65  		final Map<Integer, Integer> yearFriday13thCount = new HashMap<Integer, Integer>();
66  
67  		// get fridays and add them to the map
68  		final List<DateTime> friday13ths = getNextNthFriday13th(MAX_YEARS);
69  		for (final DateTime friday : friday13ths) {
70  			final int year = friday.getYear();
71  			if (yearFriday13thCount.get(year) == null) yearFriday13thCount.put(year, 0);
72  			yearFriday13thCount.put(year, yearFriday13thCount.get(year) + 1);
73  		}
74  
75  		// find year with the most friday 13th
76  		int year = Integer.MAX_VALUE, count = Integer.MIN_VALUE;
77  		for (final int curYear : yearFriday13thCount.keySet()) {
78  			final int curCount = yearFriday13thCount.get(curYear);
79  			if (curCount > count && curYear < year) {
80  				year = curYear;
81  				count = curCount;
82  			}
83  		}
84  
85  		final int theYear = year;
86  		final int theCount = count;
87  
88  		return new YearCount() {
89  			public int getCount() {
90  				return theCount;
91  			}
92  
93  			public int getYear() {
94  				return theYear;
95  			}
96  		};
97  	}
98  
99  	/**
100 	 * Encapsulates a year and its count of Friday the 13th dates.
101 	 */
102 	private interface YearCount {
103 		public int getYear();
104 
105 		public int getCount();
106 	}
107 
108 	public static void main(final String[] args) {
109 		final List<DateTime> fridays = getNextNthFriday13th(3);
110 		final DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd");
111 		System.out.println("Next Friday the 13th dates:");
112 		for (final DateTime friday : fridays) {
113 			System.out.println(format.print(friday));
114 		}
115 		System.out.println("");
116 
117 		final YearCount yc = getYearWithLotsOfFriday13th();
118 		System.out.println("The year " + yc.getYear() + " has got " + yc.getCount() + " Friday the 13th dates.");
119 	}
120 }