src/xalanc/XalanEXSLT/XalanEXSLTDateTime.cpp (209 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "XalanEXSLTDateTime.hpp" #include "XalanEXSLTDateTimeImpl.hpp" #include <cstdio> #include <ctime> #include <xalanc/PlatformSupport/XalanMessageLoader.hpp> #include <xalanc/XPath/XObjectFactory.hpp> namespace XALAN_CPP_NAMESPACE { static const XalanEXSLTFunctionDateTime s_dateTimeFunction; static const XalanDOMChar s_dateTimeFunctionName[] = { XalanUnicode::charLetter_d, XalanUnicode::charLetter_a, XalanUnicode::charLetter_t, XalanUnicode::charLetter_e, XalanUnicode::charHyphenMinus, XalanUnicode::charLetter_t, XalanUnicode::charLetter_i, XalanUnicode::charLetter_m, XalanUnicode::charLetter_e, 0 }; static const XalanEXSLTDateTimeFunctionsInstaller::FunctionTableEntry theFunctionTable[] = { { s_dateTimeFunctionName, &s_dateTimeFunction }, { 0, 0 } }; static const XalanDOMChar s_dateTimeNamespace[] = { XalanUnicode::charLetter_h, XalanUnicode::charLetter_t, XalanUnicode::charLetter_t, XalanUnicode::charLetter_p, XalanUnicode::charColon, XalanUnicode::charSolidus, XalanUnicode::charSolidus, XalanUnicode::charLetter_e, XalanUnicode::charLetter_x, XalanUnicode::charLetter_s, XalanUnicode::charLetter_l, XalanUnicode::charLetter_t, XalanUnicode::charFullStop, XalanUnicode::charLetter_o, XalanUnicode::charLetter_r, XalanUnicode::charLetter_g, XalanUnicode::charSolidus, XalanUnicode::charLetter_d, XalanUnicode::charLetter_a, XalanUnicode::charLetter_t, XalanUnicode::charLetter_e, XalanUnicode::charLetter_s, XalanUnicode::charHyphenMinus, XalanUnicode::charLetter_a, XalanUnicode::charLetter_n, XalanUnicode::charLetter_d, XalanUnicode::charHyphenMinus, XalanUnicode::charLetter_t, XalanUnicode::charLetter_i, XalanUnicode::charLetter_m, XalanUnicode::charLetter_e, XalanUnicode::charLetter_s, 0 }; using std::sprintf; using std::time; using std::time_t; using std::tm; namespace { #ifndef XALAN_HAVE_LOCALTIME_R using std::localtime; static struct tm* localtime_r(const time_t *clock, struct tm *res) { assert( res != 0 ); struct tm * tmpTime = localtime(clock); if (tmpTime == 0 ) { return 0; } else { *res = *tmpTime; return res; } } #endif // XALAN_HAVE_LOCALTIME_R #ifndef XALAN_HAVE_GMTIME_R using std::gmtime; static struct tm * gmtime_r(const time_t *clock, struct tm *res) { assert( res != 0 ); struct tm * tmpTime = gmtime(clock); if (tmpTime == 0 ) { return 0; } else { *res = *tmpTime; return res; } } #endif // XALAN_HAVE_GMTIME_R } XObjectPtr XalanEXSLTFunctionDateTime::execute( XPathExecutionContext& executionContext, XalanNode* context, const XObjectArgVectorType& args, const Locator* locator) const { if (args.size() != 0) { generalError( executionContext, context, locator); } const GetCachedString theGuard(executionContext); XalanDOMString& theResult = theGuard.get(); theResult.clear(); time_t long_time; time( &long_time ); struct tm localTime; const struct tm* ptrStrctTime = localtime_r(&long_time, &localTime); if (ptrStrctTime != 0 ) { struct tm gmtTime; ptrStrctTime = gmtime_r(&long_time, &gmtTime); if(ptrStrctTime != 0 ) { const size_t MAX_DATE_TIME_LEN = 1000; char stringTime[MAX_DATE_TIME_LEN + 1]; const size_t result = strftime(stringTime, MAX_DATE_TIME_LEN, "%Y-%m-%dT%H:%M:%S", ptrStrctTime); if (result != 0) { theResult.assign(stringTime); long localData = localTime.tm_year * 10000 + localTime.tm_mon * 100 + localTime.tm_mday; long gmtData = gmtTime.tm_year * 10000 + gmtTime.tm_mon * 100 + gmtTime.tm_mday; char timeZone[MAX_DATE_TIME_LEN+1]; int offset = 0; if( localData == gmtData ) { if(localTime.tm_hour == gmtTime.tm_hour) { offset = 100; // much bigger then any legal offset } else { offset = localTime.tm_hour - gmtTime.tm_hour; } } else if(localData < gmtData) { offset = localTime.tm_hour - gmtTime.tm_hour - 24; } else { offset = localTime.tm_hour - gmtTime.tm_hour + 24; } if(offset == 100) { sprintf(timeZone, "%s", "Z"); } else { if(offset < 0) { sprintf(timeZone, "%2.2d:00", offset); } else sprintf(timeZone, "+%2.2d:00", offset); } theResult.append(timeZone); } } } return executionContext.getXObjectFactory().createString(theResult); } const XalanDOMString& XalanEXSLTFunctionDateTime::getError(XalanDOMString& theResult) const { return XalanMessageLoader::getMessage( theResult, XalanMessages::EXSLTFunctionAcceptsOneArgument_1Param, s_dateTimeFunctionName); } void XalanEXSLTDateTimeFunctionsInstaller::installLocal(XPathEnvSupportDefault& theSupport) { doInstallLocal(s_dateTimeNamespace, theFunctionTable, theSupport); } void XalanEXSLTDateTimeFunctionsInstaller::installGlobal(MemoryManager& theManager) { doInstallGlobal(theManager, s_dateTimeNamespace, theFunctionTable); } void XalanEXSLTDateTimeFunctionsInstaller::uninstallLocal(XPathEnvSupportDefault& theSupport) { doUninstallLocal(s_dateTimeNamespace, theFunctionTable, theSupport); } void XalanEXSLTDateTimeFunctionsInstaller::uninstallGlobal(MemoryManager& theManager) { doUninstallGlobal(theManager, s_dateTimeNamespace, theFunctionTable); } }