• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

TAKETODAY / today-infrastructure / 19387509749

15 Nov 2025 09:04AM UTC coverage: 84.116% (-0.003%) from 84.119%
19387509749

push

github

web-flow
Java 25

Java 25

61360 of 78051 branches covered (78.62%)

Branch coverage included in aggregate %.

145107 of 167405 relevant lines covered (86.68%)

3.69 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.25
today-context/src/main/java/infra/format/datetime/standard/DateTimeFormatterFactory.java
1
/*
2
 * Copyright 2017 - 2025 the original author or authors.
3
 *
4
 * This program is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program. If not, see [https://www.gnu.org/licenses/]
16
 */
17

18
package infra.format.datetime.standard;
19

20
import org.jspecify.annotations.Nullable;
21

22
import java.time.format.DateTimeFormatter;
23
import java.time.format.FormatStyle;
24
import java.util.TimeZone;
25

26
import infra.format.annotation.DateTimeFormat.ISO;
27
import infra.lang.Assert;
28
import infra.util.StringUtils;
29

30
/**
31
 * Factory that creates a JSR-310 {@link DateTimeFormatter}.
32
 *
33
 * <p>Formatters will be created using the defined {@link #setPattern pattern},
34
 * {@link #setIso ISO}, and <code>xxxStyle</code> methods (considered in that order).
35
 *
36
 * @author Juergen Hoeller
37
 * @author Phillip Webb
38
 * @author Sam Brannen
39
 * @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
40
 * @see #createDateTimeFormatter()
41
 * @see #createDateTimeFormatter(DateTimeFormatter)
42
 * @see #setPattern
43
 * @see #setIso
44
 * @see #setDateStyle
45
 * @see #setTimeStyle
46
 * @see #setDateTimeStyle
47
 * @see DateTimeFormatterFactoryBean
48
 * @since 4.0
49
 */
50
public class DateTimeFormatterFactory {
51

52
  @Nullable
53
  private String pattern;
54

55
  @Nullable
56
  private ISO iso;
57

58
  @Nullable
59
  private FormatStyle dateStyle;
60

61
  @Nullable
62
  private FormatStyle timeStyle;
63

64
  @Nullable
65
  private TimeZone timeZone;
66

67
  /**
68
   * Create a new {@code DateTimeFormatterFactory} instance.
69
   */
70
  public DateTimeFormatterFactory() {
2✔
71
  }
1✔
72

73
  /**
74
   * Create a new {@code DateTimeFormatterFactory} instance.
75
   *
76
   * @param pattern the pattern to use to format date values
77
   */
78
  public DateTimeFormatterFactory(String pattern) {
2✔
79
    this.pattern = pattern;
3✔
80
  }
1✔
81

82
  /**
83
   * Set the pattern to use to format date values.
84
   *
85
   * @param pattern the format pattern
86
   */
87
  public void setPattern(String pattern) {
88
    this.pattern = pattern;
3✔
89
  }
1✔
90

91
  /**
92
   * Set the ISO format used to format date values.
93
   *
94
   * @param iso the ISO format
95
   */
96
  public void setIso(ISO iso) {
97
    this.iso = iso;
3✔
98
  }
1✔
99

100
  /**
101
   * Set the style to use for date types.
102
   */
103
  public void setDateStyle(FormatStyle dateStyle) {
104
    this.dateStyle = dateStyle;
3✔
105
  }
1✔
106

107
  /**
108
   * Set the style to use for time types.
109
   */
110
  public void setTimeStyle(FormatStyle timeStyle) {
111
    this.timeStyle = timeStyle;
3✔
112
  }
1✔
113

114
  /**
115
   * Set the style to use for date and time types.
116
   */
117
  public void setDateTimeStyle(FormatStyle dateTimeStyle) {
118
    this.dateStyle = dateTimeStyle;
3✔
119
    this.timeStyle = dateTimeStyle;
3✔
120
  }
1✔
121

122
  /**
123
   * Set the two characters to use to format date values.
124
   * <p>The first character is used for the date style; the second is for
125
   * the time style. Supported characters are:
126
   * <ul>
127
   * <li>'S' = Small</li>
128
   * <li>'M' = Medium</li>
129
   * <li>'L' = Long</li>
130
   * <li>'F' = Full</li>
131
   * <li>'-' = Omitted</li>
132
   * </ul>
133
   * <p>Note that JSR-310 natively favors {@link java.time.format.FormatStyle}
134
   * as used for {@link #setDateStyle}, {@link #setTimeStyle}, and
135
   * {@link #setDateTimeStyle}.
136
   *
137
   * @param style two characters from the set {"S", "M", "L", "F", "-"}
138
   */
139
  public void setStylePattern(String style) {
140
    Assert.isTrue(style.length() == 2, "Style pattern must consist of two characters");
8!
141
    this.dateStyle = convertStyleCharacter(style.charAt(0));
7✔
142
    this.timeStyle = convertStyleCharacter(style.charAt(1));
7✔
143
  }
1✔
144

145
  @Nullable
146
  private FormatStyle convertStyleCharacter(char c) {
147
    return switch (c) {
3!
148
      case 'S' -> FormatStyle.SHORT;
2✔
149
      case 'M' -> FormatStyle.MEDIUM;
2✔
150
      case 'L' -> FormatStyle.LONG;
2✔
151
      case 'F' -> FormatStyle.FULL;
×
152
      case '-' -> null;
2✔
153
      default -> throw new IllegalArgumentException("Invalid style character '" + c + "'");
×
154
    };
155
  }
156

157
  /**
158
   * Set the {@code TimeZone} to normalize the date values into, if any.
159
   *
160
   * @param timeZone the time zone
161
   */
162
  public void setTimeZone(TimeZone timeZone) {
163
    this.timeZone = timeZone;
3✔
164
  }
1✔
165

166
  /**
167
   * Create a new {@code DateTimeFormatter} using this factory.
168
   * <p>If no specific pattern or style has been defined,
169
   * {@link FormatStyle#MEDIUM medium date time format} will be used.
170
   *
171
   * @return a new date time formatter
172
   * @see #createDateTimeFormatter(DateTimeFormatter)
173
   */
174
  public DateTimeFormatter createDateTimeFormatter() {
175
    return createDateTimeFormatter(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM));
5✔
176
  }
177

178
  /**
179
   * Create a new {@code DateTimeFormatter} using this factory.
180
   * <p>If no specific pattern or style has been defined,
181
   * the supplied {@code fallbackFormatter} will be used.
182
   *
183
   * @param fallbackFormatter the fall-back formatter to use
184
   * when no specific factory properties have been set
185
   * @return a new date time formatter
186
   */
187
  public DateTimeFormatter createDateTimeFormatter(DateTimeFormatter fallbackFormatter) {
188
    DateTimeFormatter dateTimeFormatter = null;
2✔
189
    if (StringUtils.isNotEmpty(this.pattern)) {
4✔
190
      dateTimeFormatter = DateTimeFormatterUtils.createStrictDateTimeFormatter(this.pattern);
5✔
191
    }
192
    else if (this.iso != null && this.iso != ISO.NONE) {
7✔
193
      dateTimeFormatter = switch (this.iso) {
8!
194
        case DATE -> DateTimeFormatter.ISO_DATE;
2✔
195
        case TIME -> DateTimeFormatter.ISO_TIME;
2✔
196
        case DATE_TIME -> DateTimeFormatter.ISO_DATE_TIME;
2✔
197
        default -> throw new IllegalStateException("Unsupported ISO format: " + this.iso);
×
198
      };
199
    }
200
    else if (this.dateStyle != null && this.timeStyle != null) {
6✔
201
      dateTimeFormatter = DateTimeFormatter.ofLocalizedDateTime(this.dateStyle, this.timeStyle);
7✔
202
    }
203
    else if (this.dateStyle != null) {
3✔
204
      dateTimeFormatter = DateTimeFormatter.ofLocalizedDate(this.dateStyle);
5✔
205
    }
206
    else if (this.timeStyle != null) {
3✔
207
      dateTimeFormatter = DateTimeFormatter.ofLocalizedTime(this.timeStyle);
4✔
208
    }
209

210
    if (dateTimeFormatter != null && this.timeZone != null) {
5✔
211
      dateTimeFormatter = dateTimeFormatter.withZone(this.timeZone.toZoneId());
6✔
212
    }
213
    return (dateTimeFormatter != null ? dateTimeFormatter : fallbackFormatter);
6✔
214
  }
215

216
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc