1
2
3
4
5
6
7
8
9
10
11 package ch.qos.logback.core.rolling.helper;
12
13 import java.text.SimpleDateFormat;
14 import java.util.Calendar;
15 import java.util.Date;
16 import java.util.GregorianCalendar;
17 import java.util.Locale;
18 import java.util.TimeZone;
19
20 import ch.qos.logback.core.spi.ContextAwareBase;
21
22
23
24
25
26
27
28
29
30
31 public class RollingCalendar extends GregorianCalendar {
32
33 private static final long serialVersionUID = -5937537740925066161L;
34
35
36 static final TimeZone GMT_TIMEZONE = TimeZone.getTimeZone("GMT");
37
38 PeriodicityType type = PeriodicityType.ERRONEOUS;
39
40 public RollingCalendar() {
41 super();
42 }
43
44 public RollingCalendar(TimeZone tz, Locale locale) {
45 super(tz, locale);
46 }
47
48 public void init(String datePattern) {
49 type = computePeriodicity(datePattern);
50 }
51
52 private void setType(PeriodicityType type) {
53 this.type = type;
54 }
55
56 public long getNextTriggeringMillis(Date now) {
57 return getNextTriggeringDate(now).getTime();
58 }
59
60
61
62
63
64
65
66
67
68 public PeriodicityType computePeriodicity(String datePattern) {
69 RollingCalendar rollingCalendar = new RollingCalendar(GMT_TIMEZONE, Locale
70 .getDefault());
71
72
73 Date epoch = new Date(0);
74
75 if (datePattern != null) {
76 for (PeriodicityType i : PeriodicityType.VALID_ORDERED_LIST) {
77 SimpleDateFormat simpleDateFormat = new SimpleDateFormat(datePattern);
78 simpleDateFormat.setTimeZone(GMT_TIMEZONE);
79
80 String r0 = simpleDateFormat.format(epoch);
81 rollingCalendar.setType(i);
82
83 Date next = new Date(rollingCalendar.getNextTriggeringMillis(epoch));
84 String r1 = simpleDateFormat.format(next);
85
86
87 if ((r0 != null) && (r1 != null) && !r0.equals(r1)) {
88 return i;
89 }
90 }
91 }
92
93 return PeriodicityType.ERRONEOUS;
94 }
95
96 public void printPeriodicity(ContextAwareBase cab) {
97 switch (type) {
98 case TOP_OF_SECOND:
99 cab.addInfo("Roll-over every second.");
100
101 break;
102
103 case TOP_OF_MINUTE:
104 cab.addInfo("Roll-over every minute.");
105
106 break;
107
108 case TOP_OF_HOUR:
109 cab.addInfo("Roll-over at the top of every hour.");
110
111 break;
112
113 case HALF_DAY:
114 cab.addInfo("Roll-over at midday and midnight.");
115
116 break;
117
118 case TOP_OF_DAY:
119 cab.addInfo("Roll-over at midnight.");
120
121 break;
122
123 case TOP_OF_WEEK:
124 cab.addInfo("Rollover at the start of week.");
125
126 break;
127
128 case TOP_OF_MONTH:
129 cab.addInfo("Rollover at start of every month.");
130
131 break;
132
133 default:
134 cab.addInfo("Unknown periodicity.");
135 }
136 }
137
138 public Date getRelativeDate(Date now, int periods) {
139 this.setTime(now);
140
141 switch (type) {
142 case TOP_OF_SECOND:
143 this.set(Calendar.MILLISECOND, 0);
144 this.add(Calendar.SECOND, periods);
145
146 break;
147
148 case TOP_OF_MINUTE:
149 this.set(Calendar.SECOND, 0);
150 this.set(Calendar.MILLISECOND, 0);
151 this.add(Calendar.MINUTE, periods);
152
153 break;
154
155 case TOP_OF_HOUR:
156 this.set(Calendar.MINUTE, 0);
157 this.set(Calendar.SECOND, 0);
158 this.set(Calendar.MILLISECOND, 0);
159 this.add(Calendar.HOUR_OF_DAY, periods);
160
161 break;
162
163 case TOP_OF_DAY:
164 this.set(Calendar.HOUR_OF_DAY, 0);
165 this.set(Calendar.MINUTE, 0);
166 this.set(Calendar.SECOND, 0);
167 this.set(Calendar.MILLISECOND, 0);
168 this.add(Calendar.DATE, periods);
169
170 break;
171
172 case TOP_OF_WEEK:
173 this.set(Calendar.DAY_OF_WEEK, getFirstDayOfWeek());
174 this.set(Calendar.HOUR_OF_DAY, 0);
175 this.set(Calendar.MINUTE, 0);
176 this.set(Calendar.SECOND, 0);
177 this.set(Calendar.MILLISECOND, 0);
178 this.add(Calendar.WEEK_OF_YEAR, periods);
179
180 break;
181
182 case TOP_OF_MONTH:
183 this.set(Calendar.DATE, 1);
184 this.set(Calendar.HOUR_OF_DAY, 0);
185 this.set(Calendar.MINUTE, 0);
186 this.set(Calendar.SECOND, 0);
187 this.set(Calendar.MILLISECOND, 0);
188 this.add(Calendar.MONTH, periods);
189
190 break;
191
192 default:
193 throw new IllegalStateException("Unknown periodicity type.");
194 }
195
196 return getTime();
197 }
198
199 public Date getNextTriggeringDate(Date now) {
200 return getRelativeDate(now, 1);
201 }
202 }