BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlt_datetimeformatter.h
Go to the documentation of this file.
1/// @file bdlt_datetimeformatter.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlt_datetimeformatter.h -*-C++-*-
8#ifndef INCLUDED_BDLT_DATETIMEFORMATTER
9#define INCLUDED_BDLT_DATETIMEFORMATTER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlt_datetimeformatter bdlt_datetimeformatter
15/// @brief Provide `bsl::formatter` specialization for `bdlt::Datetime`.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlt
19/// @{
20/// @addtogroup bdlt_datetimeformatter
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlt_datetimeformatter-purpose"> Purpose</a>
25/// * <a href="#bdlt_datetimeformatter-classes"> Classes </a>
26/// * <a href="#bdlt_datetimeformatter-description"> Description </a>
27///
28/// # Purpose {#bdlt_datetimeformatter-purpose}
29/// Provide `bsl::formatter` specialization for `bdlt::Datetime`.
30///
31/// # Classes {#bdlt_datetimeformatter-classes}
32///
33/// - bdlt::DatetimeFormatter: datetime formatter for `bslfmt`
34/// - bsl::formatter<bdlt::Datetime, t_CHAR>: specialization
35///
36/// @see bdlt_datetime, bdlt_dateformatter,
37/// bdlt_timeformatter, bslfmt_formatter
38///
39/// # Description {#bdlt_datetimeformatter-description}
40/// This component provides `bdlt::DatetimeFormatter` and a
41/// specialization of `bsl::formatter` that allow `bsl::format` to output
42/// values of `bdlt::Datetime`.
43///
44/// The formatter interprets the following modifier:
45/// - ',' (comma) - the decimal point when displaying seconds is shown as a
46/// comma rather than a period.
47///
48/// The formatter supports various date and format specifiers including:
49/// - Year: 'Y' (4-digit), 'y' (2-digit), 'C' (century)
50/// - Month: 'm' (numeric), 'b'/'h' (abbreviated name)
51/// - Day: 'd' (zero-padded), 'e' (space-padded)
52/// - Day of week: 'a' (abbreviated name), 'u'/'w' (numeric)
53/// - Day of year: 'j' (numeric)
54/// - Hour: 'H' (2 digit) "00" - "24"
55/// - Hour: 'I' (2 digit) "01" - "12"
56/// - AM/PM: 'p' - "AM" or "PM"
57/// - Minute: 'M' (2 digits) "00" - "59"
58/// - Second: 'S' (2 digits) "00" - "59"
59/// - Composite: 'T' (time in default format), 'D' (date in default format),
60/// 'F' (date in ISO 8601 format)
61/// - Composite: "{}" (`Datetime` in default format), or 'i' (`Datetime` in
62/// ISO 8601 format)
63/// @}
64/** @} */
65/** @} */
66
67/** @addtogroup bdl
68 * @{
69 */
70/** @addtogroup bdlt
71 * @{
72 */
73/** @addtogroup bdlt_datetimeformatter
74 * @{
75 */
76
77#include <bdlscm_version.h>
78
79#include <bdlt_date.h>
80#include <bdlt_dateformatter.h>
81#include <bdlt_datetime.h>
82#include <bdlt_formatter.h>
83#include <bdlt_timeformatter.h>
84
86
87#include <bsls_exceptionutil.h>
88
89#include <bsl_iosfwd.h>
90#include <bsl_string_view.h>
91
92
93namespace bdlt {
94
95class DatetimeFormatter_Cache;
96
97 // =======================
98 // class DatetimeFormatter
99 // =======================
100
101/// This `class` provides a specifier formatter for printing `Datetime`
102/// objects.
103///
104/// See @ref bdlt_datetimeformatter
105template <class t_CHAR>
109
110 // DATA
111 int d_fixedWidth;
112
113 DateFormatter<t_CHAR> d_dateFormatter;
114 // Formatter for date specifiers.
115
116 TimeFormatter<t_CHAR> d_timeFormatter;
117 // Formatter for time specifiers.
118
119 public:
120 // CREATORS
121
122 /// Create an object in its default initial state.
125
126 // MANIPULATORS
127
128 /// Parse a date time that will be formatted in default mode.
130
131 /// Parse a date time that will be formatted in Iso8601 mode.
133
134 /// Examine the first character of the specified `*specInOut` and if it is
135 /// recognized as a modifier by this object, update this object's state to
136 /// reflect it and pop it off the front of `*specInOut` and return `true`,
137 /// and if not, return `false` with no modification to `*specInOut`.
139
140 /// If the first character of the specified `*specInOut` is recognized by
141 /// this specifier formatter, parse it, remove it from `*specInOut`, and
142 /// return `true`, otherwise return `false` with no modification to `*specInOut`.
143 ///
144 /// \pre The behavior is undefined if `*specInOut` is empty.
146 bool parseNextSpecifier(StringView *specInOut);
147
148 /// Read post-processed fields from the specified `spec` that are relevant
149 /// to this specifier formatter.
151
152 // ACCESSORS
153
154 /// Return the `bslfmt::FormatSpecificationParser::Sections` flags that
155 /// apply to this value type.
157
158 /// Return the anticipated width of output given all the `parse*` calls
159 /// that have been happened thus far and the specified `value`.
160 int totalWidth(const FormatCache& value) const;
161
162 /// If the first character of the specified `*specInOut` is recognized by
163 /// this specifier formatter, use it to format the specified `value` to
164 /// `*outIt`, remove the character from `*specInOut`, and return `true`,
165 /// otherwise return `false` with no modification to `*specInOut`.
166 template <class t_ITERATOR>
167 bool formatNextSpecifier(StringView *specInOut,
168 t_ITERATOR *outIt,
169 const FormatCache& value) const;
170
171 /// Format the specified `value` to the specified `out` using the default
172 /// format and return `out`.
173 template <class t_ITERATOR>
174 t_ITERATOR formatDefault(t_ITERATOR out, const FormatCache& value) const;
175
176 /// Format the specified `value` to the specified `out` using the Iso8601
177 /// format and return `out`.
178 template <class t_ITERATOR>
179 t_ITERATOR formatIso8601(t_ITERATOR out, const FormatCache& value) const;
180};
181
182 // =============================
183 // class DatetimeFormatter_Cache
184 // =============================
185
186/// This `class` facilitates faster access to a `Datetime` object during
187/// printing by batching access to several fields per call during construction
188/// and caching them for quick access later.
189///
190/// See @ref bdlt_datetimeformatter
192 // DATA
193 DateFormatter_Cache d_dateFormatCache;
194 TimeFormatter_Cache d_timeFormatCache;
195
196 public:
197 // CREATORS
198
199 /// Create a format cache initialized with the specified `value`.
200 explicit DatetimeFormatter_Cache(const Datetime& value);
201
202 // ACCESSORS
203
204 /// Return the date format cache held by this object.
205 const DateFormatter_Cache& date() const;
206
207 /// Return the time format cache held by this object.
208 const TimeFormatter_Cache& time() const;
209};
210
211// ============================================================================
212// INLINE FUNCTION DEFINITIONS
213// ============================================================================
214
215 // -----------------------
216 // class DatetimeFormatter
217 // -----------------------
218
219// CREATORS
220template <class t_CHAR>
223: d_fixedWidth(0)
224, d_dateFormatter()
225, d_timeFormatter()
226{}
227
228// MANIPULATORS
229template <class t_CHAR>
232{
233 d_dateFormatter.parseDefault();
234 ++d_fixedWidth; // For '_' between date and time
235 d_timeFormatter.parseDefault();
236}
237
238template <class t_CHAR>
241{
242 d_dateFormatter.parseIso8601();
243 ++d_fixedWidth; // For 'T' between date and time
244 d_timeFormatter.parseIso8601();
245}
246
247template <class t_CHAR>
250{
251 return d_dateFormatter.parseNextModifier(specInOut) ||
252 d_timeFormatter.parseNextModifier(specInOut);
253}
254
255template <class t_CHAR>
258{
259 BSLS_ASSERT(!specInOut->empty());
260
261 if (t_CHAR('i') == specInOut->front()) {
262 // Intercept iso format
263
264 parseIso8601();
265 specInOut->remove_prefix(1);
266 return true; // RETURN
267 }
268
269 return d_dateFormatter.parseNextSpecifier(specInOut) ||
270 d_timeFormatter.parseNextSpecifier(specInOut);
271}
272
273template <class t_CHAR>
274inline
277{
278 d_dateFormatter.postprocess(spec);
279 d_timeFormatter.postprocess(spec);
280}
281
282// ACCESSORS
283template <class t_CHAR>
286{
287 return d_dateFormatter.extraSections() |
288 d_timeFormatter.extraSections();
289}
290
291template <class t_CHAR>
292inline
294{
295 return d_fixedWidth + d_dateFormatter.totalWidth(value.date()) +
296 d_timeFormatter.totalWidth(value.time());
297}
298
299template <class t_CHAR>
300template <class t_ITERATOR>
301inline
303 StringView *specInOut,
304 t_ITERATOR *outIt,
305 const FormatCache& value) const
306{
307 BSLS_ASSERT_SAFE(!specInOut->empty());
308
309 if (t_CHAR('i') == specInOut->front()) {
310 *outIt = formatIso8601(*outIt, value);
311 specInOut->remove_prefix(1);
312
313 return true; // RETURN
314 }
315
316 return d_dateFormatter.formatNextSpecifier(specInOut, outIt, value.date())
317 || d_timeFormatter.formatNextSpecifier(specInOut, outIt, value.time());
318}
319
320template <class t_CHAR>
321template <class t_ITERATOR>
322inline
324 t_ITERATOR out, const FormatCache& value) const
325{
326 out = d_dateFormatter.formatDefault(out, value.date());
327 *out++ = t_CHAR('_');
328 return d_timeFormatter.formatDefault(out, value.time());
329}
330
331template <class t_CHAR>
332template <class t_ITERATOR>
333inline
335 t_ITERATOR out, const FormatCache& value) const
336{
337 out = d_dateFormatter.formatIso8601(out, value.date());
338 *out++ = t_CHAR('T');
339 return d_timeFormatter.formatIso8601(out, value.time());
340}
341
342 // -----------------------------
343 // class DatetimeFormatter_Cache
344 // -----------------------------
345
346// CREATORS
347inline
349: d_dateFormatCache(value.date())
350, d_timeFormatCache(value.time())
351{}
352
353// ACCESSORS
354
355inline
357{
358 return d_dateFormatCache;
359}
360
361inline
363{
364 return d_timeFormatCache;
365}
366
367} // close package namespace
368
369
370namespace bsl {
371
372/// This type implements the formatter logic specific for `Datetime` objects.
373template <class t_CHAR>
374class formatter<BloombergLP::bdlt::Datetime, t_CHAR> {
375 // PRIVATE TYPES
376 typedef BloombergLP::bdlt::Datetime Datetime;
377 typedef BloombergLP::bdlt::DatetimeFormatter_Cache FormatCache;
378 typedef BloombergLP::bdlt::Formatter<
379 BloombergLP::bdlt::DatetimeFormatter, t_CHAR> Formatter;
380
381 // DATA
382 Formatter d_formatter;
383
384 public:
385 /// Parse and validate the specification string stored in the specified
386 /// `parseContext`. Return an end iterator of the parsed range. Throw
387 /// `bsl::format_error`, in the event of failure.
388 template <class t_PARSE_CONTEXT>
389 BSLS_KEYWORD_CONSTEXPR_CPP20 typename t_PARSE_CONTEXT::iterator parse(
390 t_PARSE_CONTEXT& context)
391 {
392 return d_formatter.parse(context);
393 }
394
395 /// Format the value in the specified `value` parameter according to the
396 /// specification stored as a result of a previous call to the `parse`
397 /// method, and write the result to the iterator accessed by calling the
398 /// `out()` method on the specified `formatContext` parameter. Return an
399 /// end iterator of the output range.
400 template <class t_FORMAT_CONTEXT>
401 typename t_FORMAT_CONTEXT::iterator format(
402 const Datetime& value,
403 t_FORMAT_CONTEXT& formatContext) const
404 {
405 return d_formatter.format(FormatCache(value), formatContext);
406 }
407};
408
409} // close namespace bsl
410
411#endif
412
413// ----------------------------------------------------------------------------
414// Copyright 2026 Bloomberg Finance L.P.
415//
416// Licensed under the Apache License, Version 2.0 (the "License");
417// you may not use this file except in compliance with the License.
418// You may obtain a copy of the License at
419//
420// http://www.apache.org/licenses/LICENSE-2.0
421//
422// Unless required by applicable law or agreed to in writing, software
423// distributed under the License is distributed on an "AS IS" BASIS,
424// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
425// See the License for the specific language governing permissions and
426// limitations under the License.
427// ----------------------------- END-OF-FILE ----------------------------------
428
429/** @} */
430/** @} */
431/** @} */
Definition bdlt_dateformatter.h:224
Definition bdlt_dateformatter.h:94
Definition bdlt_datetimeformatter.h:191
const TimeFormatter_Cache & time() const
Return the time format cache held by this object.
Definition bdlt_datetimeformatter.h:362
DatetimeFormatter_Cache(const Datetime &value)
Create a format cache initialized with the specified value.
Definition bdlt_datetimeformatter.h:348
const DateFormatter_Cache & date() const
Return the date format cache held by this object.
Definition bdlt_datetimeformatter.h:356
Definition bdlt_datetimeformatter.h:106
void postprocess(const bslfmt::FormatSpecificationParser< t_CHAR > &spec)
Definition bdlt_datetimeformatter.h:275
BSLS_KEYWORD_CONSTEXPR_CPP20 bool parseNextSpecifier(StringView *specInOut)
Definition bdlt_datetimeformatter.h:257
BSLS_KEYWORD_CONSTEXPR_CPP20 DatetimeFormatter()
Create an object in its default initial state.
Definition bdlt_datetimeformatter.h:222
bool formatNextSpecifier(StringView *specInOut, t_ITERATOR *outIt, const FormatCache &value) const
Definition bdlt_datetimeformatter.h:302
t_ITERATOR formatIso8601(t_ITERATOR out, const FormatCache &value) const
Definition bdlt_datetimeformatter.h:334
int totalWidth(const FormatCache &value) const
Definition bdlt_datetimeformatter.h:293
BSLS_KEYWORD_CONSTEXPR_CPP20 void parseDefault()
Parse a date time that will be formatted in default mode.
Definition bdlt_datetimeformatter.h:231
BSLS_KEYWORD_CONSTEXPR_CPP20 int extraSections() const
Definition bdlt_datetimeformatter.h:285
BSLS_KEYWORD_CONSTEXPR_CPP20 bool parseNextModifier(StringView *specInOut)
Definition bdlt_datetimeformatter.h:249
t_ITERATOR formatDefault(t_ITERATOR out, const FormatCache &value) const
Definition bdlt_datetimeformatter.h:323
BSLS_KEYWORD_CONSTEXPR_CPP20 void parseIso8601()
Parse a date time that will be formatted in Iso8601 mode.
Definition bdlt_datetimeformatter.h:240
Definition bdlt_datetime.h:330
Definition bdlt_timeformatter.h:234
Definition bdlt_timeformatter.h:94
Definition bslstl_stringview.h:471
BSLS_KEYWORD_CONSTEXPR_CPP14 const_reference front() const
Definition bslstl_stringview.h:1966
BSLS_KEYWORD_CONSTEXPR_CPP14 void remove_prefix(size_type numChars)
Definition bslstl_stringview.h:1800
BSLS_KEYWORD_CONSTEXPR bool empty() const BSLS_KEYWORD_NOEXCEPT
Return true if this view has length 0, and false otherwise.
Definition bslstl_stringview.h:1931
t_FORMAT_CONTEXT::iterator format(const Datetime &value, t_FORMAT_CONTEXT &formatContext) const
Definition bdlt_datetimeformatter.h:401
BSLS_KEYWORD_CONSTEXPR_CPP20 t_PARSE_CONTEXT::iterator parse(t_PARSE_CONTEXT &context)
Definition bdlt_datetimeformatter.h:389
Definition bslfmt_formatspecificationparser.h:151
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_CONSTEXPR_CPP20
Definition bsls_keyword.h:645
Definition bbldc_basicisma30360.h:112
Definition bdlat_valuetypefunctions.h:939
Definition bslfmt_formatterbase.h:426