BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlt_timetzformatter.h
Go to the documentation of this file.
1/// @file bdlt_timetzformatter.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlt_timetzformatter.h -*-C++-*-
8#ifndef INCLUDED_BDLT_TIMETZFORMATTER
9#define INCLUDED_BDLT_TIMETZFORMATTER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlt_timetzformatter bdlt_timetzformatter
15/// @brief Provide `bsl::formatter` specialization for `bdlt::TimeTz`.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlt
19/// @{
20/// @addtogroup bdlt_timetzformatter
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlt_timetzformatter-purpose"> Purpose</a>
25/// * <a href="#bdlt_timetzformatter-classes"> Classes </a>
26/// * <a href="#bdlt_timetzformatter-description"> Description </a>
27///
28/// # Purpose {#bdlt_timetzformatter-purpose}
29/// Provide `bsl::formatter` specialization for `bdlt::TimeTz`.
30///
31/// # Classes {#bdlt_timetzformatter-classes}
32///
33/// - bdlt::TimeTzFormatter: timetz formatter for `bslfmt` framework
34/// - bsl::formatter<bdlt::TimeTz, t_CHAR>: specialization
35///
36/// @see bdlt_timetz, bdlt_timeformatter, bslfmt_formatter
37///
38/// # Description {#bdlt_timetzformatter-description}
39/// This component provides `bdlt::TimeTzFormatter` and a
40/// specialization of `bsl::formatter` that allow `bsl::format` to output
41/// values of `bdlt::TimeTz`.
42///
43/// The formatter interprets the following modifiers:
44/// - ',' (comma) - the decimal point when displaying seconds is shown as a
45/// comma rather than a period.
46/// - 'Z' - if the offset is zero, output the time zone as 'Z', otherwise output
47/// it normally.
48/// - ':' (colon) - always print a colon between hours and minutes
49/// - '_' (underscore) - never print a colon between hours and minutes
50/// Note that it is an error for both ':' and '_' to be specified at the same
51/// time.
52///
53/// The formatter supports various time format specifiers including:
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/// all the above give figures relative to `bdlt::TimeTz::localTime()`.
60/// - Offset: 'z' (time zone, 2 digit hour, 2 digit minutes)
61/// - Composite: 'T' (`localTime()` in default format), "{}" (time in default
62/// format with time zone), 'i' (time in ISO 8601 format with time zone)
63/// @}
64/** @} */
65/** @} */
66
67/** @addtogroup bdl
68 * @{
69 */
70/** @addtogroup bdlt
71 * @{
72 */
73/** @addtogroup bdlt_timetzformatter
74 * @{
75 */
76
77#include <bdlscm_version.h>
78
79#include <bdlt_formatter.h>
80#include <bdlt_time.h>
81#include <bdlt_timeformatter.h>
82#include <bdlt_timetz.h>
84
85#include <bsl_iosfwd.h>
86#include <bsl_string_view.h>
87
88
89namespace bdlt {
90
91class TimeTzFormatter_Cache;
92
93 // =====================
94 // class TimeTzFormatter
95 // =====================
96
97/// This `class` provides a specifier formatter for printing `TimeTz` objects.
98///
99/// See @ref bdlt_timetzformatter
100template <class t_CHAR>
102 // PRIVATE TYPES
103 typedef TimeFormatter<t_CHAR> Time_Formatter;
104 typedef TimeZoneFormatter<t_CHAR> TimeZone_Formatter;
107
108 enum {
109 k_HOUR_WIDTH = 2,
110 k_AMPM_WIDTH = 2,
111 k_MINUTE_WIDTH = 2,
112 k_SECOND_WIDTH = 2,
113 k_COLON_WIDTH = 1,
114 k_DEFAULT_PRECISION = 6,
115 k_DEFAULT_ISO8601_PRECISION = 3 };
116
117 // DATA
118 Time_Formatter d_timeFormatter;
119 TimeZone_Formatter d_timeZoneFormatter;
120
121 public:
122 // CREATORS
123
124 /// Create an object in its default initial state.
127
128 // MANIPULATORS
129
130 /// Parse a time that will be formatted in default mode.
132
133 /// Parse a time that will be formatted in Iso8601 mode.
135
136 /// Examine the first character of the specified `*specInOut` and if it is
137 /// recognized as a modifier by this object, update this object's state to
138 /// reflect it and pop it off the front of `*specInOut` and return `true`,
139 /// and if not, return `false` with no modification to `*specInOut`.
141
142 /// If the first character of the specified `*specInOut` is recognized by
143 /// this specifier formatter, parse it, remove it from `*specInOut`, and
144 /// return `true`, otherwise return `false` with no modification to `*specInOut`.
145 ///
146 /// \pre The behavior is undefined if `*specInOut` is empty.
148 bool parseNextSpecifier(StringView *specInOut);
149
150 /// Read post-processed fields from the specified `spec` that are relevant
151 /// to this specifier formatter.
153
154 // ACCESSORS
155
156 /// Return the `bslfmt::FormatSpecificationParser::Sections` flags that
157 /// apply to this value type.
159
160 /// Return the anticipated width of output given all the `parse*` calls
161 /// that have been happened thus far and the specified `value`.
162 int totalWidth(const FormatCache& value) const;
163
164 /// If the first character of the specified `*specInOut` is recognized by
165 /// this specifier formatter, use it to format the specified `value` to
166 /// `*outIt`, remove the character from `*specInOut`, and return `true`,
167 /// otherwise return `false` with no modification to `*specInOut`.
168 template <class t_ITERATOR>
169 bool formatNextSpecifier(StringView *specInOut,
170 t_ITERATOR *outIt,
171 const FormatCache& value) const;
172
173 /// Format the specified `value` to the specified `out` using the default
174 /// format and return `out`.
175 template <class t_ITERATOR>
176 t_ITERATOR formatDefault(t_ITERATOR out, const FormatCache& value) const;
177
178 /// Format the specified `value` to the specified `out` using the Iso8601
179 /// format and return `out`.
180 template <class t_ITERATOR>
181 t_ITERATOR formatIso8601(t_ITERATOR out, const FormatCache& value) const;
182};
183
184 // ===========================
185 // class TimeTzFormatter_Cache
186 // ===========================
187
188/// This `class` facilitates faster access to a `TimeTz` object during printing
189/// by batching access to several fields in a single call during construction
190/// and caching them for quick access later.
191///
192/// See @ref bdlt_timetzformatter
194 // DATA
195 TimeFormatter_Cache d_timeFormatCache;
196 int d_offset;
197
198 public:
199 // CREATORS
200
201 /// Populate the time format cache with the time portion of the specified
202 /// `value` and cache the timezone offset.
203 TimeTzFormatter_Cache(const Time& localTime, int offset);
204
205 // ACCESSORS
206
207 /// Return the time format cache.
208 const TimeFormatter_Cache& time() const;
209
210 /// Return the offset.
211 int offset() const;
212};
213
214// ============================================================================
215// INLINE FUNCTION DEFINITIONS
216// ============================================================================
217
218 // ---------------------
219 // class TimeTzFormatter
220 // ---------------------
221
222// CREATORS
223template <class t_CHAR>
226: d_timeFormatter()
227, d_timeZoneFormatter()
228{}
229
230// MANIPULATORS
231template <class t_CHAR>
234{
235 d_timeFormatter. parseDefault();
236 d_timeZoneFormatter.parseDefault();
237}
238
239template <class t_CHAR>
242{
243 d_timeFormatter. parseIso8601();
244 d_timeZoneFormatter.parseIso8601();
245}
246
247template <class t_CHAR>
250{
251 return d_timeFormatter. parseNextModifier(specInOut) ||
252 d_timeZoneFormatter.parseNextModifier(specInOut);
253}
254
255template <class t_CHAR>
258{
259 BSLS_ASSERT(!specInOut->empty());
260
261 if (t_CHAR('i') == specInOut->front()) {
262 d_timeFormatter. parseIso8601();
263 d_timeZoneFormatter.parseIso8601();
264 specInOut->remove_prefix(1);
265
266 return true; // RETURN
267 }
268
269 return d_timeFormatter. parseNextSpecifier(specInOut) ||
270 d_timeZoneFormatter.parseNextSpecifier(specInOut);
271}
272
273template <class t_CHAR>
274inline
277{
278 d_timeFormatter. postprocess(spec);
279 d_timeZoneFormatter.postprocess(spec);
280}
281
282// ACCESSORS
283template <class t_CHAR>
286{
287 return d_timeFormatter.extraSections() |
288 d_timeZoneFormatter.extraSections();
289}
290
291template <class t_CHAR>
292inline
294{
295 return d_timeFormatter.totalWidth(value.time()) +
296 d_timeZoneFormatter.totalWidth(value.offset());
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_timeFormatter. formatNextSpecifier(specInOut,
317 outIt,
318 value.time()) ||
319 d_timeZoneFormatter.formatNextSpecifier(specInOut,
320 outIt,
321 value.offset());
322}
323
324template <class t_CHAR>
325template <class t_ITERATOR>
326inline
328 t_ITERATOR out, const FormatCache& value) const
329{
330 out = d_timeFormatter. formatDefault(out, value.time());
331 return d_timeZoneFormatter.formatDefault(out, value.offset());
332}
333
334template <class t_CHAR>
335template <class t_ITERATOR>
336inline
338 t_ITERATOR out, const FormatCache& value) const
339{
340 out = d_timeFormatter. formatIso8601(out, value.time());
341 return d_timeZoneFormatter.formatIso8601(out, value.offset());
342}
343
344 // ---------------------------
345 // class TimeTzFormatter_Cache
346 // ---------------------------
347
348// CREATORS
349inline
351: d_timeFormatCache(localTime)
352, d_offset(offset)
353{}
354
355// ACCESSORS
356inline
358{
359 return d_timeFormatCache;
360}
361
362inline
364{
365 return d_offset;
366}
367
368} // close package namespace
369
370
371namespace bsl {
372
373/// This type implements the formatter logic specific for `TimeTz` objects.
374template <class t_CHAR>
375class formatter<BloombergLP::bdlt::TimeTz, t_CHAR> {
376 // PRIVATE TYPES
377 typedef BloombergLP::bdlt::TimeTz TimeTz;
378 typedef BloombergLP::bdlt::TimeTzFormatter_Cache FormatCache;
379 typedef BloombergLP::bdlt::Formatter<
380 BloombergLP::bdlt::TimeTzFormatter, t_CHAR> Formatter;
381
382 // DATA
383 Formatter d_formatter;
384
385 public:
386 /// Parse and validate the specification string stored in the specified
387 /// `parseContext`. Return an end iterator of the parsed range. Throw
388 /// `bsl::format_error`, in the event of failure.
389 template <class t_PARSE_CONTEXT>
390 BSLS_KEYWORD_CONSTEXPR_CPP20 typename t_PARSE_CONTEXT::iterator parse(
391 t_PARSE_CONTEXT& context)
392 {
393 return d_formatter.parse(context);
394 }
395
396 /// Format the value in the specified `value` parameter according to the
397 /// specification stored as a result of a previous call to the `parse`
398 /// method, and write the result to the iterator accessed by calling the
399 /// `out()` method on the specified `formatContext` parameter. Return an
400 /// end iterator of the output range.
401 template <class t_FORMAT_CONTEXT>
402 typename t_FORMAT_CONTEXT::iterator format(
403 const TimeTz& value,
404 t_FORMAT_CONTEXT& formatContext) const
405 {
406 const FormatCache formatCache(value.localTime(), value.offset());
407 return d_formatter.format(formatCache, formatContext);
408 }
409};
410
411} // close namespace bsl
412
413#endif
414
415// ----------------------------------------------------------------------------
416// Copyright 2026 Bloomberg Finance L.P.
417//
418// Licensed under the Apache License, Version 2.0 (the "License");
419// you may not use this file except in compliance with the License.
420// You may obtain a copy of the License at
421//
422// http://www.apache.org/licenses/LICENSE-2.0
423//
424// Unless required by applicable law or agreed to in writing, software
425// distributed under the License is distributed on an "AS IS" BASIS,
426// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
427// See the License for the specific language governing permissions and
428// limitations under the License.
429// ----------------------------- END-OF-FILE ----------------------------------
430
431/** @} */
432/** @} */
433/** @} */
Definition bdlt_timeformatter.h:234
Definition bdlt_timeformatter.h:94
Definition bdlt_timetzformatter.h:193
const TimeFormatter_Cache & time() const
Return the time format cache.
Definition bdlt_timetzformatter.h:357
TimeTzFormatter_Cache(const Time &localTime, int offset)
Definition bdlt_timetzformatter.h:350
int offset() const
Return the offset.
Definition bdlt_timetzformatter.h:363
Definition bdlt_timetzformatter.h:101
BSLS_KEYWORD_CONSTEXPR_CPP20 void parseIso8601()
Parse a time that will be formatted in Iso8601 mode.
Definition bdlt_timetzformatter.h:241
int totalWidth(const FormatCache &value) const
Definition bdlt_timetzformatter.h:293
t_ITERATOR formatIso8601(t_ITERATOR out, const FormatCache &value) const
Definition bdlt_timetzformatter.h:337
bool formatNextSpecifier(StringView *specInOut, t_ITERATOR *outIt, const FormatCache &value) const
Definition bdlt_timetzformatter.h:302
BSLS_KEYWORD_CONSTEXPR_CPP20 TimeTzFormatter()
Create an object in its default initial state.
Definition bdlt_timetzformatter.h:225
BSLS_KEYWORD_CONSTEXPR_CPP20 int extraSections() const
Definition bdlt_timetzformatter.h:285
BSLS_KEYWORD_CONSTEXPR_CPP20 bool parseNextModifier(StringView *specInOut)
Definition bdlt_timetzformatter.h:249
BSLS_KEYWORD_CONSTEXPR_CPP20 void parseDefault()
Parse a time that will be formatted in default mode.
Definition bdlt_timetzformatter.h:233
t_ITERATOR formatDefault(t_ITERATOR out, const FormatCache &value) const
Definition bdlt_timetzformatter.h:327
BSLS_KEYWORD_CONSTEXPR_CPP20 bool parseNextSpecifier(StringView *specInOut)
Definition bdlt_timetzformatter.h:257
void postprocess(const bslfmt::FormatSpecificationParser< t_CHAR > &spec)
Definition bdlt_timetzformatter.h:275
Definition bdlt_timetz.h:190
Definition bdlt_timezoneformatter.h:89
Definition bdlt_time.h:195
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
BSLS_KEYWORD_CONSTEXPR_CPP20 t_PARSE_CONTEXT::iterator parse(t_PARSE_CONTEXT &context)
Definition bdlt_timetzformatter.h:390
t_FORMAT_CONTEXT::iterator format(const TimeTz &value, t_FORMAT_CONTEXT &formatContext) const
Definition bdlt_timetzformatter.h:402
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