|
1 /* |
|
2 * Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 // INCLUDE FILES |
|
26 #include "SenDateUtils.h" |
|
27 |
|
28 namespace |
|
29 { |
|
30 _LIT8(KXmlDateTimeFormat8, "%04d-%02d-%02dT%02d:%02d:%02dZ"); // prior WS-* MT / SCT timestamp fix (2006-12-06) => Liberty IOP confirmed |
|
31 _LIT8(KXmlDateTimeFormat82, "%04d-%02d-%02dT%02d:%02d:%02d.%06dZ"); |
|
32 } |
|
33 |
|
34 EXPORT_C TTime SenDateUtils::FromXmlDateTimeL(const TDesC8& aXmlDateTime) |
|
35 { |
|
36 // Format: '2004-01-22T15:31:00Z' or '2004-01-22T15:31:00+02:00' |
|
37 |
|
38 TInt year; |
|
39 TInt month; |
|
40 TInt day; |
|
41 TInt hour; |
|
42 TInt min; |
|
43 TInt sec; |
|
44 TInt microsec; |
|
45 |
|
46 // Try to leave instead of panic in all places |
|
47 if(aXmlDateTime.Length() < 20) { User::Leave(KErrUnderflow); } |
|
48 |
|
49 TLex8 yearLex(aXmlDateTime.Mid(0, 4)); |
|
50 User::LeaveIfError(yearLex.Val(year)); |
|
51 |
|
52 if(aXmlDateTime[4] != '-') { User::Leave(KErrGeneral); } |
|
53 |
|
54 TLex8 monthLex(aXmlDateTime.Mid(5, 2)); |
|
55 User::LeaveIfError(monthLex.Val(month)); |
|
56 month--; |
|
57 if(month < 0) { User::Leave(KErrUnderflow); } |
|
58 if(month >= 12) { User::Leave(KErrOverflow); } |
|
59 |
|
60 if(aXmlDateTime[7] != '-') { User::Leave(KErrGeneral); } |
|
61 |
|
62 TLex8 dayLex(aXmlDateTime.Mid(8, 2)); |
|
63 User::LeaveIfError(dayLex.Val(day)); |
|
64 day--; |
|
65 if(day < 0) { User::Leave(KErrUnderflow); } |
|
66 if(day >= 31) { User::Leave(KErrOverflow); } |
|
67 |
|
68 if(aXmlDateTime[10] != 'T') { User::Leave(KErrGeneral); } |
|
69 |
|
70 TLex8 hourLex(aXmlDateTime.Mid(11, 2)); |
|
71 User::LeaveIfError(hourLex.Val(hour)); |
|
72 if(hour < 0) { User::Leave(KErrUnderflow); } |
|
73 if(hour >= 24) { User::Leave(KErrOverflow); } |
|
74 |
|
75 if(aXmlDateTime[13] != ':') { User::Leave(KErrGeneral); } |
|
76 |
|
77 TLex8 minLex(aXmlDateTime.Mid(14, 2)); |
|
78 User::LeaveIfError(minLex.Val(min)); |
|
79 if(min < 0) { User::Leave(KErrUnderflow); } |
|
80 if(min >= 60) { User::Leave(KErrOverflow); } |
|
81 |
|
82 if(aXmlDateTime[16] != ':') { User::Leave(KErrGeneral); } |
|
83 |
|
84 TLex8 secLex(aXmlDateTime.Mid(17, 2)); |
|
85 User::LeaveIfError(secLex.Val(sec)); |
|
86 if(sec < 0) { User::Leave(KErrUnderflow); } |
|
87 if(sec >= 60) { User::Leave(KErrOverflow); } |
|
88 |
|
89 TUint16 nextChar = aXmlDateTime[19]; |
|
90 TUint16 tzChar = aXmlDateTime[19]; |
|
91 |
|
92 TInt i = 19; |
|
93 while((tzChar != 'Z') && (tzChar != '+') && (tzChar != '-')) |
|
94 { |
|
95 i++; |
|
96 if(i < aXmlDateTime.Length()) tzChar = aXmlDateTime[i]; |
|
97 else { User::Leave(KErrGeneral); } |
|
98 } |
|
99 |
|
100 if(nextChar == '.') |
|
101 { |
|
102 TInt lastMicrosec; |
|
103 if(i > 26) lastMicrosec = 26; |
|
104 else lastMicrosec = i; |
|
105 TLex8 microsecLex(aXmlDateTime.Mid(20, lastMicrosec-20)); |
|
106 User::LeaveIfError(microsecLex.Val(microsec)); |
|
107 TInt j = 26; |
|
108 while (j > lastMicrosec) |
|
109 { |
|
110 microsec = microsec * 10; |
|
111 j--; |
|
112 } |
|
113 } |
|
114 else |
|
115 { |
|
116 microsec = 0; |
|
117 } |
|
118 |
|
119 TTime time( |
|
120 TDateTime( |
|
121 year, |
|
122 static_cast<TMonth>(month), |
|
123 day, |
|
124 hour, |
|
125 min, |
|
126 sec, |
|
127 microsec |
|
128 ) |
|
129 ); |
|
130 |
|
131 if(tzChar == 'Z') |
|
132 { |
|
133 // UTC |
|
134 if(aXmlDateTime.Length() > i+1) { User::Leave(KErrOverflow); } |
|
135 } |
|
136 else |
|
137 { |
|
138 // Time zone info is appended |
|
139 if(aXmlDateTime.Length() < i+6) { User::Leave(KErrUnderflow); } |
|
140 if(aXmlDateTime.Length() > i+6) { User::Leave(KErrOverflow); } |
|
141 TInt tzSign = 0; |
|
142 if(tzChar == '+') { tzSign = +1; } |
|
143 if(tzChar == '-') { tzSign = -1; } |
|
144 if(tzSign == 0) { User::Leave(KErrGeneral); } |
|
145 |
|
146 TInt tzHour; |
|
147 TInt tzMin; |
|
148 |
|
149 TLex8 tzHourLex(aXmlDateTime.Mid(i+1, 2)); |
|
150 User::LeaveIfError(tzHourLex.Val(tzHour)); |
|
151 if(tzHour < 0) { User::Leave(KErrUnderflow); } |
|
152 if(tzHour >= 24) { User::Leave(KErrOverflow); } |
|
153 |
|
154 if(aXmlDateTime[i+3] != ':') { User::Leave(KErrGeneral); } |
|
155 |
|
156 TLex8 tzMinLex(aXmlDateTime.Mid(i+4, 2)); |
|
157 User::LeaveIfError(tzMinLex.Val(tzMin)); |
|
158 if(tzMin < 0) { User::Leave(KErrUnderflow); } |
|
159 if(tzMin >= 60) { User::Leave(KErrOverflow); } |
|
160 |
|
161 TInt tzShiftMins = tzSign * (tzMin + tzHour * 60); |
|
162 time += TTimeIntervalMinutes(tzShiftMins); |
|
163 } |
|
164 |
|
165 return time; |
|
166 } |
|
167 |
|
168 EXPORT_C void SenDateUtils::ToXmlDateTimeUtf8L(TDes8& aDest, const TTime& aSrc) |
|
169 { |
|
170 if(aDest.MaxLength() < KXmlDateTimeMaxLength) |
|
171 { |
|
172 User::Leave(KErrOverflow); |
|
173 } |
|
174 |
|
175 TDateTime dt = aSrc.DateTime(); |
|
176 aDest.Format( |
|
177 KXmlDateTimeFormat8, |
|
178 dt.Year(), |
|
179 dt.Month() + 1, |
|
180 dt.Day() + 1, |
|
181 dt.Hour(), |
|
182 dt.Minute(), |
|
183 dt.Second() |
|
184 ); |
|
185 } |
|
186 |
|
187 |
|
188 EXPORT_C void SenDateUtils::ToXmlDateTimeUtf82L(TDes8& aDest, const TTime& aSrc) |
|
189 { |
|
190 if(aDest.MaxLength() < KXmlDateTimeMaxLength) |
|
191 { |
|
192 User::Leave(KErrOverflow); |
|
193 } |
|
194 |
|
195 TDateTime dt = aSrc.DateTime(); |
|
196 aDest.Format( |
|
197 KXmlDateTimeFormat82, |
|
198 dt.Year(), |
|
199 dt.Month() + 1, |
|
200 dt.Day() + 1, |
|
201 dt.Hour(), |
|
202 dt.Minute(), |
|
203 dt.Second(), |
|
204 dt.MicroSecond() // Added in WS-* MT / SCT fix (2006-12-06) |
|
205 ); |
|
206 } |
|
207 |
|
208 |
|
209 // End of File |
|
210 |