1 /*
2 * Copyright 2001-2005 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.format;
17
18 import java.util.Locale;
19 import java.util.ResourceBundle;
20 import java.util.concurrent.ConcurrentHashMap;
21 import java.util.concurrent.ConcurrentMap;
22
23 /**
24 * Factory that creates instances of PeriodFormatter.
25 * <p>
26 * Period formatting is performed by the {@link PeriodFormatter} class.
27 * Three classes provide factory methods to create formatters, and this is one.
28 * The others are {@link ISOPeriodFormat} and {@link PeriodFormatterBuilder}.
29 * <p>
30 * PeriodFormat is thread-safe and immutable, and the formatters it returns
31 * are as well.
32 *
33 * @author Brian S O'Neill
34 * @since 1.0
35 * @see ISOPeriodFormat
36 * @see PeriodFormatterBuilder
37 */
38 public class PeriodFormat {
39
40 /**
41 * The resource bundle name.
42 */
43 private static final String BUNDLE_NAME = "org.joda.time.format.messages";
44 /**
45 * The created formatters.
46 */
47 private static final ConcurrentMap<Locale, PeriodFormatter> FORMATTERS = new ConcurrentHashMap<Locale, PeriodFormatter>();
48
49 /**
50 * Constructor.
51 *
52 * @since 1.1 (previously private)
53 */
54 protected PeriodFormat() {
55 super();
56 }
57
58 //-----------------------------------------------------------------------
59 /**
60 * Gets the default formatter that outputs words in English.
61 * <p>
62 * This calls {@link #wordBased(Locale)} using a locale of {@code ENGLISH}.
63 *
64 * @return the formatter, not null
65 */
66 public static PeriodFormatter getDefault() {
67 return wordBased(Locale.ENGLISH);
68 }
69
70 /**
71 * Returns a word based formatter for the JDK default locale.
72 * <p>
73 * This calls {@link #wordBased(Locale)} using the {@link Locale#getDefault() default locale}.
74 *
75 * @return the formatter, not null
76 * @since 2.0
77 */
78 public static PeriodFormatter wordBased() {
79 return wordBased(Locale.getDefault());
80 }
81
82 /**
83 * Returns a word based formatter for the specified locale.
84 * <p>
85 * The words are configured in a resource bundle text file -
86 * {@code org.joda.time.format.messages}.
87 * This can be added to via the normal classpath resource bundle mechanisms.
88 * <p>
89 * Available languages are English, Danish, Dutch, French, German, Japanese, Portuguese, and Spanish.
90 *
91 * @return the formatter, not null
92 * @since 2.0
93 */
94 public static PeriodFormatter wordBased(Locale locale) {
95 PeriodFormatter pf = FORMATTERS.get(locale);
96 if (pf == null) {
97 ResourceBundle b = ResourceBundle.getBundle(BUNDLE_NAME, locale);
98 String[] variants = {
99 b.getString("PeriodFormat.space"), b.getString("PeriodFormat.comma"),
100 b.getString("PeriodFormat.commandand"), b.getString("PeriodFormat.commaspaceand")};
101 pf = new PeriodFormatterBuilder()
102 .appendYears()
103 .appendSuffix(b.getString("PeriodFormat.year"), b.getString("PeriodFormat.years"))
104 .appendSeparator(b.getString("PeriodFormat.commaspace"), b.getString("PeriodFormat.spaceandspace"), variants)
105 .appendMonths()
106 .appendSuffix(b.getString("PeriodFormat.month"), b.getString("PeriodFormat.months"))
107 .appendSeparator(b.getString("PeriodFormat.commaspace"), b.getString("PeriodFormat.spaceandspace"), variants)
108 .appendWeeks()
109 .appendSuffix(b.getString("PeriodFormat.week"), b.getString("PeriodFormat.weeks"))
110 .appendSeparator(b.getString("PeriodFormat.commaspace"), b.getString("PeriodFormat.spaceandspace"), variants)
111 .appendDays()
112 .appendSuffix(b.getString("PeriodFormat.day"), b.getString("PeriodFormat.days"))
113 .appendSeparator(b.getString("PeriodFormat.commaspace"), b.getString("PeriodFormat.spaceandspace"), variants)
114 .appendHours()
115 .appendSuffix(b.getString("PeriodFormat.hour"), b.getString("PeriodFormat.hours"))
116 .appendSeparator(b.getString("PeriodFormat.commaspace"), b.getString("PeriodFormat.spaceandspace"), variants)
117 .appendMinutes()
118 .appendSuffix(b.getString("PeriodFormat.minute"), b.getString("PeriodFormat.minutes"))
119 .appendSeparator(b.getString("PeriodFormat.commaspace"), b.getString("PeriodFormat.spaceandspace"), variants)
120 .appendSeconds()
121 .appendSuffix(b.getString("PeriodFormat.second"), b.getString("PeriodFormat.seconds"))
122 .appendSeparator(b.getString("PeriodFormat.commaspace"), b.getString("PeriodFormat.spaceandspace"), variants)
123 .appendMillis()
124 .appendSuffix(b.getString("PeriodFormat.millisecond"), b.getString("PeriodFormat.milliseconds"))
125 .toFormatter();
126 FORMATTERS.putIfAbsent(locale, pf);
127 }
128 return pf;
129 }
130
131 }