1 /*
2 * File: AbstractDateIterator.java
3 * Copyright (c) 2004-2007 Peter Kliem (Peter.Kliem@jaret.de)
4 * A commercial license is available, see http://www.jaret.de.
5 *
6 * All rights reserved. This program and the accompanying materials
7 * are made available under the terms of the Common Public License v1.0
8 * which accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/cpl-v10.html
10 */
11 package de.jaret.util.date.iterator;
12
13 import java.util.TimeZone;
14
15 import de.jaret.util.date.JaretDate;
16
17 /**
18 * Abstract base Implementation of a DateIterator.
19 *
20 * @author kliem
21 * @version $Id: AbstractDateIterator.java 883 2009-10-07 21:03:00Z kliem $
22 */
23 public abstract class AbstractDateIterator implements DateIterator {
24 /** the current date. */
25 protected JaretDate _currentDate;
26 /** the last date. */
27 protected JaretDate _endDate;
28
29 /** true if DST should be corrected. */
30 protected boolean _correctDST = false;
31 /** flag for remembering if the last date was in or out DST. */
32 protected boolean _lastInDST;
33
34 /**
35 * Constructor supplying values.
36 *
37 * @param startDate start date
38 * @param endDate end date. <code>null</code> for unlimited iterating
39 */
40 public AbstractDateIterator(JaretDate startDate, JaretDate endDate) {
41 reInitialize(startDate, endDate);
42 }
43
44 /**
45 * Default constructor. Beware: reinitialize has to be called at least once.
46 */
47 public AbstractDateIterator() {
48
49 }
50
51 /**
52 * Correct the given date to a clean starting position.
53 *
54 * @param date start date
55 * @return clean starting position
56 */
57 protected abstract JaretDate correctStartDate(JaretDate date);
58
59 /**
60 * Advance the given date by the amount necessary.
61 *
62 * @param date date to be modified
63 */
64 protected abstract void advanceDate(JaretDate date);
65
66 /**
67 * {@inheritDoc}
68 */
69 public void reInitialize(JaretDate startDate, JaretDate endDate) {
70 _currentDate = startDate.copy();
71 _lastInDST = TimeZone.getDefault().inDaylightTime(_currentDate.getDate());
72 // correct the start date
73 _currentDate = correctStartDate(_currentDate);
74 // remember the end date
75 _endDate = endDate == null ? null : endDate.copy();
76 }
77
78 /**
79 * {@inheritDoc}
80 */
81 public JaretDate getNextDate() {
82 if (_currentDate == null) {
83 throw new IllegalStateException("not initialized");
84 }
85 JaretDate result = _currentDate;
86 _currentDate = internalNextDate();
87
88 return result;
89 }
90
91 /**
92 * Internal helper to get the next date without modifications.
93 *
94 * @return the next date or <code>null</code> if no next date will be given.
95 */
96 private JaretDate internalNextDate() {
97 if (_currentDate == null) {
98 return null;
99 }
100 JaretDate d = _currentDate.copy();
101
102 // if a dst change happened and a correction should be performed do the nasty
103 // correction
104 if (_correctDST) {
105 boolean inDST = TimeZone.getDefault().inDaylightTime(_currentDate.getDate());
106
107 if (_lastInDST != inDST) {
108 if (inDST) {
109 d.advanceMillis(-TimeZone.getDefault().getDSTSavings());
110 } else {
111 d.advanceMillis(TimeZone.getDefault().getDSTSavings());
112 }
113 }
114
115 _lastInDST = inDST;
116 }
117
118 // do the advance
119 advanceDate(d);
120
121 if (_endDate == null || d.compareTo(_endDate) <= 0) {
122 return d;
123 }
124 return null;
125 }
126
127 /**
128 * {@inheritDoc}
129 */
130 public boolean hasNextDate() {
131 return _currentDate != null;
132 }
133
134 /**
135 * {@inheritDoc}
136 */
137 public JaretDate previewNextDate() {
138 return _currentDate != null ? _currentDate.copy() : null;
139 }
140
141 /**
142 * {@inheritDoc}
143 */
144 public String getLabel(JaretDate date, Format format) {
145 return getFormatter().getLabel(date, format);
146 }
147
148 /** if set this formatter overrides default behaviour. */
149 protected IIteratorFormatter _formatter;
150
151 /**
152 * Retrieve the formatter to use. This is either a set formatter or the default formatter.
153 *
154 * @return a formatter to be used.
155 */
156 protected IIteratorFormatter getFormatter() {
157 if (_formatter != null) {
158 return _formatter;
159 } else {
160 return getDefaultFormatter();
161 }
162 }
163
164 /**
165 * Internal method to retrieve a default formatter.
166 *
167 * @return the default formatter of the iterator
168 */
169 protected abstract IIteratorFormatter getDefaultFormatter();
170
171 /**
172 * {@inheritDoc}
173 */
174 public void setFormatter(IIteratorFormatter formatter) {
175 _formatter = formatter;
176 }
177
178 /**
179 * {@inheritDoc}
180 */
181 public void setCorrectDST(boolean correctDST) {
182 _correctDST = correctDST;
183 }
184
185 }