sl@0: // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Mapping between EPOC32 time and libc time sl@0: // The basic philosophy is to work in time_t units (TInt) which sl@0: // will be essentially TTimeIntervalSeconds from the start of Unix time. sl@0: // To stay compliant with the C-Standard (with reference to C99 draft), we sl@0: // set the meaning of time_t to be Universal time. sl@0: // sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include "reent.h" // for _ASCTIME_SIZE sl@0: #include // for gettimeofday sl@0: #include sl@0: #include // for strcpy sl@0: sl@0: #define UNIX_BASE TTime(MAKE_TINT64(0x00dcddb3,0x0f2f8000)) // 00:00, Jan 1st 1970 sl@0: sl@0: // Utility routines for converting between representations sl@0: sl@0: #ifdef __SYMBIAN_COMPILE_UNUSED__ sl@0: static struct tm& as_struct_tm (const time_t& t, struct tm& res) sl@0: { sl@0: TTime us = UNIX_BASE + TTimeIntervalSeconds(t); sl@0: TDateTime dt = us.DateTime(); sl@0: sl@0: res.tm_sec = dt.Second(); sl@0: res.tm_min = dt.Minute(); sl@0: res.tm_hour = dt.Hour(); sl@0: res.tm_mday = dt.Day() + 1; sl@0: res.tm_mon = dt.Month(); sl@0: res.tm_year = dt.Year() - 1900; sl@0: sl@0: // EPOC32 counts the year day as Jan 1st == day 1 sl@0: res.tm_yday = us.DayNoInYear() - 1; sl@0: sl@0: // EPOC32 counts the weekdays from 0==Monday to 6==Sunday sl@0: res.tm_wday = us.DayNoInWeek() + 1; sl@0: if (res.tm_wday==7) sl@0: res.tm_wday=0; // Sunday==0 in a struct tm sl@0: sl@0: // newlib just sets this field to -1 sl@0: // tm_isdst doesn't really make sense here since we don't sl@0: // know the locale for which to interpret this time. sl@0: sl@0: res.tm_isdst = -1; sl@0: sl@0: return res; sl@0: } sl@0: sl@0: static void as_ttime (const struct tm& p, TTime& res, TBool normalise=EFalse) sl@0: { sl@0: TDateTime dt; sl@0: TInt err = dt.Set(p.tm_year+1900, (enum TMonth)p.tm_mon, p.tm_mday-1, sl@0: p.tm_hour, p.tm_min, p.tm_sec, 0); sl@0: if (err == KErrNone) sl@0: { sl@0: res = dt; sl@0: return; sl@0: } sl@0: if (!normalise) sl@0: { sl@0: res = TInt64(-1); sl@0: return; sl@0: } sl@0: // Try to normalise things (for mktime) sl@0: dt.Set(p.tm_year+1900, EJanuary, 0, 0, 0, 0, 0); sl@0: res = dt; sl@0: res += TTimeIntervalMonths (p.tm_mon); sl@0: res += TTimeIntervalDays (p.tm_mday-1); sl@0: res += TTimeIntervalHours (p.tm_hour); sl@0: res += TTimeIntervalMinutes(p.tm_min); sl@0: res += TTimeIntervalSeconds(p.tm_sec); sl@0: } sl@0: sl@0: inline void as_ttime (const time_t& p, TTime& res) sl@0: { sl@0: res = UNIX_BASE + TTimeIntervalSeconds(p); sl@0: } sl@0: sl@0: #endif //__SYMBIAN_COMPILE_UNUSED__ sl@0: sl@0: sl@0: GLDEF_C time_t as_time_t(const TTime& t) sl@0: { sl@0: TTimeIntervalSeconds res; sl@0: TInt err = t.SecondsFrom(UNIX_BASE, res); sl@0: if (err) sl@0: return -1; sl@0: else sl@0: return res.Int(); sl@0: } sl@0: sl@0: #ifdef __SYMBIAN_COMPILE_UNUSED__ sl@0: // Utility routine for formatting a TTime into a descriptor using the sl@0: // UNIX ctime format. NB. EPOC32 abbreviations can be up to KMaxDayNameAbb sl@0: // and KMaxMonthNameAbb characters (both == 4). The %F is needed to sl@0: // force the meanings of %D, %Y etc. sl@0: sl@0: static TDes8& as_string (TTime& t, TDes8& res) sl@0: { sl@0: // UNICODE problem - t.Format operates on TDes => TDes16 sl@0: sl@0: #if !defined(_UNICODE) sl@0: TRAPD(err, t.FormatL(res, _L("%F%*E %*N %D %H:%T:%S %Y"))); sl@0: #else sl@0: TBuf<_ASCTIME_SIZE> unires; sl@0: TRAPD(err, t.FormatL(unires, _L("%F%*E %*N %D %H:%T:%S %Y"))); sl@0: if (!err) sl@0: res.Copy(unires); sl@0: #endif sl@0: if (err) sl@0: res = _L8("Error\n"); sl@0: else sl@0: res.Append('\n'); sl@0: return res; sl@0: } sl@0: #endif sl@0: sl@0: #ifdef __SYMBIAN_COMPILE_UNUSED__ sl@0: /* sl@0: Intended Usage: Utility routine for converting from UTC to localtime. sl@0: */ sl@0: inline time_t toLocal (const time_t aUniversalTime) sl@0: { sl@0: #ifndef __SERIES60_MRT_1_0 sl@0: TTimeIntervalSeconds offset = User::UTCOffset(); sl@0: return aUniversalTime + offset.Int(); sl@0: #else sl@0: TLocale locale; sl@0: return aUniversalTime + locale.UniversalTimeOffset().Int(); sl@0: #endif //__SERIES60_MRT_1_0 sl@0: } sl@0: sl@0: /* sl@0: Intended Usage: Utility routine for converting from localtime to UTC. sl@0: However, having decided that time_t is always Universal time, toGMT is empty. sl@0: */ sl@0: inline time_t toGMT (const time_t aLocalTime) sl@0: { sl@0: return aLocalTime; sl@0: } sl@0: #endif //__SYMBIAN_COMPILE_UNUSED__ sl@0: sl@0: // external interface for the C library sl@0: sl@0: extern "C" { sl@0: /* sl@0: Intended Usage: Get current UTC time. sl@0: Get the number of seconds elapsed since 00:00 hours, sl@0: Jan 1, 1970 UTC from the system clock. sl@0: */ sl@0: EXPORT_C time_t time (time_t* p) sl@0: { sl@0: TTime t; sl@0: t.UniversalTime(); sl@0: sl@0: time_t res = as_time_t(t); sl@0: if (p) sl@0: *p = res; sl@0: return res; sl@0: } sl@0: sl@0: sl@0: /* sl@0: Return number of clock ticks since process start. sl@0: Returns the number of clock ticks elapsed. sl@0: A macro constant called CLK_TCK defines the relation betwen sl@0: clock tick and second (clock ticks per second). sl@0: */ sl@0: sl@0: EXPORT_C clock_t clock () sl@0: { sl@0: int retval=-1; sl@0: RThread proc; sl@0: TTimeIntervalMicroSeconds iMicSecsFromEpoc; sl@0: TInt err=proc.GetCpuTime(iMicSecsFromEpoc); sl@0: sl@0: if(err) sl@0: { sl@0: return retval; sl@0: } sl@0: return I64INT(iMicSecsFromEpoc.Int64()); sl@0: } sl@0: }// extern "C" sl@0: sl@0: