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

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: 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 pattern_map_[ui::TEXT_INPUT_TYPE_DATE] = "yyyy-MM-dd";
17 pattern_map_[ui::TEXT_INPUT_TYPE_DATE_TIME] = "yyyy-MM-dd'T'HH:mm'Z'";
18 pattern_map_[ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL] = "yyyy-MM-dd'T'HH:mm";
19 pattern_map_[ui::TEXT_INPUT_TYPE_MONTH] = "yyyy-MM";
20 pattern_map_[ui::TEXT_INPUT_TYPE_TIME] = "HH:mm";
21
22 // Not implemented
23 pattern_map_[ui::TEXT_INPUT_TYPE_WEEK] = "";
24 pattern_map_[ui::TEXT_INPUT_TYPE_NONE] = "";
bulach 2013/02/05 11:54:56 nit: unindent this block, but chris suggestion is
Miguel Garcia 2013/02/05 17:44:40 Yeah I went ahead with that. On 2013/02/05 11:54:
25 }
26
27
28 DateTimeFormatter::DateTimeFormatter(
29 const WebKit::WebDateTimeChooserParams& source):
bulach 2013/02/05 11:54:56 nit: ":" goes on the next line
Miguel Garcia 2013/02/05 17:44:40 Done.
30 formatted_string_(source.currentValue.utf8()) {
31 CreatePatternMap();
32 ExtractType(source);
33 if (!ParseValues()) {
34 type_ = ui::TEXT_INPUT_TYPE_NONE;
35 ClearAll();
36 LOG(WARNING) << "Problems parsing input <" << formatted_string_ << ">";
37 }
38 }
39
40 DateTimeFormatter::DateTimeFormatter(
41 ui::TextInputType type,
42 int year, int month, int day, int hour, int minute, int second) :
bulach 2013/02/05 11:54:56 nit: ":" goes into the next line
Miguel Garcia 2013/02/05 17:44:40 Done.
43 type_(type),
44 year_(year),
45 month_(month),
46 day_(day),
47 hour_(hour),
48 minute_(minute),
49 second_(second) {
50 CreatePatternMap();
51 pattern_ = &pattern_map_[(ui::TextInputType) type_];
bulach 2013/02/05 11:54:56 nit: static_cast rather than c-style cast
Miguel Garcia 2013/02/05 17:44:40 Done.
52 formatted_string_ = FormatString();
53 }
54
55 DateTimeFormatter::~DateTimeFormatter() {
56 }
57
58 int DateTimeFormatter::GetYear() const {
59 return year_;
60 }
61
62 int DateTimeFormatter::GetMonth() const {
63 return month_;
64 }
65
66 int DateTimeFormatter::GetDay() const {
67 return day_;
68 }
69
70 int DateTimeFormatter::GetHour() const {
71 return hour_;
72 }
73
74 int DateTimeFormatter::GetMinute() const {
75 return minute_;
76 }
77
78 int DateTimeFormatter::GetSecond() const {
79 return second_;
80 }
81
82 ui::TextInputType DateTimeFormatter::GetType() {
palmer 2013/02/04 22:14:08 Efficiency: This can be const too, right?
Miguel Garcia 2013/02/05 17:44:40 right
83 return type_;
84 }
85
86 std::string DateTimeFormatter::GetFormattedValue() {
palmer 2013/02/04 22:14:08 Could also be const? Does it have to return a copy
Miguel Garcia 2013/02/05 17:44:40 Done.
87 return formatted_string_;
88 }
89
90 const std::string DateTimeFormatter::FormatString() const {
91 UErrorCode success = U_ZERO_ERROR;
92 if (year_ == 0 && month_ == 0 && day_ == 0 &&
93 hour_ == 0 && minute_ == 0 && second_ == 0) {
94 return "";
palmer 2013/02/04 22:14:08 But what if I want to actually represent New Year'
Miguel Garcia 2013/02/05 17:44:40 The spec prevents 0 based values so I think there
95 } else {
bulach 2013/02/05 11:54:56 nit: no need for else, could remove and unindent t
Miguel Garcia 2013/02/05 17:44:40 Done.
96 std::string result;
97 const icu::GregorianCalendar calendar(
98 year_, month_, day_, hour_, minute_, second_, success);
99 if (success <= U_ZERO_ERROR) {
100 UDate time = calendar.getTime(success);
101 icu::SimpleDateFormat formatter(*pattern_, success);
102 icu::UnicodeString formattedTime;
103 formatter.format(time, formattedTime, success);
104 formattedTime.toUTF8String(result);
105 if (success <= U_ZERO_ERROR) {
bulach 2013/02/05 11:54:56 nit: remove {} here and 108 below
Miguel Garcia 2013/02/05 17:44:40 Done.
106 return result;
107 }
108 } else {
109 LOG(WARNING) << "Calendar not created: error " << success;
110 }
111
112 return "";
113 }
114 }
115
116 void DateTimeFormatter::ExtractType(
117 const WebKit::WebDateTimeChooserParams& source) {
118 switch (source.type) {
119 case WebKit::WebDateTimeInputTypeDate:
120 type_ = ui::TEXT_INPUT_TYPE_DATE;
121 break;
122 case WebKit::WebDateTimeInputTypeDateTime:
123 type_ = ui::TEXT_INPUT_TYPE_DATE_TIME;
124 break;
125 case WebKit::WebDateTimeInputTypeDateTimeLocal:
126 type_ = ui::TEXT_INPUT_TYPE_DATE_TIME_LOCAL;
127 break;
128 case WebKit::WebDateTimeInputTypeMonth:
129 type_ = ui::TEXT_INPUT_TYPE_MONTH;
130 break;
131 case WebKit::WebDateTimeInputTypeTime:
132 type_ = ui::TEXT_INPUT_TYPE_TIME;
133 break;
134 case WebKit::WebDateTimeInputTypeWeek: // Not implemented
135 case WebKit::WebDateTimeInputTypeNone:
136 default:
137 type_ = ui::TEXT_INPUT_TYPE_NONE;
138 }
139 }
140
141 // Not all fields are defined in all configurations and ICU might store
142 // garbage if success <= U_ZERO_ERROR so the output is sanitized here.
143 int DateTimeFormatter::ExtractValue(
144 const icu::Calendar* calendar, UCalendarDateFields value) const {
145 UErrorCode success = U_ZERO_ERROR;
146 int result = calendar->get(value, success);
147 return (success <= U_ZERO_ERROR) ? result : 0;
148 }
149
150 bool DateTimeFormatter::ParseValues() {
151 if (type_ == ui::TEXT_INPUT_TYPE_NONE) {
152 ClearAll();
153 return false;
154 }
155
156 if (formatted_string_.empty()) {
157 ClearAll();
158 return true;
159 }
160
161 UErrorCode success = U_ZERO_ERROR;
162 icu::UnicodeString icu_value =
163 icu::UnicodeString::fromUTF8(formatted_string_);
164 if (pattern_map_.count(type_) > 0) {
bulach 2013/02/05 11:54:56 nit: pattern_map_.find(type) != pattern_map_.end()
Miguel Garcia 2013/02/05 17:44:40 Since I switched to an array I now just checked th
165 const icu::UnicodeString pattern = pattern_map_[type_];
166 icu::SimpleDateFormat formatter(pattern, success);
167 formatter.parse(icu_value, success);
168 if (success <= U_ZERO_ERROR) {
169 const icu::Calendar* cal = formatter.getCalendar();
170 year_ = ExtractValue(cal, UCAL_YEAR);
171 month_ = ExtractValue(cal, UCAL_MONTH);
172 day_ = ExtractValue(cal, UCAL_DATE);
173 hour_ = ExtractValue(cal, UCAL_HOUR_OF_DAY); // 24h format
174 minute_ = ExtractValue(cal, UCAL_MINUTE);
175 second_ = ExtractValue(cal, UCAL_SECOND);
176 }
177 }
178
179 return (success <= U_ZERO_ERROR);
180 }
181
182 void DateTimeFormatter::ClearAll() {
palmer 2013/02/04 22:14:08 Yeah, it seems we have a semipredicate problem her
Miguel Garcia 2013/02/05 17:44:40 See above, I am open to suggestions if you still f
183 year_ = 0;
184 month_ = 0;
185 day_ = 0;
186 hour_ = 0;
187 minute_ = 0;
188 second_ = 0;
189 }
190
191 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698