os/ossrv/genericopenlibs/cstdlib/LTIME/TIME.CPP
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// Mapping between EPOC32 time and libc time
sl@0
    15
// The basic philosophy is to work in time_t units (TInt) which
sl@0
    16
// will be essentially TTimeIntervalSeconds from the start of Unix time.
sl@0
    17
// To stay compliant with the C-Standard (with reference to C99 draft), we  
sl@0
    18
// set the meaning of time_t to be Universal time.
sl@0
    19
// 
sl@0
    20
//
sl@0
    21
sl@0
    22
#include <e32std.h>
sl@0
    23
#include "LTIME.H"
sl@0
    24
#include <sys/reent.h>	    // for _ASCTIME_SIZE
sl@0
    25
#include <sys/time.h>	    // for gettimeofday
sl@0
    26
#include <time.h>
sl@0
    27
#include <string.h>	    // for strcpy
sl@0
    28
sl@0
    29
#define UNIX_BASE   TTime(MAKE_TINT64(0x00dcddb3,0x0f2f8000))    // 00:00, Jan 1st 1970
sl@0
    30
sl@0
    31
// Utility routines for converting between representations
sl@0
    32
sl@0
    33
static struct tm& as_struct_tm (const time_t& t, struct tm& res)
sl@0
    34
    {
sl@0
    35
    TTime us = UNIX_BASE + TTimeIntervalSeconds(t);
sl@0
    36
    TDateTime dt = us.DateTime();
sl@0
    37
sl@0
    38
    res.tm_sec  = dt.Second();
sl@0
    39
    res.tm_min  = dt.Minute();
sl@0
    40
    res.tm_hour = dt.Hour();
sl@0
    41
    res.tm_mday = dt.Day() + 1;
sl@0
    42
    res.tm_mon  = dt.Month();
sl@0
    43
    res.tm_year = dt.Year() - 1900;
sl@0
    44
sl@0
    45
    // EPOC32 counts the year day as Jan 1st == day 1
sl@0
    46
    res.tm_yday = us.DayNoInYear() - 1;
sl@0
    47
sl@0
    48
    // EPOC32 counts the weekdays from 0==Monday to 6==Sunday
sl@0
    49
    res.tm_wday = us.DayNoInWeek() + 1;
sl@0
    50
    if (res.tm_wday==7)
sl@0
    51
	    res.tm_wday=0;	// Sunday==0 in a struct tm
sl@0
    52
sl@0
    53
    // newlib just sets this field to -1
sl@0
    54
    // tm_isdst doesn't really make sense here since we don't 
sl@0
    55
    // know the locale for which to interpret this time.
sl@0
    56
sl@0
    57
    res.tm_isdst = -1;
sl@0
    58
sl@0
    59
    return res;
sl@0
    60
    }
sl@0
    61
sl@0
    62
static void as_ttime (const struct tm& p, TTime& res, TBool normalise=EFalse)
sl@0
    63
    {
sl@0
    64
    TDateTime dt;
sl@0
    65
    TInt err = dt.Set(p.tm_year+1900, (enum TMonth)p.tm_mon, p.tm_mday-1, 
sl@0
    66
	p.tm_hour, p.tm_min, p.tm_sec, 0);
sl@0
    67
    if (err == KErrNone)
sl@0
    68
	{
sl@0
    69
	res = dt;
sl@0
    70
	return;
sl@0
    71
	}
sl@0
    72
    if (!normalise)
sl@0
    73
	{
sl@0
    74
	res = TInt64(-1);
sl@0
    75
	return;
sl@0
    76
	}
sl@0
    77
    // Try to normalise things (for mktime)
sl@0
    78
    dt.Set(p.tm_year+1900, EJanuary, 0, 0, 0, 0, 0);
sl@0
    79
    res = dt;
sl@0
    80
    res += TTimeIntervalMonths (p.tm_mon);
sl@0
    81
    res += TTimeIntervalDays   (p.tm_mday-1);
sl@0
    82
    res += TTimeIntervalHours  (p.tm_hour);
sl@0
    83
    res += TTimeIntervalMinutes(p.tm_min);
sl@0
    84
    res += TTimeIntervalSeconds(p.tm_sec);
sl@0
    85
    }
sl@0
    86
sl@0
    87
inline void as_ttime (const time_t& p, TTime& res)
sl@0
    88
    {
sl@0
    89
    res = UNIX_BASE + TTimeIntervalSeconds(p);
sl@0
    90
    }
sl@0
    91
sl@0
    92
GLDEF_C time_t as_time_t(const TTime& t)
sl@0
    93
    {
sl@0
    94
    TTimeIntervalSeconds res;
sl@0
    95
    TInt err = t.SecondsFrom(UNIX_BASE, res);
sl@0
    96
    if (err)
sl@0
    97
	return -1;
sl@0
    98
    else
sl@0
    99
	return res.Int();
sl@0
   100
    }
sl@0
   101
sl@0
   102
// Utility routine for formatting a TTime into a descriptor using the
sl@0
   103
// UNIX ctime format. NB. EPOC32 abbreviations can be up to KMaxDayNameAbb
sl@0
   104
// and KMaxMonthNameAbb characters (both == 4). The %F is needed to
sl@0
   105
// force the meanings of %D, %Y etc.
sl@0
   106
sl@0
   107
static TDes8& as_string (TTime& t, TDes8& res)
sl@0
   108
    {
sl@0
   109
    // UNICODE problem - t.Format operates on TDes => TDes16
sl@0
   110
sl@0
   111
#if !defined(_UNICODE)
sl@0
   112
    TRAPD(err, t.FormatL(res, _L("%F%*E %*N %D %H:%T:%S %Y")));
sl@0
   113
#else
sl@0
   114
    TBuf<_ASCTIME_SIZE> unires;
sl@0
   115
    TRAPD(err, t.FormatL(unires, _L("%F%*E %*N %D %H:%T:%S %Y")));
sl@0
   116
    if (!err)
sl@0
   117
	res.Copy(unires);
sl@0
   118
#endif
sl@0
   119
    if (err)
sl@0
   120
	res = _L8("Error\n");
sl@0
   121
    else
sl@0
   122
	res.Append('\n');
sl@0
   123
    return res;
sl@0
   124
    }
sl@0
   125
sl@0
   126
/**
sl@0
   127
Intended Usage:	Utility routine for converting from UTC to localtime.
sl@0
   128
@return   		Localtime in seconds
sl@0
   129
@param 			aUniversalTime Universaltime in seconds
sl@0
   130
*/
sl@0
   131
inline time_t toLocal (const time_t aUniversalTime)
sl@0
   132
    {
sl@0
   133
    TTimeIntervalSeconds offset = User::UTCOffset();
sl@0
   134
    return aUniversalTime + offset.Int();
sl@0
   135
    }
sl@0
   136
sl@0
   137
/**
sl@0
   138
Intended Usage:	Utility routine for converting from localtime to UTC.
sl@0
   139
				However, having decided that time_t is always Universal time, toGMT is empty.
sl@0
   140
@return			Localtime Universaltime in seconds
sl@0
   141
@param 			aLocalTime Universaltime in seconds (meaning of time_t is UTC)
sl@0
   142
*/
sl@0
   143
inline time_t toGMT (const time_t aLocalTime)
sl@0
   144
    {
sl@0
   145
    return aLocalTime;
sl@0
   146
    }
sl@0
   147
sl@0
   148
// external interface for the C library
sl@0
   149
sl@0
   150
extern "C" {
sl@0
   151
/**
sl@0
   152
Intended Usage:	Get current UTC time.
sl@0
   153
				Get the number of seconds elapsed since 00:00 hours, 
sl@0
   154
				Jan 1, 1970 UTC from the system clock.
sl@0
   155
@return   		Elapsed time in seconds, as described.
sl@0
   156
@param 			p Location where to store the retrieved value. 
sl@0
   157
				If this is NULL the value is not stored. 
sl@0
   158
				But it is still returned by the function.
sl@0
   159
				time_t is generally defined by default to long.
sl@0
   160
*/
sl@0
   161
EXPORT_C time_t time (time_t* p)
sl@0
   162
    {
sl@0
   163
    TTime t;
sl@0
   164
    t.UniversalTime();
sl@0
   165
	
sl@0
   166
    time_t res = as_time_t(t);
sl@0
   167
    if (p)
sl@0
   168
		*p = res;
sl@0
   169
    return res;
sl@0
   170
    }
sl@0
   171
/**
sl@0
   172
Intended Usage:	The gettimeofday function obtains the current UTC time, which is 
sl@0
   173
				expressed as seconds and microseconds since 00:00:00 Coordinated Universal Time (UTC), 
sl@0
   174
				January 1, 1970, and stores it in a timeval structure.
sl@0
   175
				Please note that tz_minuteswest includes daytime saving. The struct member tz_dsttime is no 
sl@0
   176
				longer supported by Symbian OS and therefore set to Zero.
sl@0
   177
@publishedAll
sl@0
   178
@released
sl@0
   179
@return
sl@0
   180
@param 			tp	Struct with two members of type long (tv_sec, tv_usec)
sl@0
   181
@param 			tzp Struct with two members of type integer (tz_minuteswest, tz_dsttime)
sl@0
   182
*/
sl@0
   183
EXPORT_C int gettimeofday (struct timeval *tp, struct timezone *tzp)
sl@0
   184
    {
sl@0
   185
    if (tp)
sl@0
   186
	{
sl@0
   187
	TTime t;
sl@0
   188
	t.UniversalTime();
sl@0
   189
	
sl@0
   190
	TTimeIntervalSeconds sec;
sl@0
   191
	TInt err = t.SecondsFrom(UNIX_BASE, sec);
sl@0
   192
	if (err)
sl@0
   193
	    return -1;
sl@0
   194
	else
sl@0
   195
	    tp->tv_sec = sec.Int();
sl@0
   196
	t -= sec;
sl@0
   197
	TTimeIntervalMicroSeconds usec = t.MicroSecondsFrom(UNIX_BASE);
sl@0
   198
	TInt64 hackyfix = usec.Int64();	// because GetTInt() isn't declared const
sl@0
   199
	tp->tv_usec = I64INT(hackyfix);
sl@0
   200
	}
sl@0
   201
    if (tzp)
sl@0
   202
	{
sl@0
   203
	    tzp->tz_minuteswest = (User::UTCOffset().Int())/60;
sl@0
   204
	    tzp->tz_dsttime = 0;
sl@0
   205
	}
sl@0
   206
    return 0;
sl@0
   207
    }
sl@0
   208
/**
sl@0
   209
Return number of clock ticks since process start.
sl@0
   210
Returns the number of clock ticks elapsed.
sl@0
   211
A macro constant called CLK_TCK defines the relation betwen
sl@0
   212
clock tick and second (clock ticks per second).
sl@0
   213
@return   The number of clock ticks elapsed since start.
sl@0
   214
clock_t type is defined by default as long int by most compilers.
sl@0
   215
*/
sl@0
   216
EXPORT_C clock_t clock ()
sl@0
   217
    {
sl@0
   218
    return -1;
sl@0
   219
    }
sl@0
   220
/**
sl@0
   221
A reentrant version of gmtime(). 
sl@0
   222
*/
sl@0
   223
EXPORT_C struct tm* gmtime_r (const time_t* p, struct tm* res)
sl@0
   224
    {
sl@0
   225
    return &as_struct_tm( toGMT(*p), *res);
sl@0
   226
    }
sl@0
   227
/**
sl@0
   228
A reentrant version of localtime().
sl@0
   229
*/
sl@0
   230
EXPORT_C struct tm* localtime_r (const time_t* p, struct tm* res)
sl@0
   231
    {
sl@0
   232
    return &as_struct_tm( toLocal(*p), *res);
sl@0
   233
    }
sl@0
   234
/**
sl@0
   235
Convert tm structure to time_t value.
sl@0
   236
Checks the members of the tm structure passed as parameter ptm 
sl@0
   237
adjusting the values if the ones provided are not in the possible range 
sl@0
   238
or they are not complete or mistaken and then translates that structure 
sl@0
   239
to a time_t value (seconds elapsed since Jan 1, 1970) that is returned.
sl@0
   240
The original values of tm_wday and tm_yday members of ptm are ignored 
sl@0
   241
and filled with the correspondent ones to the calculated date. 
sl@0
   242
The range of tm_mday is not checked until tm_mon and tm_year are determined.
sl@0
   243
@return A time_t value corresponding to the date and time passed in ptm parameter.
sl@0
   244
On error, a -1 value is returned.
sl@0
   245
@param p Pointer to a tm structure, that contains data to be computed.
sl@0
   246
*/
sl@0
   247
EXPORT_C time_t mktime (struct tm *p)
sl@0
   248
    {
sl@0
   249
    TTime t;
sl@0
   250
    as_ttime(*p, t, ETrue);
sl@0
   251
    time_t res = as_time_t(t);
sl@0
   252
sl@0
   253
    as_struct_tm(res, *p);    // Must also update the struct tm passed to us...
sl@0
   254
    return res;
sl@0
   255
    }
sl@0
   256
sl@0
   257
/**
sl@0
   258
A reentrant version of asctime().
sl@0
   259
*/
sl@0
   260
EXPORT_C char* asctime_r (const struct tm *p, char* result)
sl@0
   261
    {
sl@0
   262
    TTime t;
sl@0
   263
    as_ttime(*p, t);
sl@0
   264
sl@0
   265
    TPtr8 rDes((TUint8*)result, _ASCTIME_SIZE);
sl@0
   266
sl@0
   267
    return (char *)as_string(t, rDes).PtrZ();
sl@0
   268
    }
sl@0
   269
sl@0
   270
/**
sl@0
   271
A reentrant version of ctime().
sl@0
   272
*/
sl@0
   273
EXPORT_C char* ctime_r (const time_t* p, char* result)
sl@0
   274
    {
sl@0
   275
    TTime t;
sl@0
   276
    as_ttime(toLocal(*p), t);
sl@0
   277
sl@0
   278
    TPtr8 rDes((TUint8*)result, _ASCTIME_SIZE);
sl@0
   279
sl@0
   280
    return (char *)as_string(t, rDes).PtrZ();
sl@0
   281
    }
sl@0
   282
sl@0
   283
} // extern "C"