webservices/wsutils/src/sendateutils.cpp
changeset 0 62f9d29f7211
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webservices/wsutils/src/sendateutils.cpp	Thu Jan 07 16:19:19 2010 +0200
@@ -0,0 +1,210 @@
+/*
+* Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:        
+*
+*/
+
+
+
+
+
+
+
+
+// INCLUDE FILES
+#include "SenDateUtils.h"
+
+namespace
+    {
+    _LIT8(KXmlDateTimeFormat8, "%04d-%02d-%02dT%02d:%02d:%02dZ"); // prior WS-* MT / SCT timestamp fix (2006-12-06) => Liberty IOP confirmed
+    _LIT8(KXmlDateTimeFormat82, "%04d-%02d-%02dT%02d:%02d:%02d.%06dZ");
+    }
+
+EXPORT_C TTime SenDateUtils::FromXmlDateTimeL(const TDesC8& aXmlDateTime)
+    {
+    // Format: '2004-01-22T15:31:00Z' or '2004-01-22T15:31:00+02:00'
+
+    TInt year;
+    TInt month;
+    TInt day;
+    TInt hour;
+    TInt min;
+    TInt sec;
+    TInt microsec;
+
+    // Try to leave instead of panic in all places
+    if(aXmlDateTime.Length() < 20) { User::Leave(KErrUnderflow); }
+
+    TLex8 yearLex(aXmlDateTime.Mid(0, 4));
+    User::LeaveIfError(yearLex.Val(year));
+
+    if(aXmlDateTime[4] != '-') { User::Leave(KErrGeneral); }
+
+    TLex8 monthLex(aXmlDateTime.Mid(5, 2));
+    User::LeaveIfError(monthLex.Val(month));
+    month--;
+    if(month < 0) { User::Leave(KErrUnderflow); }
+    if(month >= 12) { User::Leave(KErrOverflow); }
+
+    if(aXmlDateTime[7] != '-') { User::Leave(KErrGeneral); }
+
+    TLex8 dayLex(aXmlDateTime.Mid(8, 2));
+    User::LeaveIfError(dayLex.Val(day));
+    day--;
+    if(day < 0) { User::Leave(KErrUnderflow); }
+    if(day >= 31) { User::Leave(KErrOverflow); }
+
+    if(aXmlDateTime[10] != 'T') { User::Leave(KErrGeneral); }
+
+    TLex8 hourLex(aXmlDateTime.Mid(11, 2));
+    User::LeaveIfError(hourLex.Val(hour));
+    if(hour < 0) { User::Leave(KErrUnderflow); }
+    if(hour >= 24) { User::Leave(KErrOverflow); }
+
+    if(aXmlDateTime[13] != ':') { User::Leave(KErrGeneral); }
+
+    TLex8 minLex(aXmlDateTime.Mid(14, 2));
+    User::LeaveIfError(minLex.Val(min));
+    if(min < 0) { User::Leave(KErrUnderflow); }
+    if(min >= 60) { User::Leave(KErrOverflow); }
+
+    if(aXmlDateTime[16] != ':') { User::Leave(KErrGeneral); }
+
+    TLex8 secLex(aXmlDateTime.Mid(17, 2));
+    User::LeaveIfError(secLex.Val(sec));
+    if(sec < 0) { User::Leave(KErrUnderflow); }
+    if(sec >= 60) { User::Leave(KErrOverflow); }
+
+    TUint16 nextChar = aXmlDateTime[19];
+    TUint16 tzChar = aXmlDateTime[19];
+    
+    TInt i = 19;
+    while((tzChar != 'Z') && (tzChar != '+') && (tzChar != '-'))
+        {
+        i++;
+        if(i < aXmlDateTime.Length()) tzChar = aXmlDateTime[i];
+        else { User::Leave(KErrGeneral); }
+        }
+        
+    if(nextChar == '.')
+        {
+        TInt lastMicrosec;
+        if(i > 26) lastMicrosec = 26;
+        else lastMicrosec = i;
+        TLex8 microsecLex(aXmlDateTime.Mid(20, lastMicrosec-20));
+        User::LeaveIfError(microsecLex.Val(microsec));
+        TInt j = 26;
+        while (j > lastMicrosec)
+            {
+            microsec = microsec * 10;
+            j--;
+            }
+        }
+    else
+        {
+        microsec = 0;
+        }       
+
+    TTime time(
+        TDateTime(
+            year,
+            static_cast<TMonth>(month),
+            day,
+            hour,
+            min,
+            sec,
+            microsec
+            )
+        );
+
+    if(tzChar == 'Z')
+        {
+        // UTC
+        if(aXmlDateTime.Length() > i+1) { User::Leave(KErrOverflow); }
+        }
+    else
+        {
+        // Time zone info is appended
+        if(aXmlDateTime.Length() < i+6) { User::Leave(KErrUnderflow); }
+        if(aXmlDateTime.Length() > i+6) { User::Leave(KErrOverflow); }
+        TInt tzSign = 0;
+        if(tzChar == '+') { tzSign = +1; }
+        if(tzChar == '-') { tzSign = -1; }
+        if(tzSign == 0) { User::Leave(KErrGeneral); }
+
+        TInt tzHour;
+        TInt tzMin;
+
+        TLex8 tzHourLex(aXmlDateTime.Mid(i+1, 2));
+        User::LeaveIfError(tzHourLex.Val(tzHour));
+        if(tzHour < 0) { User::Leave(KErrUnderflow); }
+        if(tzHour >= 24) { User::Leave(KErrOverflow); }
+
+        if(aXmlDateTime[i+3] != ':') { User::Leave(KErrGeneral); }
+
+        TLex8 tzMinLex(aXmlDateTime.Mid(i+4, 2));
+        User::LeaveIfError(tzMinLex.Val(tzMin));
+        if(tzMin < 0) { User::Leave(KErrUnderflow); }
+        if(tzMin >= 60) { User::Leave(KErrOverflow); }
+
+        TInt tzShiftMins = tzSign * (tzMin + tzHour * 60);
+        time += TTimeIntervalMinutes(tzShiftMins);
+        }
+
+    return time;
+    }
+
+EXPORT_C void SenDateUtils::ToXmlDateTimeUtf8L(TDes8& aDest, const TTime& aSrc)
+    {
+    if(aDest.MaxLength() < KXmlDateTimeMaxLength)
+        {
+        User::Leave(KErrOverflow);
+        }
+
+    TDateTime dt = aSrc.DateTime();
+    aDest.Format(
+        KXmlDateTimeFormat8,
+        dt.Year(),
+        dt.Month() + 1,
+        dt.Day() + 1,
+        dt.Hour(),
+        dt.Minute(),
+        dt.Second()
+        );
+}
+    
+    
+EXPORT_C void SenDateUtils::ToXmlDateTimeUtf82L(TDes8& aDest, const TTime& aSrc)
+    {
+    if(aDest.MaxLength() < KXmlDateTimeMaxLength)
+        {
+        User::Leave(KErrOverflow);
+        }
+
+    TDateTime dt = aSrc.DateTime();
+    aDest.Format(
+        KXmlDateTimeFormat82,
+        dt.Year(),
+        dt.Month() + 1,
+        dt.Day() + 1,
+        dt.Hour(),
+        dt.Minute(),
+        dt.Second(),
+		dt.MicroSecond()   // Added in WS-* MT / SCT fix (2006-12-06)
+        );
+    }
+    
+
+// End of File
+