[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [tyndur-devel] [PATCH] libc: gmtime() und localtime()



On Tue, Aug 11, 2009 at 09:10:04PM +0200, Andreas Freimuth wrote:
> 

> # HG changeset patch
> # User Andreas Freimuth <m.nemo@xxxxxxx>
> # Date 1250016661 -7200
> # Node ID 35b73a071d85076542f0e0f4e1a466a9e784a45d
> # Parent  8134734351cb5895acc183021bd8a6b9af38cd0a
> + libc: gmtime() und localtime()
>   localtime geht noch fest von UTC+1 aus

Vorneweg ein paar allgemeine Sachen: Die Codeformatierung ist so nicht
ganz in Ordnung (wir benutzen 4 Leerzeichen als Einrückung, du hast Tabs
geschickt; außerdem hast du manchmal übrige Leerzeichen am Zeilenende).
Und das Signed-off-by fehlt.

Die Details inline:

> 
> diff --git a/src/modules/include/time.h b/src/modules/include/time.h
> --- a/src/modules/include/time.h
> +++ b/src/modules/include/time.h
> @@ -46,6 +46,13 @@
>  
>  time_t time(time_t* t);
>  
> +/// Timestamp in tm-Struct einfuellen
> +struct tm* gmtime(const time_t* time_ptr);
> +struct tm* gmtime_r(const time_t* time_ptr, struct tm* result);
> +
> +struct tm* localtime(const time_t* time_ptr);
> +struct tm* localtime_r(const time_t* time_ptr, struct tm* result);
> +
>  #ifndef CONFIG_LIBC_NO_STUBS
>  /// Datum und Uhrzeit in einen String umwandeln
>  char* ctime(const time_t* time_ptr);
> @@ -53,11 +60,6 @@
>  /// Zeit und Datum als String
>  char* asctime(const struct tm* time_ptr);
>  
> -/// Timestamp in tm-Struct einfuellen
> -struct tm* gmtime(const time_t* time_ptr);
> -
> -struct tm* localtime(const time_t* time_ptr);
> -
>  time_t mktime(struct tm* time_ptr);
>  #endif
>  
> diff --git a/src/modules/lib/stdlibc/time.c b/src/modules/lib/stdlibc/time.c
> --- a/src/modules/lib/stdlibc/time.c
> +++ b/src/modules/lib/stdlibc/time.c
> @@ -30,18 +30,9 @@
>  #include <stdio.h>
>  #include <lost/config.h>
>  
> +static struct tm tm;
> +
>  #ifndef CONFIG_LIBC_NO_STUBS
> -static struct tm tm = {
> -    .tm_wday = 3,
> -    .tm_mday = 42,
> -    .tm_mon = 6,
> -    .tm_year = 1337,
> -    .tm_yday = 1337,
> -
> -    .tm_hour = 13,
> -    .tm_min = 37,
> -    .tm_sec = 42
> -};
>  static char* asctime_buf = "Wed Jun 42 13:37:42 1337\n";
>  static char* ctime_string = "Wed Jun 42 13:37:42 1337\n";
>  #endif
> @@ -71,30 +62,114 @@
>      return result;
>  }
>  
> -#ifndef CONFIG_LIBC_NO_STUBS
>  /**
> - * TODO
> - **/
> -struct tm* localtime(const time_t* time)
> + * Timestamp, unter Bachtung der Zeitzone, in tm-Struktur einfuellen
> + * 
> + * @param timer_ptr Pointer auf den Timestamp
> + * @param result Pointer auf die tm-Struktur in die 

Fehlt da nicht irgendwie ein halber Satz?

> + *
> + * @return result
> + */
> +struct tm* localtime_r(const time_t* time_ptr, struct tm* result)
>  {
> -    // TODO
> -    return &tm;
> +	/* FIXME hier wird fest von UTC+1 ausgegangen */
> +	time_t ltime = *time_ptr + 60*60;
> +	return gmtime_r(&ltime, result);
> +}
> +
> +/**
> + * Timestamp, unter Bachtung der Zeitzone, in tm-Struktur einfuellen
> + *
> + * @param timer_ptr Pointer auf den Timestamp
> + *
> + * @return Pointer auf die interne statisch allozierte tm-Struktur. Diese kann
> + *          bei jedem Aufruf einer Zeitfunktion ueberschrieben werden!
> + */
> +struct tm* localtime(const time_t* time_ptr)
> +{
> +    return localtime_r(time_ptr, &tm);
>  }
>  
>  /**
>   * Timestamp in tm-Struktur einfuellen
>   *
> - * @param time_ptr Pointer auf den Timestamp
> + * @param timer_ptr Pointer auf den Timestamp
> + * @param result Pointer auf die tm-Struktur in die 
> + *
> + * @return result
> + */
> +struct tm* gmtime_r(const time_t* timer_ptr, struct tm* result)
> +{
> +	static const int monat[2][12] = {
> +		{ 0,31,59,90,120,151,181,212,243,273,304,334},
> +		{ 0,31,60,91,121,152,182,213,244,274,305,335}
> +	};
> +	time_t time = *timer_ptr;
> +	int schaltjahr = 0;
> +
> +	/* die Uhrzeit ist noch einfach */
> +	result->tm_sec = time % 60;
> +	time /= 60;
> +	result->tm_min = time % 60;
> +	time /= 60;
> +	result->tm_hour = time % 24;
> +	time /= 24;
> +
> +	/* 01.01.70 wahr ein Donnerstag (5) */
> +	result->tm_wday = (time + 5) % 7;

Müßte Donnerstag nicht 4 sein? Die Manpage sagt 0 = Sonntag.

> +
> +	/* jetzt kommen die Schaltjahre ins Spiel */
> +
> +	/* rebase auf 1969-01-01 00:00:00 UTC 
> +	 * dann ist jedes 4. Jahr ein Schaltjahr
> +	 */
> +	time += 365;
> +
> +	int tmp_years = 69 + 4 * (time / (4*365 + 1));
> +	time %= 4*365 + 1;
> +	
> +	if( (time / 365) > 2 ) {
> +		schaltjahr = 1;
> +		result->tm_year = tmp_years + 3;
> +		result->tm_yday = time - 3*365 + 1;
> +	} else {
> +		result->tm_year = tmp_years + (time / 365);
> +		result->tm_yday = time % 365 + 1;
> +	}

tm_yday fängt bei 0 für 1. Januar an. Damit ist das + 1 dann eins
zuviel, oder?

> +	
> +	/* den richtigen monat raussuchen */
> +	if( monat[schaltjahr][result->tm_yday / 30] > result->tm_yday ) {
> +		result->tm_mon = (result->tm_yday / 30) - 1;
> +	} else if( monat[schaltjahr][result->tm_yday / 30 + 1] > result->tm_yday ) {
> +		result->tm_mon = (result->tm_yday / 30);
> +	} else {
> +		result->tm_mon = (result->tm_yday / 30) + 1;
> +	}

Hm, lustige Methode. Könnte aber sogar hinkommen. ;-)

> +
> +	result->tm_mday = 1 + (result->tm_yday - monat[schaltjahr][result->tm_mon]);
> +
> +	/* keine Ahnung was das ist */
> +	result->tm_isdst = -1;

Das ist ein Flag, das gesetzt ist, wenn das Datum in der Sommerzeit
(DST = Daylight Saving Time) liegt.

Sieht ansonsten gut aus, soweit ich das sagen kann.