~ubuntu-branches/ubuntu/precise/libjoda-time-java/precise

« back to all changes in this revision

Viewing changes to src/main/java/org/joda/time/Weeks.java

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2011-02-09 23:05:14 UTC
  • mfrom: (5.2.1 sid)
  • Revision ID: james.westby@ubuntu.com-20110209230514-22otglg8nm2y2y2n
Tags: 1.6.2-2
* Upload to unstable.
* Add (temporary) Build-Depends: ant.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright 2001-2006 Stephen Colebourne
 
3
 *
 
4
 *  Licensed under the Apache License, Version 2.0 (the "License");
 
5
 *  you may not use this file except in compliance with the License.
 
6
 *  You may obtain a copy of the License at
 
7
 *
 
8
 *      http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
10
 *  Unless required by applicable law or agreed to in writing, software
 
11
 *  distributed under the License is distributed on an "AS IS" BASIS,
 
12
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 *  See the License for the specific language governing permissions and
 
14
 *  limitations under the License.
 
15
 */
 
16
package org.joda.time;
 
17
 
 
18
import org.joda.time.base.BaseSingleFieldPeriod;
 
19
import org.joda.time.field.FieldUtils;
 
20
import org.joda.time.format.ISOPeriodFormat;
 
21
import org.joda.time.format.PeriodFormatter;
 
22
 
 
23
/**
 
24
 * An immutable time period representing a number of weeks.
 
25
 * <p>
 
26
 * <code>Weeks</code> is an immutable period that can only store weeks.
 
27
 * It does not store years, months or hours for example. As such it is a
 
28
 * type-safe way of representing a number of weeks in an application.
 
29
 * <p>
 
30
 * The number of weeks is set in the constructor, and may be queried using
 
31
 * <code>getWeeks()</code>. Basic mathematical operations are provided -
 
32
 * <code>plus()</code>, <code>minus()</code>, <code>multipliedBy()</code> and
 
33
 * <code>dividedBy()</code>.
 
34
 * <p>
 
35
 * <code>Weeks</code> is thread-safe and immutable.
 
36
 *
 
37
 * @author Stephen Colebourne
 
38
 * @since 1.4
 
39
 */
 
40
public final class Weeks extends BaseSingleFieldPeriod {
 
41
 
 
42
    /** Constant representing zero weeks. */
 
43
    public static final Weeks ZERO = new Weeks(0);
 
44
    /** Constant representing one week. */
 
45
    public static final Weeks ONE = new Weeks(1);
 
46
    /** Constant representing two weeks. */
 
47
    public static final Weeks TWO = new Weeks(2);
 
48
    /** Constant representing three weeks. */
 
49
    public static final Weeks THREE = new Weeks(3);
 
50
    /** Constant representing the maximum number of weeks that can be stored in this object. */
 
51
    public static final Weeks MAX_VALUE = new Weeks(Integer.MAX_VALUE);
 
52
    /** Constant representing the minimum number of weeks that can be stored in this object. */
 
53
    public static final Weeks MIN_VALUE = new Weeks(Integer.MIN_VALUE);
 
54
 
 
55
    /** The paser to use for this class. */
 
56
    private static final PeriodFormatter PARSER = ISOPeriodFormat.standard().withParseType(PeriodType.weeks());
 
57
    /** Serialization version. */
 
58
    private static final long serialVersionUID = 87525275727380866L;
 
59
 
 
60
    //-----------------------------------------------------------------------
 
61
    /**
 
62
     * Obtains an instance of <code>Weeks</code> that may be cached.
 
63
     * <code>Weeks</code> is immutable, so instances can be cached and shared.
 
64
     * This factory method provides access to shared instances.
 
65
     *
 
66
     * @param weeks  the number of weeks to obtain an instance for
 
67
     * @return the instance of Weeks
 
68
     */
 
69
    public static Weeks weeks(int weeks) {
 
70
        switch (weeks) {
 
71
            case 0:
 
72
                return ZERO;
 
73
            case 1:
 
74
                return ONE;
 
75
            case 2:
 
76
                return TWO;
 
77
            case 3:
 
78
                return THREE;
 
79
            case Integer.MAX_VALUE:
 
80
                return MAX_VALUE;
 
81
            case Integer.MIN_VALUE:
 
82
                return MIN_VALUE;
 
83
            default:
 
84
                return new Weeks(weeks);
 
85
        }
 
86
    }
 
87
 
 
88
    //-----------------------------------------------------------------------
 
89
    /**
 
90
     * Creates a <code>Weeks</code> representing the number of whole weeks
 
91
     * between the two specified datetimes.
 
92
     *
 
93
     * @param start  the start instant, must not be null
 
94
     * @param end  the end instant, must not be null
 
95
     * @return the period in weeks
 
96
     * @throws IllegalArgumentException if the instants are null or invalid
 
97
     */
 
98
    public static Weeks weeksBetween(ReadableInstant start, ReadableInstant end) {
 
99
        int amount = BaseSingleFieldPeriod.between(start, end, DurationFieldType.weeks());
 
100
        return Weeks.weeks(amount);
 
101
    }
 
102
 
 
103
    /**
 
104
     * Creates a <code>Weeks</code> representing the number of whole weeks
 
105
     * between the two specified partial datetimes.
 
106
     * <p>
 
107
     * The two partials must contain the same fields, for example you can specify
 
108
     * two <code>LocalDate</code> objects.
 
109
     *
 
110
     * @param start  the start partial date, must not be null
 
111
     * @param end  the end partial date, must not be null
 
112
     * @return the period in weeks
 
113
     * @throws IllegalArgumentException if the partials are null or invalid
 
114
     */
 
115
    public static Weeks weeksBetween(ReadablePartial start, ReadablePartial end) {
 
116
        if (start instanceof LocalDate && end instanceof LocalDate)   {
 
117
            Chronology chrono = DateTimeUtils.getChronology(start.getChronology());
 
118
            int weeks = chrono.weeks().getDifference(
 
119
                    ((LocalDate) end).getLocalMillis(), ((LocalDate) start).getLocalMillis());
 
120
            return Weeks.weeks(weeks);
 
121
        }
 
122
        int amount = BaseSingleFieldPeriod.between(start, end, ZERO);
 
123
        return Weeks.weeks(amount);
 
124
    }
 
125
 
 
126
    /**
 
127
     * Creates a <code>Weeks</code> representing the number of whole weeks
 
128
     * in the specified interval.
 
129
     *
 
130
     * @param interval  the interval to extract weeks from, null returns zero
 
131
     * @return the period in weeks
 
132
     * @throws IllegalArgumentException if the partials are null or invalid
 
133
     */
 
134
    public static Weeks weeksIn(ReadableInterval interval) {
 
135
        if (interval == null)   {
 
136
            return Weeks.ZERO;
 
137
        }
 
138
        int amount = BaseSingleFieldPeriod.between(interval.getStart(), interval.getEnd(), DurationFieldType.weeks());
 
139
        return Weeks.weeks(amount);
 
140
    }
 
141
 
 
142
    /**
 
143
     * Creates a new <code>Weeks</code> representing the number of complete
 
144
     * standard length weeks in the specified period.
 
145
     * <p>
 
146
     * This factory method converts all fields from the period to hours using standardised
 
147
     * durations for each field. Only those fields which have a precise duration in
 
148
     * the ISO UTC chronology can be converted.
 
149
     * <ul>
 
150
     * <li>One week consists of 7 days.
 
151
     * <li>One day consists of 24 hours.
 
152
     * <li>One hour consists of 60 minutes.
 
153
     * <li>One minute consists of 60 weeks.
 
154
     * <li>One second consists of 1000 milliseconds.
 
155
     * </ul>
 
156
     * Months and Years are imprecise and periods containing these values cannot be converted.
 
157
     *
 
158
     * @param period  the period to get the number of hours from, null returns zero
 
159
     * @return the period in weeks
 
160
     * @throws IllegalArgumentException if the period contains imprecise duration values
 
161
     */
 
162
    public static Weeks standardWeeksIn(ReadablePeriod period) {
 
163
        int amount = BaseSingleFieldPeriod.standardPeriodIn(period, DateTimeConstants.MILLIS_PER_WEEK);
 
164
        return Weeks.weeks(amount);
 
165
    }
 
166
 
 
167
    /**
 
168
     * Creates a new <code>Weeks</code> by parsing a string in the ISO8601 format 'PnW'.
 
169
     * <p>
 
170
     * The parse will accept the full ISO syntax of PnYnMnWnDTnHnMnS however only the
 
171
     * weeks component may be non-zero. If any other component is non-zero, an exception
 
172
     * will be thrown.
 
173
     *
 
174
     * @param periodStr  the period string, null returns zero
 
175
     * @return the period in weeks
 
176
     * @throws IllegalArgumentException if the string format is invalid
 
177
     */
 
178
    public static Weeks parseWeeks(String periodStr) {
 
179
        if (periodStr == null) {
 
180
            return Weeks.ZERO;
 
181
        }
 
182
        Period p = PARSER.parsePeriod(periodStr);
 
183
        return Weeks.weeks(p.getWeeks());
 
184
    }
 
185
 
 
186
    //-----------------------------------------------------------------------
 
187
    /**
 
188
     * Creates a new instance representing a number of weeks.
 
189
     * You should consider using the factory method {@link #weeks(int)}
 
190
     * instead of the constructor.
 
191
     *
 
192
     * @param weeks  the number of weeks to represent
 
193
     */
 
194
    private Weeks(int weeks) {
 
195
        super(weeks);
 
196
    }
 
197
 
 
198
    /**
 
199
     * Resolves singletons.
 
200
     * 
 
201
     * @return the singleton instance
 
202
     */
 
203
    private Object readResolve() {
 
204
        return Weeks.weeks(getValue());
 
205
    }
 
206
 
 
207
    //-----------------------------------------------------------------------
 
208
    /**
 
209
     * Gets the duration field type, which is <code>weeks</code>.
 
210
     *
 
211
     * @return the period type
 
212
     */
 
213
    public DurationFieldType getFieldType() {
 
214
        return DurationFieldType.weeks();
 
215
    }
 
216
 
 
217
    /**
 
218
     * Gets the period type, which is <code>weeks</code>.
 
219
     *
 
220
     * @return the period type
 
221
     */
 
222
    public PeriodType getPeriodType() {
 
223
        return PeriodType.weeks();
 
224
    }
 
225
 
 
226
    //-----------------------------------------------------------------------
 
227
    /**
 
228
     * Converts this period in weeks to a period in days assuming a
 
229
     * 7 day week.
 
230
     * <p>
 
231
     * This method allows you to convert between different types of period.
 
232
     * However to achieve this it makes the assumption that all weeks are
 
233
     * 7 days long.
 
234
     * This may not be true for some unusual chronologies. However, it is included
 
235
     * as it is a useful operation for many applications and business rules.
 
236
     * 
 
237
     * @return a period representing the number of days for this number of weeks
 
238
     * @throws ArithmeticException if the number of days is too large to be represented
 
239
     */
 
240
    public Days toStandardDays() {
 
241
        return Days.days(FieldUtils.safeMultiply(getValue(), DateTimeConstants.DAYS_PER_WEEK));
 
242
    }
 
243
 
 
244
    /**
 
245
     * Converts this period in weeks to a period in hours assuming a
 
246
     * 7 day week and 24 hour day.
 
247
     * <p>
 
248
     * This method allows you to convert between different types of period.
 
249
     * However to achieve this it makes the assumption that all weeks are
 
250
     * 7 days long and all days are 24 hours long.
 
251
     * This is not true when daylight savings is considered and may also not
 
252
     * be true for some unusual chronologies. However, it is included
 
253
     * as it is a useful operation for many applications and business rules.
 
254
     * 
 
255
     * @return a period representing the number of hours for this number of weeks
 
256
     * @throws ArithmeticException if the number of hours is too large to be represented
 
257
     */
 
258
    public Hours toStandardHours() {
 
259
        return Hours.hours(FieldUtils.safeMultiply(getValue(), DateTimeConstants.HOURS_PER_WEEK));
 
260
    }
 
261
 
 
262
    /**
 
263
     * Converts this period in weeks to a period in minutes assuming a
 
264
     * 7 day week, 24 hour day and 60 minute hour.
 
265
     * <p>
 
266
     * This method allows you to convert between different types of period.
 
267
     * However to achieve this it makes the assumption that all weeks are
 
268
     * 7 days long, all days are 24 hours long and all hours are 60 minutes long.
 
269
     * This is not true when daylight savings is considered and may also not
 
270
     * be true for some unusual chronologies. However, it is included
 
271
     * as it is a useful operation for many applications and business rules.
 
272
     * 
 
273
     * @return a period representing the number of minutes for this number of weeks
 
274
     * @throws ArithmeticException if the number of minutes is too large to be represented
 
275
     */
 
276
    public Minutes toStandardMinutes() {
 
277
        return Minutes.minutes(FieldUtils.safeMultiply(getValue(), DateTimeConstants.MINUTES_PER_WEEK));
 
278
    }
 
279
 
 
280
    /**
 
281
     * Converts this period in weeks to a period in seconds assuming a
 
282
     * 7 day week, 24 hour day, 60 minute hour and 60 second minute.
 
283
     * <p>
 
284
     * This method allows you to convert between different types of period.
 
285
     * However to achieve this it makes the assumption that all weeks are
 
286
     * 7 days long, all days are 24 hours long, all hours are 60 minutes long
 
287
     * and all minutes are 60 seconds long.
 
288
     * This is not true when daylight savings is considered and may also not
 
289
     * be true for some unusual chronologies. However, it is included
 
290
     * as it is a useful operation for many applications and business rules.
 
291
     * 
 
292
     * @return a period representing the number of seconds for this number of weeks
 
293
     * @throws ArithmeticException if the number of seconds is too large to be represented
 
294
     */
 
295
    public Seconds toStandardSeconds() {
 
296
        return Seconds.seconds(FieldUtils.safeMultiply(getValue(), DateTimeConstants.SECONDS_PER_WEEK));
 
297
    }
 
298
 
 
299
    //-----------------------------------------------------------------------
 
300
    /**
 
301
     * Converts this period in weeks to a duration in milliweeks assuming a
 
302
     * 7 day week, 24 hour day, 60 minute hour and 60 second minute.
 
303
     * <p>
 
304
     * This method allows you to convert from a period to a duration.
 
305
     * However to achieve this it makes the assumption that all weeks are
 
306
     * 7 days long, all days are 24 hours long, all hours are 60 minutes long
 
307
     * and all minutes are 60 seconds long.
 
308
     * This is not true when daylight savings time is considered, and may also
 
309
     * not be true for some unusual chronologies. However, it is included as it
 
310
     * is a useful operation for many applications and business rules.
 
311
     * 
 
312
     * @return a duration equivalent to this number of weeks
 
313
     */
 
314
    public Duration toStandardDuration() {
 
315
        long weeks = getValue();  // assign to a long
 
316
        return new Duration(weeks * DateTimeConstants.MILLIS_PER_WEEK);
 
317
    }
 
318
 
 
319
    //-----------------------------------------------------------------------
 
320
    /**
 
321
     * Gets the number of weeks that this period represents.
 
322
     *
 
323
     * @return the number of weeks in the period
 
324
     */
 
325
    public int getWeeks() {
 
326
        return getValue();
 
327
    }
 
328
 
 
329
    //-----------------------------------------------------------------------
 
330
    /**
 
331
     * Returns a new instance with the specified number of weeks added.
 
332
     * <p>
 
333
     * This instance is immutable and unaffected by this method call.
 
334
     *
 
335
     * @param weeks  the amount of weeks to add, may be negative
 
336
     * @return the new period plus the specified number of weeks
 
337
     * @throws ArithmeticException if the result overflows an int
 
338
     */
 
339
    public Weeks plus(int weeks) {
 
340
        if (weeks == 0) {
 
341
            return this;
 
342
        }
 
343
        return Weeks.weeks(FieldUtils.safeAdd(getValue(), weeks));
 
344
    }
 
345
 
 
346
    /**
 
347
     * Returns a new instance with the specified number of weeks added.
 
348
     * <p>
 
349
     * This instance is immutable and unaffected by this method call.
 
350
     *
 
351
     * @param weeks  the amount of weeks to add, may be negative, null means zero
 
352
     * @return the new period plus the specified number of weeks
 
353
     * @throws ArithmeticException if the result overflows an int
 
354
     */
 
355
    public Weeks plus(Weeks weeks) {
 
356
        if (weeks == null) {
 
357
            return this;
 
358
        }
 
359
        return plus(weeks.getValue());
 
360
    }
 
361
 
 
362
    //-----------------------------------------------------------------------
 
363
    /**
 
364
     * Returns a new instance with the specified number of weeks taken away.
 
365
     * <p>
 
366
     * This instance is immutable and unaffected by this method call.
 
367
     *
 
368
     * @param weeks  the amount of weeks to take away, may be negative
 
369
     * @return the new period minus the specified number of weeks
 
370
     * @throws ArithmeticException if the result overflows an int
 
371
     */
 
372
    public Weeks minus(int weeks) {
 
373
        return plus(FieldUtils.safeNegate(weeks));
 
374
    }
 
375
 
 
376
    /**
 
377
     * Returns a new instance with the specified number of weeks taken away.
 
378
     * <p>
 
379
     * This instance is immutable and unaffected by this method call.
 
380
     *
 
381
     * @param weeks  the amount of weeks to take away, may be negative, null means zero
 
382
     * @return the new period minus the specified number of weeks
 
383
     * @throws ArithmeticException if the result overflows an int
 
384
     */
 
385
    public Weeks minus(Weeks weeks) {
 
386
        if (weeks == null) {
 
387
            return this;
 
388
        }
 
389
        return minus(weeks.getValue());
 
390
    }
 
391
 
 
392
    //-----------------------------------------------------------------------
 
393
    /**
 
394
     * Returns a new instance with the weeks multiplied by the specified scalar.
 
395
     * <p>
 
396
     * This instance is immutable and unaffected by this method call.
 
397
     *
 
398
     * @param scalar  the amount to multiply by, may be negative
 
399
     * @return the new period multiplied by the specified scalar
 
400
     * @throws ArithmeticException if the result overflows an int
 
401
     */
 
402
    public Weeks multipliedBy(int scalar) {
 
403
        return Weeks.weeks(FieldUtils.safeMultiply(getValue(), scalar));
 
404
    }
 
405
 
 
406
    /**
 
407
     * Returns a new instance with the weeks divided by the specified divisor.
 
408
     * The calculation uses integer division, thus 3 divided by 2 is 1.
 
409
     * <p>
 
410
     * This instance is immutable and unaffected by this method call.
 
411
     *
 
412
     * @param divisor  the amount to divide by, may be negative
 
413
     * @return the new period divided by the specified divisor
 
414
     * @throws ArithmeticException if the divisor is zero
 
415
     */
 
416
    public Weeks dividedBy(int divisor) {
 
417
        if (divisor == 1) {
 
418
            return this;
 
419
        }
 
420
        return Weeks.weeks(getValue() / divisor);
 
421
    }
 
422
 
 
423
    //-----------------------------------------------------------------------
 
424
    /**
 
425
     * Returns a new instance with the weeks value negated.
 
426
     *
 
427
     * @return the new period with a negated value
 
428
     * @throws ArithmeticException if the result overflows an int
 
429
     */
 
430
    public Weeks negated() {
 
431
        return Weeks.weeks(FieldUtils.safeNegate(getValue()));
 
432
    }
 
433
 
 
434
    //-----------------------------------------------------------------------
 
435
    /**
 
436
     * Is this weeks instance greater than the specified number of weeks.
 
437
     *
 
438
     * @param other  the other period, null means zero
 
439
     * @return true if this weeks instance is greater than the specified one
 
440
     */
 
441
    public boolean isGreaterThan(Weeks other) {
 
442
        if (other == null) {
 
443
            return getValue() > 0;
 
444
        }
 
445
        return getValue() > other.getValue();
 
446
    }
 
447
 
 
448
    /**
 
449
     * Is this weeks instance less than the specified number of weeks.
 
450
     *
 
451
     * @param other  the other period, null means zero
 
452
     * @return true if this weeks instance is less than the specified one
 
453
     */
 
454
    public boolean isLessThan(Weeks other) {
 
455
        if (other == null) {
 
456
            return getValue() < 0;
 
457
        }
 
458
        return getValue() < other.getValue();
 
459
    }
 
460
 
 
461
    //-----------------------------------------------------------------------
 
462
    /**
 
463
     * Gets this instance as a String in the ISO8601 duration format.
 
464
     * <p>
 
465
     * For example, "P4W" represents 4 weeks.
 
466
     *
 
467
     * @return the value as an ISO8601 string
 
468
     */
 
469
    public String toString() {
 
470
        return "P" + String.valueOf(getValue()) + "W";
 
471
    }
 
472
 
 
473
}