Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(249)

Side by Side Diff: content/renderer/date_time_formatter.cc

Issue 12191005: Move Android Date/Time parsing to the renderer (C++ and ICU) instead of the current parsing that ha… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed Review comments except renaming the file Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/renderer/date_time_formatter.h"
6
7 #include "base/string_util.h"
8 #include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h"
9 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDateTimeChooserPar ams.h"
10 #include "third_party/icu/public/i18n/unicode/smpdtfmt.h"
11
12
13 namespace content {
14
15 void DateTimeFormatter::CreatePatternMap() {
16
palmer 2013/02/05 19:57:51 Nit: Get rid of this blank line.
Miguel Garcia 2013/02/06 11:39:44 Done.
17 // Initialize all the UI elements with empty patterns,
18 // then fill in the ones that are actually date/time inputs and
19 // are implemented.
20 for (int i = 0 ; i <= ui::TEXT_INPUT_TYPE_MAX; ++i) {
21 patterns_[i] = "";
22 }
23 patterns_[ui::TEXT_INPUT_TYPE_DATE] = "yyyy-MM-dd";
24 patterns_[ui::TEXT_INPUT_TYPE_DATE_TIME] = "yyyy-MM-dd'T'HH:mm'Z'";
25 patterns_[ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL] = "yyyy-MM-dd'T'HH:mm";
26 patterns_[ui::TEXT_INPUT_TYPE_MONTH] = "yyyy-MM";
27 patterns_[ui::TEXT_INPUT_TYPE_TIME] = "HH:mm";
28 }
29
palmer 2013/02/05 19:57:51 Nit: Get rid of this blank line.
Miguel Garcia 2013/02/06 11:39:44 Done.
30
31 DateTimeFormatter::DateTimeFormatter(
32 const WebKit::WebDateTimeChooserParams& source)
33 : formatted_string_(source.currentValue.utf8()) {
34 CreatePatternMap();
35 ExtractType(source);
36 if (!ParseValues()) {
37 type_ = ui::TEXT_INPUT_TYPE_NONE;
38 ClearAll();
39 LOG(WARNING) << "Problems parsing input <" << formatted_string_ << ">";
40 }
41 }
42
43 DateTimeFormatter::DateTimeFormatter(
44 ui::TextInputType type,
45 int year, int month, int day, int hour, int minute, int second)
46 : type_(type),
47 year_(year),
48 month_(month),
49 day_(day),
50 hour_(hour),
51 minute_(minute),
52 second_(second) {
53 CreatePatternMap();
54 pattern_ = &patterns_[static_cast<ui::TextInputType>(type_)];
palmer 2013/02/05 19:57:51 Why do you cast it to the type that it already is?
Miguel Garcia 2013/02/06 11:39:44 Done, added a test as well to check this case.
55 std::string patt;
56 pattern_->toUTF8String(patt);
57 formatted_string_ = FormatString();
58 }
59
60 DateTimeFormatter::~DateTimeFormatter() {
61 }
62
63 int DateTimeFormatter::GetYear() const {
64 return year_;
65 }
66
67 int DateTimeFormatter::GetMonth() const {
68 return month_;
69 }
70
71 int DateTimeFormatter::GetDay() const {
72 return day_;
73 }
74
75 int DateTimeFormatter::GetHour() const {
76 return hour_;
77 }
78
79 int DateTimeFormatter::GetMinute() const {
80 return minute_;
81 }
82
83 int DateTimeFormatter::GetSecond() const {
84 return second_;
85 }
86
87 ui::TextInputType DateTimeFormatter::GetType() const {
88 return type_;
89 }
90
91 const std::string& DateTimeFormatter::GetFormattedValue() const {
92 return formatted_string_;
93 }
94
95 const std::string DateTimeFormatter::FormatString() const {
96 UErrorCode success = U_ZERO_ERROR;
97 if (year_ == 0 && month_ == 0 && day_ == 0 &&
98 hour_ == 0 && minute_ == 0 && second_ == 0) {
99 return "";
100 }
101
102 std::string result;
103 const icu::GregorianCalendar calendar(
104 year_, month_, day_, hour_, minute_, second_, success);
105 if (success <= U_ZERO_ERROR) {
106 UDate time = calendar.getTime(success);
107 icu::SimpleDateFormat formatter(*pattern_, success);
108 icu::UnicodeString formattedTime;
109 formatter.format(time, formattedTime, success);
110 formattedTime.toUTF8String(result);
111 if (success <= U_ZERO_ERROR)
112 return result;
113 }
114 LOG(WARNING) << "Calendar not created: error " << success;
115 return "";
116 }
117
118 void DateTimeFormatter::ExtractType(
119 const WebKit::WebDateTimeChooserParams& source) {
120 switch (source.type) {
121 case WebKit::WebDateTimeInputTypeDate:
122 type_ = ui::TEXT_INPUT_TYPE_DATE;
123 break;
124 case WebKit::WebDateTimeInputTypeDateTime:
125 type_ = ui::TEXT_INPUT_TYPE_DATE_TIME;
126 break;
127 case WebKit::WebDateTimeInputTypeDateTimeLocal:
128 type_ = ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL;
129 break;
130 case WebKit::WebDateTimeInputTypeMonth:
131 type_ = ui::TEXT_INPUT_TYPE_MONTH;
132 break;
133 case WebKit::WebDateTimeInputTypeTime:
134 type_ = ui::TEXT_INPUT_TYPE_TIME;
135 break;
136 case WebKit::WebDateTimeInputTypeWeek: // Not implemented
137 case WebKit::WebDateTimeInputTypeNone:
138 default:
139 type_ = ui::TEXT_INPUT_TYPE_NONE;
140 }
141 }
142
143 // Not all fields are defined in all configurations and ICU might store
144 // garbage if success <= U_ZERO_ERROR so the output is sanitized here.
145 int DateTimeFormatter::ExtractValue(
146 const icu::Calendar* calendar, UCalendarDateFields value) const {
147 UErrorCode success = U_ZERO_ERROR;
148 int result = calendar->get(value, success);
149 return (success <= U_ZERO_ERROR) ? result : 0;
150 }
151
152 bool DateTimeFormatter::ParseValues() {
153 if (type_ == ui::TEXT_INPUT_TYPE_NONE) {
154 ClearAll();
155 return false;
156 }
157
158 if (formatted_string_.empty()) {
159 ClearAll();
160 return true;
161 }
162
163 UErrorCode success = U_ZERO_ERROR;
164 icu::UnicodeString icu_value =
165 icu::UnicodeString::fromUTF8(formatted_string_);
166 if (type_ > 0 && type_ <= ui::TEXT_INPUT_TYPE_MAX) {
palmer 2013/02/05 19:57:51 Yes, exactly — do this check above in DateTimeForm
Miguel Garcia 2013/02/06 11:39:44 Done.
167 const icu::UnicodeString pattern = patterns_[type_];
168 icu::SimpleDateFormat formatter(pattern, success);
169 formatter.parse(icu_value, success);
170 if (success <= U_ZERO_ERROR) {
171 const icu::Calendar* cal = formatter.getCalendar();
172 year_ = ExtractValue(cal, UCAL_YEAR);
173 month_ = ExtractValue(cal, UCAL_MONTH);
174 day_ = ExtractValue(cal, UCAL_DATE);
175 hour_ = ExtractValue(cal, UCAL_HOUR_OF_DAY); // 24h format
176 minute_ = ExtractValue(cal, UCAL_MINUTE);
177 second_ = ExtractValue(cal, UCAL_SECOND);
178 }
179 }
180
181 return (success <= U_ZERO_ERROR);
182 }
183
184 void DateTimeFormatter::ClearAll() {
185 year_ = 0;
186 month_ = 0;
187 day_ = 0;
188 hour_ = 0;
189 minute_ = 0;
190 second_ = 0;
191 }
192
193 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698