Ejemplo n.º 1
0
double Time::GetTime() const
{
	struct tm t;

	t.tm_wday = 0;
	t.tm_yday = 0;
	t.tm_year = m_year - 1900;
	t.tm_mon = m_month - 1;
	t.tm_mday = m_day;
	t.tm_hour = m_hour;
	t.tm_min = m_minute;
	t.tm_sec = m_second;

	time_t tt = 0;

	if (m_type == Universal) {
		t.tm_isdst = 0;
		tt = _mkgmtime(&t);
		if (tt <= 1) {
			throw std::runtime_error("Invalid UTC date/time: " + ToExtendedISO());
		}
	}
	else if (m_type == Local) {
		// MSDN: "A value less than zero to have the C run-time library code compute whether standard time or daylight savings time is in effect."
		t.tm_isdst = -1; 
		tt = mktime(&t);
		if (tt < 0) {
			throw std::runtime_error("Invalid local date/time: " + ToExtendedISO());
		}
	}
	else {
#ifdef WIN32
#ifdef _DEBUG
		OutputDebugStringA("\n--> GetTime(): Time type is unknown - assuming universal time.\n\n");
#endif // _DEBUG
#endif // WIN32
		t.tm_isdst = 0;
		tt = _mkgmtime(&t);
		if (tt <= 1) {
			throw std::runtime_error("Invalid date/time: " + ToExtendedISO());
		}
	}

	double d = static_cast<double>(tt);
	d += m_fraction_of_second;

#ifdef _DEBUG
	Time tim(d, m_type);
	assert(*this == tim);
#endif // _DEBUG
	return d;
}
Ejemplo n.º 2
0
time_t MakeGmTime(tm *timeUtc)
//----------------------------
{
	#if MPT_COMPILER_MSVC
		return _mkgmtime(timeUtc);
	#else // !MPT_COMPILER_MSVC
		// There is no portable way in C/C++ to convert between time_t and struct tm in UTC.
		// Approximate it as good as possible without implementing full date handling logic.
		// NOTE:
		// This can be wrong for dates during DST switch.
		if(!timeUtc)
		{
			return time_t();
		}
		tm t = *timeUtc;
		time_t localSinceEpoch = mktime(&t);
		const tm * tmpLocal = localtime(&localSinceEpoch);
		if(!tmpLocal)
		{
			return localSinceEpoch;
		}
		tm localTM = *tmpLocal;
		const tm * tmpUTC = gmtime(&localSinceEpoch);
		if(!tmpUTC)
		{
			return localSinceEpoch;
		}
		tm utcTM = *tmpUTC;
		double offset = difftime(mktime(&localTM), mktime(&utcTM));
		double timeScaleFactor = difftime(2, 1);
		time_t utcSinceEpoch = localSinceEpoch + Util::Round<time_t>(offset / timeScaleFactor);
		return utcSinceEpoch;
	#endif // MPT_COMPILER_MSVC
}
Ejemplo n.º 3
0
// retrieve a date structure from an ASN1 time, for 
// validity checking.
LLDate cert_date_from_asn1_time(ASN1_TIME* asn1_time)
{
	
	struct tm timestruct = {0};
	int i = asn1_time->length;
	
	if (i < 10)
	{
		return LLDate();
	}	
	// convert the date from the ASN1 time (which is a string in ZULU time), to
	// a timeval.
	timestruct.tm_year = (asn1_time->data[0]-'0') * 10 + (asn1_time->data[1]-'0');
	
	/* Deal with Year 2000 */
	if (timestruct.tm_year < 70)
		timestruct.tm_year += 100;
	
	timestruct.tm_mon = (asn1_time->data[2]-'0') * 10 + (asn1_time->data[3]-'0') - 1;
	timestruct.tm_mday = (asn1_time->data[4]-'0') * 10 + (asn1_time->data[5]-'0');
	timestruct.tm_hour = (asn1_time->data[6]-'0') * 10 + (asn1_time->data[7]-'0');
	timestruct.tm_min = (asn1_time->data[8]-'0') * 10 + (asn1_time->data[9]-'0');
	timestruct.tm_sec = (asn1_time->data[10]-'0') * 10 + (asn1_time->data[11]-'0');

#if LL_WINDOWS
	return LLDate((F64)_mkgmtime(&timestruct));
#else // LL_WINDOWS
	return LLDate((F64)timegm(&timestruct));
#endif // LL_WINDOWS
}
Ejemplo n.º 4
0
time_t
nv_mkgmtime(struct tm *tm)
{
#if NV_MSVC
	return _mkgmtime(tm);
#else	
	time_t ret;
	const char *tz;
	
#  if _OPENMP
#    pragma omp critical (nv_mkgmtime)
#  endif
	{
		tz = nv_getenv("TZ");
		nv_setenv("TZ", "");
		tzset();
		ret = mktime(tm);
		if (tz) {
			nv_setenv("TZ", tz);
		} else {
			nv_unsetenv("TZ");
		}
		tzset();
	}
	
	return ret;
#endif	
}
Ejemplo n.º 5
0
    time_t date_time::to_time(const tm_type& tm, bool check_wday) {
        assert_in_range(tm, check_wday);
        time_t t;
        tm_type tt = tm;
#ifdef _WIN32
        t = _mkgmtime(&tt);
#else
        t = timegm(&tt);
#endif
        if (t == NULL_TIME)
            throw std::invalid_argument("invalid time structure on conversion to date and time");
        // Check that tm is canonical.
        std::string err;
        if (check_wday && tm.tm_wday != tt.tm_wday)
            err = std::string("week day (1-7) incorrect: ") + uripp::convert(tm.tm_wday + 1);
        else if (tm.tm_mday != tt.tm_mday)
            err = std::string("month day (1-31) incorrect: ") + uripp::convert(tm.tm_mday);
        else if (tm.tm_sec != tt.tm_sec)
            err = std::string("second (0-60) incorrect: ") + uripp::convert(tm.tm_sec);
        if (!err.empty()) {
            std::ostringstream oss;
            oss << "time structure for date (YYY-MM-DD) "
                << (tm.tm_year + 1900) << "-"
                << std::setw(2) << std::setfill('0') << (tm.tm_mon + 1) << "-"
                << std::setw(2) << std::setfill('0') << tm.tm_mday << ": "
                << err;
            throw std::invalid_argument(oss.str());
        }
        return t;
    }
Ejemplo n.º 6
0
void DateTime::UpdateUTCDateToTimePoint()
{
#ifdef MEDUSA_WINDOWS
	auto val = _mkgmtime(&mDate);
#else
	auto val = mktime(&mDate) - timezone;
#endif
	mTimePoint = std::chrono::system_clock::from_time_t(val);

}
Ejemplo n.º 7
0
int64_t os_timegm(date_t* date)
{
  struct tm tm;
  date_to_tm(date, &tm);

#ifdef PLATFORM_IS_WINDOWS
  return _mkgmtime(&tm);
#else
  return timegm(&tm);
#endif
}
Ejemplo n.º 8
0
        inline time_t parse_timestamp(const char* str) {
            static const int mon_lengths[] = {
                31, 29, 31, 30, 31, 30,
                31, 31, 30, 31, 30, 31
            };
            if (str[ 0] >= '0' && str[ 0] <= '9' &&
                str[ 1] >= '0' && str[ 1] <= '9' &&
                str[ 2] >= '0' && str[ 2] <= '9' &&
                str[ 3] >= '0' && str[ 3] <= '9' &&
                str[ 4] == '-' &&
                str[ 5] >= '0' && str[ 5] <= '9' &&
                str[ 6] >= '0' && str[ 6] <= '9' &&
                str[ 7] == '-' &&
                str[ 8] >= '0' && str[ 8] <= '9' &&
                str[ 9] >= '0' && str[ 9] <= '9' &&
                str[10] == 'T' &&
                str[11] >= '0' && str[11] <= '9' &&
                str[12] >= '0' && str[12] <= '9' &&
                str[13] == ':' &&
                str[14] >= '0' && str[14] <= '9' &&
                str[15] >= '0' && str[15] <= '9' &&
                str[16] == ':' &&
                str[17] >= '0' && str[17] <= '9' &&
                str[18] >= '0' && str[18] <= '9' &&
                str[19] == 'Z') {
                struct tm tm;
                tm.tm_year = (str[ 0] - '0') * 1000 +
                             (str[ 1] - '0') *  100 +
                             (str[ 2] - '0') *   10 +
                             (str[ 3] - '0')        - 1900;
                tm.tm_mon  = (str[ 5] - '0') * 10 + (str[ 6] - '0') - 1;
                tm.tm_mday = (str[ 8] - '0') * 10 + (str[ 9] - '0');
                tm.tm_hour = (str[11] - '0') * 10 + (str[12] - '0');
                tm.tm_min  = (str[14] - '0') * 10 + (str[15] - '0');
                tm.tm_sec  = (str[17] - '0') * 10 + (str[18] - '0');
                tm.tm_wday = 0;
                tm.tm_yday = 0;
                tm.tm_isdst = 0;
                if (tm.tm_year >= 0 &&
                    tm.tm_mon  >= 0 && tm.tm_mon  <= 11 &&
                    tm.tm_mday >= 1 && tm.tm_mday <= mon_lengths[tm.tm_mon] &&
                    tm.tm_hour >= 0 && tm.tm_hour <= 23 &&
                    tm.tm_min  >= 0 && tm.tm_min  <= 59 &&
                    tm.tm_sec  >= 0 && tm.tm_sec  <= 60) {
#ifndef _WIN32
                    return timegm(&tm);
#else
                    return _mkgmtime(&tm);
#endif
                }
            }
            throw std::invalid_argument{"can not parse timestamp"};
        }
Ejemplo n.º 9
0
time_t Util::sdTime::MakeGmTime(tm& timeUtc)
{
#if (_MSC_VER < MSVC_VER_2005)
    // VC++ 2003 doesn't have _mkgmtime
    // This does not seem to work properly with DST time zones sometimes - if that's of any concern for you, please upgrade your compiler :)
    TIME_ZONE_INFORMATION tzi;
    GetTimeZoneInformation(&tzi);
    const time_t timeUtcTimeT = mktime(&timeUtc) - tzi.Bias * 60;
#else
    const time_t timeUtcTimeT = _mkgmtime(&timeUtc);
#endif
    return timeUtcTimeT;
}
Ejemplo n.º 10
0
//-----------------------------------------------------------------------------
unsigned TTime::toUnixStamp() const
{
    struct tm utc;
    Date_Time(m_julianDate, &utc);

#if defined(_WIN32)
    time_t epoch = _mkgmtime(&utc);
#else
    time_t epoch = timegm(&utc);
#endif

    return (unsigned)epoch;
}
Ejemplo n.º 11
0
LEMON_SYS_API LemonTime LemonDateTimeToTime(
	__lemon_in const LemonDateTime * now,
	__lemon_inout LemonErrorInfo * errorCode){

		LEMON_RESET_ERRORINFO(*errorCode);

		time_t t = 0;

		tm current;

		LemonTime result = {0};

		current.tm_year = now->Year - 1900;

		current.tm_mon = now->Month;

		current.tm_mday = now->DayOfMonth;

		current.tm_yday = now->DayOfYear;

		current.tm_wday = now->DayOfWeek;

		current.tm_hour = now->Hour;

		current.tm_min = now->Minute;

		current.tm_sec = now->Second;

		if(now->UTC){
			t = _mkgmtime(&current);
		}else{
			t = mktime(&current);
		}

		if(-1 == t){
			LEMON_POSIX_ERROR(*errorCode,errno);

			return result;
		}

		result.Seconds = t;

		result.Microseconds = now->Microseconds;

		return result;
}
Ejemplo n.º 12
0
   time_t DateTime::GetTime() const
   {
      struct tm mt;
      mt.tm_mon = mMonths - 1;
      mt.tm_mday = mDays;
      mt.tm_year = mYears - 1900;
      mt.tm_hour = mHours;
      mt.tm_min = mMinutes;
      mt.tm_sec = mSeconds;
      mt.tm_isdst = 0;


      /**
         On many systems it is ambiguous if mktime() assumes the input is in
         GMT, or local timezone.  To address this, a new function called
         timegm() is appearing.  It works exactly like mktime() but
         explicitely interprets the input as GMT.

         timegm() is available and documented under FreeBSD.  It is
         available, but completely undocumented on my current Debian 2.1
         distribution.

         In the absence of timegm() we have to guess what mktime() might do.

         Many older BSD style systems have a mktime() that assumes the input
         time in GMT.  But FreeBSD explicitly states that mktime() assumes
         local time zone

         The mktime() on many SYSV style systems (such as Linux) usually
         returns its result assuming you have specified the input time in
         your local timezone.  Therefore, in the absence if timegm() you
         have to go to extra trouble to convert back to GMT.

         If you are having problems with incorrectly positioned astronomical
         bodies, this is a really good place to start looking.
      */
#ifdef DELTA_WIN32
      // mktime on windows adjusts for time zone, and we really don't want that
      time_t ret = _mkgmtime(&mt);
#else
      time_t ret = timegm(&mt);
#endif

      return ret;
   }
Ejemplo n.º 13
0
// set the value of a property
qbool oDateTime::setProperty(qlong pPropID,EXTfldval &pNewValue,EXTCompInfo* pECI) {
	// most anum properties are managed by Omnis but some we need to do ourselves, no idea why...
	
	switch (pPropID) {
		case oDT_localtime: {
			datestamptype omnisstamp;
			qbool success;
			pNewValue.getDate(omnisstamp, dpFdtimeC, &success);
			
			if (success) {
				struct tm timestruct;
				
				OmnisToTimeStruct(omnisstamp, timestruct);
				
				setTimestamp(mktime(&timestruct));
			};
			return qtrue;
		}; break;
		case oDT_utctime: {
			datestamptype omnisstamp;
			qbool success;
			pNewValue.getDate(omnisstamp, dpFdtimeC, &success);
			
			if (success) {
				struct tm timestruct;
				
				OmnisToTimeStruct(omnisstamp, timestruct);
				
#ifdef iswin32
				setTimestamp(_mkgmtime(&timestruct));
#else
				setTimestamp(timegm(&timestruct));
#endif
			};
			return qtrue;
		}; break;
		default:
			return oBaseNVComponent::setProperty(pPropID, pNewValue, pECI);
			break;
	};
};
Ejemplo n.º 14
0
    /**Parse time. Currently supports only UTC 'YYYY-MM-DDTHH:MM:SS' with optional trailing Z.*/
    inline time_t parse_iso_time(const std::string &str)
    {
        auto strp = str.c_str();
        auto len = str.size();
        if (len < sizeof("YYYY-MM-DDTHH:MM:SS") - 1) throw std::runtime_error("Invalid time " + str);
        if (len > sizeof("YYYY-MM-DDTHH:MM:SSZ") - 1) throw std::runtime_error("Invalid time " + str);
        //validate static components
        if (len == sizeof("YYYY-MM-DDTHH:MM:SSZ") - 1 && str[19] != 'Z') throw std::runtime_error("Invalid time " + str);
        if (strp[4] != '-' || strp[7] != '-' || strp[10] != 'T' || strp[13] != ':' || strp[16] != ':')
            throw std::runtime_error("Invalid time " + str);
        //parse numbers
        tm tm;

        tm.tm_year = parse_time_num<4>(strp + 0, str);
        tm.tm_mon = parse_time_num<2>(strp + 5, str);
        tm.tm_mday = parse_time_num<2>(strp + 8, str);

        tm.tm_hour = parse_time_num<2>(strp + 11, str);
        tm.tm_min = parse_time_num<2>(strp + 14, str);
        tm.tm_sec = parse_time_num<2>(strp + 17, str);
        //adjust for tm
        tm.tm_year -= 1900;
        tm.tm_mon -= 1;
        tm.tm_isdst = 0;
        //validate
        if (tm.tm_year < 0 || tm.tm_year > 1100 ||
            tm.tm_mon < 0 || tm.tm_mon > 11 ||
            tm.tm_mday < 1 || tm.tm_mday > 31 ||
            tm.tm_hour < 0 || tm.tm_hour > 23 ||
            tm.tm_min < 0 || tm.tm_min > 59 ||
            tm.tm_sec < 0 || tm.tm_sec > 60)
        {
            throw std::runtime_error("Invalid time " + str);
        }
        //convert to time_t
#ifdef _MSC_VER
        return _mkgmtime(&tm);
#else
        return timegm(&tm);
#endif
    }
Ejemplo n.º 15
0
void GetDateFromYYMMDDHHMMSS(char *str, TCHAR* formattedDate, size_t len)
{
	struct tm tm;
	int year = GetDigitsFromString(str, 0);
	if (year < 50)
	{
		year += 100;
	}

	tm.tm_year	= year;
	tm.tm_mon	= GetDigitsFromString(str, 2) - 1;
	tm.tm_mday	= GetDigitsFromString(str, 4);
	tm.tm_hour	= GetDigitsFromString(str, 6);
	tm.tm_min	= GetDigitsFromString(str, 8);
	tm.tm_sec	= 0;

	time_t t = str[strlen(str) - 1] == 'Z' ? _mkgmtime(&tm) : mktime(&tm);
	localtime_s(&tm, &t);

	swprintf_s(formattedDate, len, DATE_FORMAT, tm.tm_mon + 1, tm.tm_mday, tm.tm_year + 1900, tm.tm_hour, tm.tm_min);
}
Ejemplo n.º 16
0
/*!
 * \brief Parse RFC date and time string.
 *
 * This routine accepts RFC 850, RFC 1123 and asctime time formats.
 *
 * \param str Pointer to the date and time string.
 *
 * \return Number of seconds since epoch or -1 in case of any error.
 */
time_t RfcTimeParse(CONST char *str)
{
    struct _tm dts = { 0, 0, 0, 1, 0, 0, 0, 0, 0 };

    /* Skip leading whitespace. */
    str = skip_spaces(str);

    /* Skip weekday, optional in RFC 822. */
    if (isalpha((unsigned char)*str)) {
        while (*str && *str != ' ' && *str != '\t')
            str++;
        str = skip_spaces(str);
    }

    if (isalpha((unsigned char)*str)) {
        /* asctime format 'Fri Feb 2 2007 07:30:05'. */
        str = TimeParseMonth(str, &dts.tm_mon);
        str = skip_spaces(str);
        str = parse_digits(str, &dts.tm_mday);
        str = skip_spaces(str);
        str = TimeParseYear(str, &dts.tm_year);
        str = skip_spaces(str);
        str = TimeParseHms(str, &dts.tm_hour, &dts.tm_min, &dts.tm_sec);
    }
    else if (*str) {
        /* RFC 850 'Friday, 02-Feb-2007 07:30:05 GMT'. */
        /* RFC 1123 'Fri, 02 Feb 2007 07:30:05 GMT'. */
        str = TimeParseDmy(str, &dts.tm_mday, &dts.tm_mon, &dts.tm_year);
        str = skip_spaces(str);
        str = TimeParseHms(str, &dts.tm_hour, &dts.tm_min, &dts.tm_sec);
    }
    str = skip_spaces(str);
    if (    (strcmp(str, "GMT") == 0)
         || (strcmp(str, "UTC") == 0)
       )
    {
        return mktime(&dts);
    }
    return _mkgmtime(&dts);
}
Ejemplo n.º 17
0
        /**
         * Construct timestamp from ISO date/time string.
         * Throws std::invalid_argument, if the timestamp can not be parsed.
         */
        explicit Timestamp(const char* timestamp) {
#ifndef _WIN32
            struct tm tm {
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            };
            if (strptime(timestamp, timestamp_format(), &tm) == nullptr) {
                throw std::invalid_argument("can't parse timestamp");
            }
            m_timestamp = static_cast<uint32_t>(timegm(&tm));
#else
            struct tm tm;
            int n = sscanf(timestamp, "%4d-%2d-%2dT%2d:%2d:%2dZ", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
            if (n != 6) {
                throw std::invalid_argument("can't parse timestamp");
            }
            tm.tm_year -= 1900;
            tm.tm_mon--;
            tm.tm_wday = 0;
            tm.tm_yday = 0;
            tm.tm_isdst = 0;
            m_timestamp = static_cast<uint32_t>(_mkgmtime(&tm));
#endif
        }
Ejemplo n.º 18
0
        time_t IgniteTimeGm(const tm& time)
        {
            tm tmc = time;

            return _mkgmtime(&tmc);
        }
Ejemplo n.º 19
0
ChattyPostDataRef getChattyPostDataRefFromJSONPost(const JsonTree& post)
{
   ChattyPostDataRef post_data_ref = ChattyPostData::create();

   post_data_ref->m_id = fromString<uint32_t>(post["id"].getValue());
   post_data_ref->m_thread_id = fromString<uint32_t>(post["threadId"].getValue());
   post_data_ref->m_parent_id = fromString<uint32_t>(post["parentId"].getValue());
   post_data_ref->m_author = post["author"].getValue();
   post_data_ref->m_body = post["body"].getValue();

   replaceEncodingsInString(post_data_ref->m_body);

   std::string strvalue = post["category"].getValue();
   if(strvalue.length() > 0)
   {
           if(strvalue == "ontopic")        post_data_ref->m_category = category_type::NORMAL;
      else if(strvalue == "nws")            post_data_ref->m_category = category_type::NWS;
      else if(strvalue == "stupid")         post_data_ref->m_category = category_type::STUPID;
      else if(strvalue == "political")      post_data_ref->m_category = category_type::POLITICAL;
      else if(strvalue == "tangent")        post_data_ref->m_category = category_type::OFFTOPIC;
      else if(strvalue == "informative")    post_data_ref->m_category = category_type::INFORMATIVE;
      else if(strvalue == "nuked")          post_data_ref->m_category = category_type::NUKED;
   }

   strvalue = post["date"].getValue();
   if(strvalue.length() > 0)
   {
      std::tm post_time;
      memset(&post_time, 0, sizeof(std::tm));
      
#if defined(CINDER_MSW)
      sscanf_s(strvalue.c_str(), "%d-%d-%dT%d:%d",
               &post_time.tm_year,
               &post_time.tm_mon,
               &post_time.tm_mday,
               &post_time.tm_hour,
               &post_time.tm_min);
#else
      sscanf(strvalue.c_str(), "%d-%d-%dT%d:%d",
               &post_time.tm_year,
               &post_time.tm_mon,
               &post_time.tm_mday,
               &post_time.tm_hour,
               &post_time.tm_min);
#endif

      post_time.tm_year -= 1900;
      post_time.tm_mon -= 1;

#if defined(CINDER_MSW)
      post_data_ref->m_date_time = _mkgmtime(&post_time);
#else
      post_data_ref->m_date_time = timegm(&post_time); // and I have no idea if this is right
#endif
      // if mac doesn't have _mkgmtime, need to find a way to convert UTC to local
      //post_data_ref->m_date_time = std::mktime(&post_time);
   }

   if(post.hasChild("lols"))
   {
      const JsonTree& lols = post.getChild("lols");
      for(size_t lol_i = 0; lol_i < lols.getNumChildren(); lol_i++)
      {
         const JsonTree& lol = lols.getChild(lol_i);
         strvalue = lol["tag"].getValue();
         if(strvalue.length() > 0)
         {
            lol_type which_lol = LOL;
                 if(strvalue == "lol") which_lol = lol_type::LOL;
            else if(strvalue == "inf") which_lol = lol_type::INF;
            else if(strvalue == "unf") which_lol = lol_type::UNF;
            else if(strvalue == "tag") which_lol = lol_type::TAG;
            else if(strvalue == "wtf") which_lol = lol_type::WTF;
            else if(strvalue == "ugh") which_lol = lol_type::UGH;

            post_data_ref->m_lol_count[which_lol] = fromString<unsigned int>(lol["count"].getValue());
         }
      }
   }

   return post_data_ref;
}
Ejemplo n.º 20
0
time_t rtc_timegm(struct tm *tm)
{
	return _mkgmtime(tm);
}
Ejemplo n.º 21
0
time_t
timegm(struct tm* tm)
{
    // Timezone independant version
    return _mkgmtime(tm);
}
Ejemplo n.º 22
0
time_t rtc_timegm(struct tm *tm)
{
	struct tm modified;
	memcpy(&modified, tm, sizeof(modified));
	return _mkgmtime(&modified);
}
Ejemplo n.º 23
0
Archivo: date.c Proyecto: 0branch/boron
/*
  Read ISO 8601 date and time notation (extended format only).
*/
double ur_stringToDate( const char* start, const char* end, const char** pos )
{
    // yyyy-mm-ddThh:mm:ss.fff[+/-hh:mm]
    // _123456789_123456789_123456789

    struct tm tmp;
    const char* it;
    double sec = 0.0;
    int utc = 0;
    int offset;
    int len = end - start;

    if( (len < 10) || (start[4] != '-') || (start[7] != '-') )
    {
        if( pos )
            *pos = start;
        return 0.0;
    }

    // Handle date portion.

    tmp.tm_year  = (twoInt( start ) * 100 + twoInt( start + 2 )) - 1900;
    tmp.tm_mon   = twoInt( start + 5 ) - 1;
    tmp.tm_mday  = twoInt( start + 8 );
    tmp.tm_hour  = 0;
    tmp.tm_min   = 0;
    tmp.tm_sec   = 0;
    tmp.tm_isdst = -1;


    // Handle time portion.  Both 'T' and '/' are accepted as separator.

    it = start + 10;

    if( (len < 13) || (*it != 'T' && *it != '/') )
        goto done;
    ++it;
    len = end - it;

    tmp.tm_hour = twoInt( it );
    it += 2;
    if( (len < 5) || (*it != ':') )
        goto done;

    tmp.tm_min = twoInt( ++it );
    it += 2;
    if( it == end )
        goto done;
    if( *it == ':' )
    {
        ++it;
        sec = str_toDouble( it, end, &it );
        if( it == end )
            goto done;
    }


    // Handle UTC offset.

    switch( *it )
    {
        case '+':
            utc = 1;
            break;
        case '-':
            utc = -1;
            break;
        case 'Z':
            utc = 1;
            ++it;
        default:
            goto done;
    }
    ++it;
    len = end - it;
    if( len < 2 )
        goto done;
    offset = twoInt( it );
    tmp.tm_hour += (utc < 0) ? offset : -offset;
    it += 2;
    if( (len < 5) || (*it != ':') )
        goto done;
    ++it;
    offset = twoInt( it );
    tmp.tm_min += (utc < 0) ? offset : -offset;
    it += 2;

done:

    if( pos )
        *pos = it;
#ifdef _WIN32
#if _MSC_VER >= 1400
    return sec + (double) (utc ? _mkgmtime( &tmp ) : mktime( &tmp ));
#else
    return sec + (double) mktime( &tmp );   // TODO: Handle utc.
#endif
#elif defined(__sun__)
    return sec + (double) mktime( &tmp );   // TODO: Handle utc.
#else
    return sec + (double) (utc ? timegm( &tmp ) : mktime( &tmp ));
#endif
}