1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_ucb.hxx"
26 
27 #include <stdio.h>
28 #include <osl/time.h>
29 #include <com/sun/star/util/DateTime.hpp>
30 #include "DateTimeHelper.hxx"
31 
32 using namespace com::sun::star::util;
33 using namespace rtl;
34 
35 using namespace http_dav_ucp;
36 
37 bool DateTimeHelper::ISO8601_To_DateTime (const OUString& s,
38 	DateTime& dateTime)
39 {
40 	OString aDT (s.getStr(), s.getLength(), RTL_TEXTENCODING_ASCII_US);
41 
42     int year, month, day, hours, minutes, off_hours, off_minutes, fix;
43     double seconds;
44 
45     // 2001-01-01T12:30:00Z
46     int n = sscanf( aDT.getStr(), "%04d-%02d-%02dT%02d:%02d:%lfZ",
47 	                &year, &month, &day, &hours, &minutes, &seconds );
48     if ( n == 6 )
49     {
50         fix = 0;
51     }
52     else
53     {
54         // 2001-01-01T12:30:00+03:30
55         n = sscanf( aDT.getStr(), "%04d-%02d-%02dT%02d:%02d:%lf+%02d:%02d",
56                     &year, &month, &day, &hours, &minutes, &seconds,
57                     &off_hours, &off_minutes );
58         if ( n == 8 )
59         {
60             fix = - off_hours * 3600 - off_minutes * 60;
61         }
62         else
63         {
64             // 2001-01-01T12:30:00-03:30
65             n = sscanf( aDT.getStr(), "%04d-%02d-%02dT%02d:%02d:%lf-%02d:%02d",
66                         &year, &month, &day, &hours, &minutes, &seconds,
67                         &off_hours, &off_minutes );
68             if ( n == 8 )
69             {
70                 fix = off_hours * 3600 + off_minutes * 60;
71             }
72             else
73             {
74                 return false;
75             }
76         }
77     }
78 
79     // Convert to local time...
80 
81     oslDateTime aDateTime;
82     aDateTime.NanoSeconds = 0;
83     aDateTime.Seconds     = sal::static_int_cast< sal_uInt16 >(seconds); // 0-59
84     aDateTime.Minutes     = sal::static_int_cast< sal_uInt16 >(minutes); // 0-59
85     aDateTime.Hours       = sal::static_int_cast< sal_uInt16 >(hours); // 0-23
86     aDateTime.Day         = sal::static_int_cast< sal_uInt16 >(day); // 1-31
87     aDateTime.DayOfWeek   = 0;          // 0-6, 0 = Sunday
88     aDateTime.Month       = sal::static_int_cast< sal_uInt16 >(month); // 1-12
89     aDateTime.Year        = sal::static_int_cast< sal_uInt16 >(year);
90 
91     TimeValue aTimeValue;
92     if ( osl_getTimeValueFromDateTime( &aDateTime, &aTimeValue ) )
93     {
94         aTimeValue.Seconds += fix;
95 
96         if ( osl_getLocalTimeFromSystemTime( &aTimeValue, &aTimeValue ) )
97         {
98             if ( osl_getDateTimeFromTimeValue( &aTimeValue, &aDateTime ) )
99             {
100                 dateTime.Year    = aDateTime.Year;
101                 dateTime.Month   = aDateTime.Month;
102                 dateTime.Day     = aDateTime.Day;
103                 dateTime.Hours   = aDateTime.Hours;
104                 dateTime.Minutes = aDateTime.Minutes;
105                 dateTime.Seconds = aDateTime.Seconds;
106 
107                 return true;
108              }
109         }
110     }
111 
112     return false;
113 }
114 
115 /*
116 sal_Int32 DateTimeHelper::convertDayToInt (const OUString& day)
117 {
118     if (day.compareToAscii ("Sun") == 0)
119         return 0;
120     else if (day.compareToAscii ("Mon") == 0)
121         return 1;
122     else if (day.compareToAscii ("Tue") == 0)
123 		return 2;
124     else if (day.compareToAscii ("Wed") == 0)
125 		return 3;
126     else if (day.compareToAscii ("Thu") == 0)
127 		return 4;
128     else if (day.compareToAscii ("Fri") == 0)
129 		return 5;
130     else if (day.compareToAscii ("Sat") == 0)
131 		return 6;
132 	else
133         return -1;
134 }
135 */
136 
137 sal_Int32 DateTimeHelper::convertMonthToInt (const OUString& month)
138 {
139     if (month.compareToAscii ("Jan") == 0)
140 		return 1;
141     else if (month.compareToAscii ("Feb") == 0)
142 		return 2;
143     else if (month.compareToAscii ("Mar") == 0)
144 		return 3;
145     else if (month.compareToAscii ("Apr") == 0)
146 		return 4;
147     else if (month.compareToAscii ("May") == 0)
148 		return 5;
149     else if (month.compareToAscii ("Jun") == 0)
150 		return 6;
151     else if (month.compareToAscii ("Jul") == 0)
152 		return 7;
153     else if (month.compareToAscii ("Aug") == 0)
154 		return 8;
155     else if (month.compareToAscii ("Sep") == 0)
156 		return 9;
157     else if (month.compareToAscii ("Oct") == 0)
158 		return 10;
159     else if (month.compareToAscii ("Nov") == 0)
160 		return 11;
161     else if (month.compareToAscii ("Dec") == 0)
162 		return 12;
163 	else
164 		return 0;
165 }
166 
167 bool DateTimeHelper::RFC2068_To_DateTime (const OUString& s,
168 	DateTime& dateTime)
169 {
170 	int year;
171 	int day;
172 	int hours;
173 	int minutes;
174 	int seconds;
175 	sal_Char string_month[3 + 1];
176     sal_Char string_day[3 + 1];
177 
178 	sal_Int32 found = s.indexOf (',');
179 	if (found != -1)
180 	{
181         OString aDT (s.getStr(), s.getLength(), RTL_TEXTENCODING_ASCII_US);
182 
183 		// RFC 1123
184         found = sscanf (aDT.getStr(), "%3s, %2d %3s %4d %2d:%2d:%2d GMT",
185                         string_day, &day, string_month, &year, &hours, &minutes, &seconds);
186         if (found != 7)
187 		{
188 			// RFC 1036
189             found = sscanf (aDT.getStr(), "%3s, %2d-%3s-%2d %2d:%2d:%2d GMT",
190                             string_day, &day, string_month, &year, &hours, &minutes, &seconds);
191 		}
192         found = (found == 7) ? 1 : 0;
193 	}
194 	else
195 	{
196 		OString aDT (s.getStr(), s.getLength(), RTL_TEXTENCODING_ASCII_US);
197 
198 		// ANSI C's asctime () format
199 		found = sscanf (aDT.getStr(), "%3s %3s %d %2d:%2d:%2d %4d",
200 						string_day, string_month,
201 						&day, &hours, &minutes, &seconds, &year);
202 		found = (found == 7) ? 1 : 0;
203 	}
204 
205 	if (found)
206 	{
207         found = 0;
208 
209         int month = DateTimeHelper::convertMonthToInt (
210                             OUString::createFromAscii (string_month));
211 		if (month)
212 		{
213             // Convert to local time...
214 
215             oslDateTime aDateTime;
216             aDateTime.NanoSeconds = 0;
217             aDateTime.Seconds     = sal::static_int_cast< sal_uInt16 >(seconds);
218                 // 0-59
219             aDateTime.Minutes     = sal::static_int_cast< sal_uInt16 >(minutes);
220                 // 0-59
221             aDateTime.Hours       = sal::static_int_cast< sal_uInt16 >(hours);
222                 // 0-23
223             aDateTime.Day         = sal::static_int_cast< sal_uInt16 >(day);
224                 // 1-31
225             aDateTime.DayOfWeek   = 0; //dayofweek;  // 0-6, 0 = Sunday
226             aDateTime.Month       = sal::static_int_cast< sal_uInt16 >(month);
227                 // 1-12
228             aDateTime.Year        = sal::static_int_cast< sal_uInt16 >(year);
229 
230             TimeValue aTimeValue;
231             if ( osl_getTimeValueFromDateTime( &aDateTime,
232                                                 &aTimeValue ) )
233             {
234                 if ( osl_getLocalTimeFromSystemTime( &aTimeValue,
235                                                         &aTimeValue ) )
236                 {
237                     if ( osl_getDateTimeFromTimeValue( &aTimeValue,
238                                                         &aDateTime ) )
239                     {
240                         dateTime.Year    = aDateTime.Year;
241                         dateTime.Month   = aDateTime.Month;
242                         dateTime.Day     = aDateTime.Day;
243                         dateTime.Hours   = aDateTime.Hours;
244                         dateTime.Minutes = aDateTime.Minutes;
245                         dateTime.Seconds = aDateTime.Seconds;
246 
247                         found = 1;
248                     }
249                 }
250             }
251 		}
252 	}
253 
254 	return (found) ? true : false;
255 }
256 
257 bool DateTimeHelper::convert (const OUString& s, DateTime& dateTime)
258 {
259 	if (ISO8601_To_DateTime (s, dateTime))
260 		return true;
261 	else if (RFC2068_To_DateTime (s, dateTime))
262 		return true;
263 	else
264 		return false;
265 }
266 
267