1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_ucb.hxx"
30 
31 #include <stdio.h>
32 #include <osl/time.h>
33 #include <com/sun/star/util/DateTime.hpp>
34 #include "DateTimeHelper.hxx"
35 
36 using namespace com::sun::star::util;
37 using namespace rtl;
38 
39 using namespace webdav_ucp;
40 
41 bool DateTimeHelper::ISO8601_To_DateTime (const OUString& s,
42 	DateTime& dateTime)
43 {
44 	OString aDT (s.getStr(), s.getLength(), RTL_TEXTENCODING_ASCII_US);
45 
46     int year, month, day, hours, minutes, off_hours, off_minutes, fix;
47     double seconds;
48 
49     // 2001-01-01T12:30:00Z
50     int n = sscanf( aDT.getStr(), "%04d-%02d-%02dT%02d:%02d:%lfZ",
51 	                &year, &month, &day, &hours, &minutes, &seconds );
52     if ( n == 6 )
53     {
54         fix = 0;
55     }
56     else
57     {
58         // 2001-01-01T12:30:00+03:30
59         n = sscanf( aDT.getStr(), "%04d-%02d-%02dT%02d:%02d:%lf+%02d:%02d",
60                     &year, &month, &day, &hours, &minutes, &seconds,
61                     &off_hours, &off_minutes );
62         if ( n == 8 )
63         {
64             fix = - off_hours * 3600 - off_minutes * 60;
65         }
66         else
67         {
68             // 2001-01-01T12:30:00-03:30
69             n = sscanf( aDT.getStr(), "%04d-%02d-%02dT%02d:%02d:%lf-%02d:%02d",
70                         &year, &month, &day, &hours, &minutes, &seconds,
71                         &off_hours, &off_minutes );
72             if ( n == 8 )
73             {
74                 fix = off_hours * 3600 + off_minutes * 60;
75             }
76             else
77             {
78                 return false;
79             }
80         }
81     }
82 
83     // Convert to local time...
84 
85     oslDateTime aDateTime;
86     aDateTime.NanoSeconds = 0;
87     aDateTime.Seconds     = sal::static_int_cast< sal_uInt16 >(seconds); // 0-59
88     aDateTime.Minutes     = sal::static_int_cast< sal_uInt16 >(minutes); // 0-59
89     aDateTime.Hours       = sal::static_int_cast< sal_uInt16 >(hours); // 0-23
90     aDateTime.Day         = sal::static_int_cast< sal_uInt16 >(day); // 1-31
91     aDateTime.DayOfWeek   = 0;          // 0-6, 0 = Sunday
92     aDateTime.Month       = sal::static_int_cast< sal_uInt16 >(month); // 1-12
93     aDateTime.Year        = sal::static_int_cast< sal_uInt16 >(year);
94 
95     TimeValue aTimeValue;
96     if ( osl_getTimeValueFromDateTime( &aDateTime, &aTimeValue ) )
97     {
98         aTimeValue.Seconds += fix;
99 
100         if ( osl_getLocalTimeFromSystemTime( &aTimeValue, &aTimeValue ) )
101         {
102             if ( osl_getDateTimeFromTimeValue( &aTimeValue, &aDateTime ) )
103             {
104                 dateTime.Year    = aDateTime.Year;
105                 dateTime.Month   = aDateTime.Month;
106                 dateTime.Day     = aDateTime.Day;
107                 dateTime.Hours   = aDateTime.Hours;
108                 dateTime.Minutes = aDateTime.Minutes;
109                 dateTime.Seconds = aDateTime.Seconds;
110 
111                 return true;
112              }
113         }
114     }
115 
116     return false;
117 }
118 
119 /*
120 sal_Int32 DateTimeHelper::convertDayToInt (const OUString& day)
121 {
122     if (day.compareToAscii ("Sun") == 0)
123         return 0;
124     else if (day.compareToAscii ("Mon") == 0)
125         return 1;
126     else if (day.compareToAscii ("Tue") == 0)
127 		return 2;
128     else if (day.compareToAscii ("Wed") == 0)
129 		return 3;
130     else if (day.compareToAscii ("Thu") == 0)
131 		return 4;
132     else if (day.compareToAscii ("Fri") == 0)
133 		return 5;
134     else if (day.compareToAscii ("Sat") == 0)
135 		return 6;
136 	else
137         return -1;
138 }
139 */
140 
141 sal_Int32 DateTimeHelper::convertMonthToInt (const OUString& month)
142 {
143     if (month.compareToAscii ("Jan") == 0)
144 		return 1;
145     else if (month.compareToAscii ("Feb") == 0)
146 		return 2;
147     else if (month.compareToAscii ("Mar") == 0)
148 		return 3;
149     else if (month.compareToAscii ("Apr") == 0)
150 		return 4;
151     else if (month.compareToAscii ("May") == 0)
152 		return 5;
153     else if (month.compareToAscii ("Jun") == 0)
154 		return 6;
155     else if (month.compareToAscii ("Jul") == 0)
156 		return 7;
157     else if (month.compareToAscii ("Aug") == 0)
158 		return 8;
159     else if (month.compareToAscii ("Sep") == 0)
160 		return 9;
161     else if (month.compareToAscii ("Oct") == 0)
162 		return 10;
163     else if (month.compareToAscii ("Nov") == 0)
164 		return 11;
165     else if (month.compareToAscii ("Dec") == 0)
166 		return 12;
167 	else
168 		return 0;
169 }
170 
171 bool DateTimeHelper::RFC2068_To_DateTime (const OUString& s,
172 	DateTime& dateTime)
173 {
174 	int year;
175 	int day;
176 	int hours;
177 	int minutes;
178 	int seconds;
179 	sal_Char string_month[3 + 1];
180     sal_Char string_day[3 + 1];
181 
182 	sal_Int32 found = s.indexOf (',');
183 	if (found != -1)
184 	{
185         OString aDT (s.getStr(), s.getLength(), RTL_TEXTENCODING_ASCII_US);
186 
187 		// RFC 1123
188         found = sscanf (aDT.getStr(), "%3s, %2d %3s %4d %2d:%2d:%2d GMT",
189                         string_day, &day, string_month, &year, &hours, &minutes, &seconds);
190         if (found != 7)
191 		{
192 			// RFC 1036
193             found = sscanf (aDT.getStr(), "%3s, %2d-%3s-%2d %2d:%2d:%2d GMT",
194                             string_day, &day, string_month, &year, &hours, &minutes, &seconds);
195 		}
196         found = (found == 7) ? 1 : 0;
197 	}
198 	else
199 	{
200 		OString aDT (s.getStr(), s.getLength(), RTL_TEXTENCODING_ASCII_US);
201 
202 		// ANSI C's asctime () format
203 		found = sscanf (aDT.getStr(), "%3s %3s %d %2d:%2d:%2d %4d",
204 						string_day, string_month,
205 						&day, &hours, &minutes, &seconds, &year);
206 		found = (found == 7) ? 1 : 0;
207 	}
208 
209 	if (found)
210 	{
211         found = 0;
212 
213         int month = DateTimeHelper::convertMonthToInt (
214                             OUString::createFromAscii (string_month));
215 		if (month)
216 		{
217             // Convert to local time...
218 
219             oslDateTime aDateTime;
220             aDateTime.NanoSeconds = 0;
221             aDateTime.Seconds     = sal::static_int_cast< sal_uInt16 >(seconds);
222                 // 0-59
223             aDateTime.Minutes     = sal::static_int_cast< sal_uInt16 >(minutes);
224                 // 0-59
225             aDateTime.Hours       = sal::static_int_cast< sal_uInt16 >(hours);
226                 // 0-23
227             aDateTime.Day         = sal::static_int_cast< sal_uInt16 >(day);
228                 // 1-31
229             aDateTime.DayOfWeek   = 0; //dayofweek;  // 0-6, 0 = Sunday
230             aDateTime.Month       = sal::static_int_cast< sal_uInt16 >(month);
231                 // 1-12
232             aDateTime.Year        = sal::static_int_cast< sal_uInt16 >(year);
233 
234             TimeValue aTimeValue;
235             if ( osl_getTimeValueFromDateTime( &aDateTime,
236                                                 &aTimeValue ) )
237             {
238                 if ( osl_getLocalTimeFromSystemTime( &aTimeValue,
239                                                         &aTimeValue ) )
240                 {
241                     if ( osl_getDateTimeFromTimeValue( &aTimeValue,
242                                                         &aDateTime ) )
243                     {
244                         dateTime.Year    = aDateTime.Year;
245                         dateTime.Month   = aDateTime.Month;
246                         dateTime.Day     = aDateTime.Day;
247                         dateTime.Hours   = aDateTime.Hours;
248                         dateTime.Minutes = aDateTime.Minutes;
249                         dateTime.Seconds = aDateTime.Seconds;
250 
251                         found = 1;
252                     }
253                 }
254             }
255 		}
256 	}
257 
258 	return (found) ? true : false;
259 }
260 
261 bool DateTimeHelper::convert (const OUString& s, DateTime& dateTime)
262 {
263 	if (ISO8601_To_DateTime (s, dateTime))
264 		return true;
265 	else if (RFC2068_To_DateTime (s, dateTime))
266 		return true;
267 	else
268 		return false;
269 }
270 
271