1//
2// DateTimeFormatter.cpp
3//
4// Library: Foundation
5// Package: DateTime
6// Module: DateTimeFormatter
7//
8// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
9// and Contributors.
10//
11// SPDX-License-Identifier: BSL-1.0
12//
13
14
15#include "Poco/DateTimeFormatter.h"
16#include "Poco/DateTimeFormat.h"
17#include "Poco/Timestamp.h"
18#include "Poco/NumberFormatter.h"
19
20
21namespace Poco {
22
23
24void DateTimeFormatter::append(std::string& str, const LocalDateTime& dateTime, const std::string& fmt)
25{
26 DateTimeFormatter::append(str, dateTime._dateTime, fmt, dateTime.tzd());
27}
28
29
30void DateTimeFormatter::append(std::string& str, const DateTime& dateTime, const std::string& fmt, int timeZoneDifferential)
31{
32 std::string::const_iterator it = fmt.begin();
33 std::string::const_iterator end = fmt.end();
34 while (it != end)
35 {
36 if (*it == '%')
37 {
38 if (++it != end)
39 {
40 switch (*it)
41 {
42 case 'w': str.append(DateTimeFormat::WEEKDAY_NAMES[dateTime.dayOfWeek()], 0, 3); break;
43 case 'W': str.append(DateTimeFormat::WEEKDAY_NAMES[dateTime.dayOfWeek()]); break;
44 case 'b': str.append(DateTimeFormat::MONTH_NAMES[dateTime.month() - 1], 0, 3); break;
45 case 'B': str.append(DateTimeFormat::MONTH_NAMES[dateTime.month() - 1]); break;
46 case 'd': NumberFormatter::append0(str, dateTime.day(), 2); break;
47 case 'e': NumberFormatter::append(str, dateTime.day()); break;
48 case 'f': NumberFormatter::append(str, dateTime.day(), 2); break;
49 case 'm': NumberFormatter::append0(str, dateTime.month(), 2); break;
50 case 'n': NumberFormatter::append(str, dateTime.month()); break;
51 case 'o': NumberFormatter::append(str, dateTime.month(), 2); break;
52 case 'y': NumberFormatter::append0(str, dateTime.year() % 100, 2); break;
53 case 'Y': NumberFormatter::append0(str, dateTime.year(), 4); break;
54 case 'H': NumberFormatter::append0(str, dateTime.hour(), 2); break;
55 case 'h': NumberFormatter::append0(str, dateTime.hourAMPM(), 2); break;
56 case 'a': str.append(dateTime.isAM() ? "am" : "pm"); break;
57 case 'A': str.append(dateTime.isAM() ? "AM" : "PM"); break;
58 case 'M': NumberFormatter::append0(str, dateTime.minute(), 2); break;
59 case 'S': NumberFormatter::append0(str, dateTime.second(), 2); break;
60 case 's': NumberFormatter::append0(str, dateTime.second(), 2);
61 str += '.';
62 NumberFormatter::append0(str, dateTime.millisecond()*1000 + dateTime.microsecond(), 6);
63 break;
64 case 'i': NumberFormatter::append0(str, dateTime.millisecond(), 3); break;
65 case 'c': NumberFormatter::append(str, dateTime.millisecond()/100); break;
66 case 'F': NumberFormatter::append0(str, dateTime.millisecond()*1000 + dateTime.microsecond(), 6); break;
67 case 'z': tzdISO(str, timeZoneDifferential); break;
68 case 'Z': tzdRFC(str, timeZoneDifferential); break;
69 default: str += *it;
70 }
71 ++it;
72 }
73 }
74 else str += *it++;
75 }
76}
77
78
79void DateTimeFormatter::append(std::string& str, const Timespan& timespan, const std::string& fmt)
80{
81 std::string::const_iterator it = fmt.begin();
82 std::string::const_iterator end = fmt.end();
83 while (it != end)
84 {
85 if (*it == '%')
86 {
87 if (++it != end)
88 {
89 switch (*it)
90 {
91 case 'd': NumberFormatter::append(str, timespan.days()); break;
92 case 'H': NumberFormatter::append0(str, timespan.hours(), 2); break;
93 case 'h': NumberFormatter::append(str, timespan.totalHours()); break;
94 case 'M': NumberFormatter::append0(str, timespan.minutes(), 2); break;
95 case 'm': NumberFormatter::append(str, timespan.totalMinutes()); break;
96 case 'S': NumberFormatter::append0(str, timespan.seconds(), 2); break;
97 case 's': NumberFormatter::append(str, timespan.totalSeconds()); break;
98 case 'i': NumberFormatter::append0(str, timespan.milliseconds(), 3); break;
99 case 'c': NumberFormatter::append(str, timespan.milliseconds()/100); break;
100 case 'F': NumberFormatter::append0(str, timespan.milliseconds()*1000 + timespan.microseconds(), 6); break;
101 default: str += *it;
102 }
103 ++it;
104 }
105 }
106 else str += *it++;
107 }
108}
109
110
111void DateTimeFormatter::tzdISO(std::string& str, int timeZoneDifferential)
112{
113 if (timeZoneDifferential != UTC)
114 {
115 if (timeZoneDifferential >= 0)
116 {
117 str += '+';
118 NumberFormatter::append0(str, timeZoneDifferential/3600, 2);
119 str += ':';
120 NumberFormatter::append0(str, (timeZoneDifferential%3600)/60, 2);
121 }
122 else
123 {
124 str += '-';
125 NumberFormatter::append0(str, -timeZoneDifferential/3600, 2);
126 str += ':';
127 NumberFormatter::append0(str, (-timeZoneDifferential%3600)/60, 2);
128 }
129 }
130 else str += 'Z';
131}
132
133
134void DateTimeFormatter::tzdRFC(std::string& str, int timeZoneDifferential)
135{
136 if (timeZoneDifferential != UTC)
137 {
138 if (timeZoneDifferential >= 0)
139 {
140 str += '+';
141 NumberFormatter::append0(str, timeZoneDifferential/3600, 2);
142 NumberFormatter::append0(str, (timeZoneDifferential%3600)/60, 2);
143 }
144 else
145 {
146 str += '-';
147 NumberFormatter::append0(str, -timeZoneDifferential/3600, 2);
148 NumberFormatter::append0(str, (-timeZoneDifferential%3600)/60, 2);
149 }
150 }
151 else str += "GMT";
152}
153
154
155} // namespace Poco
156