1
import java.text.DecimalFormat;
2
import java.util.Arrays;
3
4
/**
5
* 時間計算工具類
6
*/
7
public class Time {
8
9
/**
10
* 時間字段常量,表示“秒”
11
*/
12
public final static int SECOND = 0;
13
14
/**
15
* 時間字段常量,表示“分”
16
*/
17
public final static int MINUTE = 1;
18
19
/**
20
* 時間字段常量,表示“時”
21
*/
22
public final static int HOUR = 2;
23
24
/**
25
* 時間字段常量,表示“天”
26
*/
27
public final static int DAY = 3;
28
29
/**
30
* 各常量允許的最大值
31
*/
32
private final int[] maxFields = { 59, 59, 23, Integer.MAX_VALUE - 1 };
33
34
/**
35
* 各常量允許的最小值
36
*/
37
private final int[] minFields = { 0, 0, 0, Integer.MIN_VALUE };
38
39
/**
40
* 默認的字符串格式時間分隔符
41
*/
42
private String timeSeparator = ":";
43
44
/**
45
* 時間數據容器
46
*/
47
private int[] fields = new int[4];
48
49
/**
50
* 無參構造,將各字段置為 0
51
*/
52
public Time() {
53
this(0, 0, 0, 0);
54
}
55
56
/**
57
* 使用時、分構造一個時間
58
* @param hour 小時
59
* @param minute 分鐘
60
*/
61
public Time(int hour, int minute) {
62
this(0, hour, minute, 0);
63
}
64
65
/**
66
* 使用時、分、秒構造一個時間
67
* @param hour 小時
68
* @param minute 分鐘
69
* @param second 秒
70
*/
71
public Time(int hour, int minute, int second) {
72
this(0, hour, minute, second);
73
}
74
75
/**
76
* 使用一個字符串構造時間<br/>
77
* Time time = new Time("14:22:23");
78
* @param time 字符串格式的時間,默認采用“:”作為分隔符
79
*/
80
public Time(String time) {
81
this(time, null);
82
}
83
84
/**
85
* 使用天、時、分、秒構造時間,進行全字符的構造
86
* @param day 天
87
* @param hour 時
88
* @param minute 分
89
* @param second 秒
90
*/
91
public Time(int day, int hour, int minute, int second) {
92
set(DAY, day);
93
set(HOUR, hour);
94
set(MINUTE, minute);
95
set(SECOND, second);
96
}
97
98
/**
99
* 使用一個字符串構造時間,指定分隔符<br/>
100
* Time time = new Time("14-22-23", "-");
101
* @param time 字符串格式的時間
102
*/
103
public Time(String time, String timeSeparator) {
104
if(timeSeparator != null) {
105
setTimeSeparator(timeSeparator);
106
}
107
String pattern = patternQuote(this.timeSeparator);
108
String matcher = new StringBuffer()
109
.append("\\d+?").append(pattern)
110
.append("\\d+?").append(pattern)
111
.append("\\d+?")
112
.toString();
113
if(!time.matches(matcher)) {
114
throw new IllegalArgumentException(time + ", time format error, HH"
115
+ this.timeSeparator + "mm" + this.timeSeparator + "ss");
116
}
117
String[] times = time.split(pattern);
118
set(DAY, 0);
119
set(HOUR, Integer.parseInt(times[0]));
120
set(MINUTE, Integer.parseInt(times[1]));
121
set(SECOND, Integer.parseInt(times[2]));
122
}
123
124
/**
125
* 設置時間字段的值
126
* @param field 時間字段常量
127
* @param value 時間字段的值
128
*/
129
public void set(int field, int value) {
130
if(value < minFields[field]) {
131
throw new IllegalArgumentException(value +
132
", time value must be positive.");
133
}
134
fields[field] = value % (maxFields[field] + 1);
135
// 進行進位計算
136
int carry = value / (maxFields[field] + 1);
137
if(carry > 0) {
138
int upFieldValue = get(field + 1);
139
set(field + 1, upFieldValue + carry);
140
}
141
}
142
143
/**
144
* 獲得時間字段的值
145
* @param field 時間字段常量
146
* @return 該時間字段的值
147
*/
148
public int get(int field) {
149
if(field < 0 || field > fields.length - 1) {
150
throw new IllegalArgumentException(field + ", field value is error.");
151
}
152
return fields[field];
153
}
154
155
/**
156
* 將時間進行“加”運算,即加上一個時間
157
* @param time 需要加的時間
158
* @return 運算后的時間
159
*/
160
public Time addTime(Time time) {
161
Time result = new Time();
162
int up = 0; // 進位標志
163
for (int i = 0; i < fields.length; i++) {
164
int sum = fields[i] + time.fields[i] + up;
165
up = sum / (maxFields[i] + 1);
166
result.fields[i] = sum % (maxFields[i] + 1);
167
}
168
return result;
169
}
170
171
/**
172
* 將時間進行“減”運算,即減去一個時間
173
* @param time 需要減的時間
174
* @return 運算后的時間
175
*/
176
public Time subtractTime(Time time) {
177
Time result = new Time();
178
int down = 0; // 退位標志
179
for (int i = 0, k = fields.length - 1; i < k; i++) {
180
int difference = fields[i] + down;
181
if (difference >= time.fields[i]) {
182
difference -= time.fields[i];
183
down = 0;
184
} else {
185
difference += maxFields[i] + 1 - time.fields[i];
186
down = -1;
187
}
188
result.fields[i] = difference;
189
}
190
result.fields[DAY] = fields[DAY] - time.fields[DAY] + down;
191
return result;
192
}
193
194
/**
195
* 獲得時間字段的分隔符
196
* @return
197
*/
198
public String getTimeSeparator() {
199
return timeSeparator;
200
}
201
202
/**
203
* 設置時間字段的分隔符(用于字符串格式的時間)
204
* @param timeSeparator 分隔符字符串
205
*/
206
public void setTimeSeparator(String timeSeparator) {
207
this.timeSeparator = timeSeparator;
208
}
209
210
/**
211
* 正則表達式引用處理方法,源自 JDK @link java.util.regex.Pattern#quote(String)
212
*/
213
private String patternQuote(String s) {
214
int slashEIndex = s.indexOf("\\E");
215
if (slashEIndex == -1)
216
return "\\Q" + s + "\\E";
217
218
StringBuilder sb = new StringBuilder(s.length() * 2);
219
sb.append("\\Q");
220
slashEIndex = 0;
221
int current = 0;
222
while ((slashEIndex = s.indexOf("\\E", current)) != -1) {
223
sb.append(s.substring(current, slashEIndex));
224
current = slashEIndex + 2;
225
sb.append("\\E\\\\E\\Q");
226
}
227
sb.append(s.substring(current, s.length()));
228
sb.append("\\E");
229
return sb.toString();
230
}
231
232
public String toString() {
233
DecimalFormat df = new DecimalFormat("00");
234
return new StringBuffer().append(fields[DAY]).append(", ")
235
.append(df.format(fields[HOUR])).append(timeSeparator)
236
.append(df.format(fields[MINUTE])).append(timeSeparator)
237
.append(df.format(fields[SECOND]))
238
.toString();
239
}
240
241
public int hashCode() {
242
final int PRIME = 31;
243
int result = 1;
244
result = PRIME * result + Arrays.hashCode(fields);
245
return result;
246
}
247
248
public boolean equals(Object obj) {
249
if (this == obj)
250
return true;
251
if (obj == null)
252
return false;
253
if (getClass() != obj.getClass())
254
return false;
255
final Time other = (Time) obj;
256
if (!Arrays.equals(fields, other.fields)) {
257
return false;
258
}
259
return true;
260
}
261
}
262

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262
