localtime doesnt return the correct date/month/year

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
cools
Posts: 46
Joined: Sat Mar 04, 2006 12:57 pm

localtime doesnt return the correct date/month/year

Post by cools »

This is just something I noticed recently, every time I try to call date/month/year, it will always return January 1 1970 (when unix time started) using the latest toolchain.

Does anyone else experience this problem?
gambiting
Posts: 154
Joined: Thu Aug 17, 2006 5:39 pm

Post by gambiting »

Try time() - it will return you number of seconds since that date.
jimparis
Posts: 1145
Joined: Fri Jun 10, 2005 4:21 am
Location: Boston

Re: localtime doesnt return the correct date/month/year

Post by jimparis »

cools wrote:This is just something I noticed recently, every time I try to call date/month/year, it will always return January 1 1970 (when unix time started) using the latest toolchain.
What exactly are you trying to call?
If you call localtime, you need to pass it a pointer to a correct time_t.
cools
Posts: 46
Joined: Sat Mar 04, 2006 12:57 pm

Post by cools »

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspdisplay.h>
#include <time.h>

/* Define the module info section */
PSP_MODULE_INFO&#40;"TEST", 0, 1, 1&#41;;

/* Define the main thread's attribute value &#40;optional&#41; */
PSP_MAIN_THREAD_ATTR&#40;THREAD_ATTR_USER | THREAD_ATTR_VFPU&#41;;

int main&#40;void&#41;
&#123;
   pspDebugScreenInit&#40;&#41;;

   int c = 0;
   while &#40;1&#41; &#123;
      time_t t = time&#40;NULL&#41;;
      struct tm *stm = localtime&#40;&t&#41;;
      pspDebugScreenClear&#40;&#41;;
	  pspDebugScreenPrintf&#40;"%02i&#58;%02i&#58;%02i", stm->tm_year+1900, stm->tm_mon+1, stm->tm_mday&#41;;
      sceDisplayWaitVblankStart&#40;&#41;;
      sceDisplayWaitVblankStart&#40;&#41;;
      if &#40;c++ == 300&#41; break;
   &#125;
   sceKernelExitGame&#40;&#41;;

   return 0;
&#125;
^oh and thats pretty much shines code, except 1 line...

It will return 1970:01:01
carlosedp
Posts: 21
Joined: Tue Jun 19, 2007 4:20 am
Location: Sao Paulo / Brazil

Post by carlosedp »

Hi cools,

I got this problem too. Fixed it replacing the following:


time() -> sceKernelLibcTime() like:

Code: Select all

    time_t now;
    sceKernelLibcTime&#40;&now&#41;;
    printf&#40;"Time is&#58; %s\n", ctime&#40;&now&#41;&#41;;
gettimeofday() -> sceKernelLibcGettimeofday():

gettimeofday have microseconds resolution but its seconds are from 0:00 so you can grab the seconds since epoch with sceKernelLibcTime() and add to the usec from the structure like this:

Code: Select all

double gettime&#40;&#41; &#123;
    time_t now;
    struct timeval t;
    double result;

    sceKernelLibcTime&#40;&now&#41;;
    sceKernelLibcGettimeofday&#40;&t, NULL&#41;
    res = &#40;double&#41;now;
    res += t.tv_usec*0.000001;

    return res
&#125;
I have also used the initTimezone function above... i got it from another post here in the forum and fixed the timezone with DST. I call it from my main() just one time....

Code: Select all

void initTimezone&#40;&#41; &#123;
    int tzOffset = 0;
    sceUtilityGetSystemParamInt&#40;PSP_SYSTEMPARAM_ID_INT_TIMEZONE, &tzOffset&#41;;
    int tzOffsetAbs = tzOffset < 0 ? -tzOffset &#58; tzOffset;
    int hours = tzOffsetAbs / 60;
    int minutes = tzOffsetAbs - hours * 60;
    int pspDaylight = 0;
    sceUtilityGetSystemParamInt&#40;PSP_SYSTEMPARAM_ID_INT_DAYLIGHTSAVINGS, &pspDaylight&#41;;
    static char tz&#91;18&#93;;
    sprintf&#40;tz, "GMT%s%02i&#58;%02i%s", tzOffset < 0 ? "+" &#58; "-", hours, minutes, pspDaylight ? " DST" &#58; ""&#41;;
    setenv&#40;"TZ", tz, 1&#41;;
    tzset&#40;&#41;;
&#125;

[/code]
carlosedp
Posts: 21
Joined: Tue Jun 19, 2007 4:20 am
Location: Sao Paulo / Brazil

Post by carlosedp »

One thing I noticed that is very weird is that the file newlib-1.15.0/newlib/libc/sys/psp/libcglue.c already does this mapping from the original C call to the PSP call... like this:

Code: Select all

/* Time routines.  These wrap around the routines provided by the kernel. */
#ifdef F__gettimeofday
int _gettimeofday&#40;struct timeval *tp, struct timezone *tzp&#41;
&#123;
    return __psp_set_errno&#40;sceKernelLibcGettimeofday&#40;tp, tzp&#41;&#41;;
&#125;

#endif

Or this:

Code: Select all

#if defined&#40;F_time&#41;
time_t time&#40;time_t *t&#41;
&#123;
    return __psp_set_errno&#40;sceKernelLibcTime&#40;t&#41;&#41;;
&#125;
#endif

Why it is not called when I use the clock or similar functions???? It looks like the library itself would wrap this for me.... It happens also on tzset()... it appears on libcglue.c and should do all that I do in the function I posted above but this doesnt happens.

Carlos
jimparis
Posts: 1145
Joined: Fri Jun 10, 2005 4:21 am
Location: Boston

Post by jimparis »

Yeah, it should just work. Are you sure you're linking against newlib?
carlosedp
Posts: 21
Joined: Tue Jun 19, 2007 4:20 am
Location: Sao Paulo / Brazil

Post by carlosedp »

Well,

I think I am.... tell me if is there anything wrong...

Here is my makefile:

Code: Select all

TARGET = StacklessPSP
BUILD_PRX = 1
PSP_FW_VERSION = 371
RELEASE_NAME = StacklessPSP
RELEASE_VERSION = 2.5.1
RELEASE_DIRECTORY = ~/$&#40;RELEASE_NAME&#41;-$&#40;RELEASE_VERSION&#41;

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Stackless PyPSP 2.5.1
PSP_EBOOT_ICON = icon_slp251.png
#PSP_EBOOT_UNKPNG = pic0.png
#PSP_EBOOT_PIC1 = pic1.png
#PSP_EBOOT_SND0 = snd0.at3

MODULES_STATIC = \
	Modules/config.o
        ........

OBJECTS_PYTHON = \
    ../Python/ast.o \
        ........
 
OBJECTS_OBJECTS = \
	../Objects/typeobject.o \
        ........

OBJECTS_PARSER = \
	../Parser/tokenizer.o \
	        ........


OBJS_STACKLESS = ../Stackless/core/cframeobject.o \
	../Stackless/core/slp_transfer.o \
	        ........

OBJS = main.o psperror.o support.o \
	$&#40;MODULES_STATIC&#41; $&#40;OBJECTS_PYTHON&#41; $&#40;OBJECTS_OBJECTS&#41; $&#40;OBJECTS_PARSER&#41; $&#40;OBJS_STACKLESS&#41;

CPPFLAGS=-I../../cpplibs
LDFLAGS=-L../../cpplibs
LIBS=

ifeq &#40;$&#40;WITH_SQLITE&#41;,1&#41;
OBJS += $&#40;OBJS_SQLITE&#41;
CPPFLAGS += -I../Modules/_sqlite -DMODULE_NAME=\"sqlite3\" -DWITH_SQLITE
LIBS += -lsqlite3
endif

ifeq &#40;$&#40;WITH_PSP2D&#41;,1&#41;
OBJS += $&#40;OBJS_PSP2D&#41;
LDFAGS += -Llibpsp2d
LIBS += -lpsp2d -ljpeg -lpng -lz -lpspgu
CPPFLAGS += -DWITH_PSP2D
endif

ifeq &#40;$&#40;WITH_PSPSND&#41;,1&#41;
OBJS += $&#40;OBJS_PSPSND&#41;
LDFLAGS += -Llibpspsnd
LIBS += -lpspsnd -lmikmod -lmmio -lpspaudiolib -lpspaudio
CPPFLAGS += -DWITH_PSPSND
endif

ifeq &#40;$&#40;WITH_PSPNET&#41;,1&#41;
OBJS += $&#40;OBJS_PSPNET&#41;
CPPFLAGS += -DWITH_PSPNET
LIBS += -lpspwlan
endif

ifeq &#40;$&#40;WITH_PSPOGG&#41;,1&#41;
OBJS += $&#40;OBJS_PSPOGG&#41;
LIBS += -lvorbisidec -lpspaudiolib -lpspaudio
CPPFLAGS += -DWITH_PSPOGG
endif

ifeq &#40;$&#40;WITH_PSPMP3&#41;,1&#41;
OBJS += $&#40;OBJS_PSPMP3&#41;
LIBS += -lmad -lpspaudiolib -lpspaudio
CPPFLAGS += -DWITH_PSPMP3
endif

LIBS += -lpsppower -lstdc++ -lbz2 -lssl -lcrypto

CPPFLAGS += -DHAVE_CONFIG_H -DPSP -I../Include -I../Stackless
CPPFLAGS += -I../Modules/expat -DHAVE_MEMMOVE

LIBS += -lc -lm

CFLAGS = -Os -G0 -Wall -Wno-strict-aliasing
CXXFLAGS = $&#40;CFLAGS&#41; -fno-rtti -fno-strict-aliasing
ASFLAGS = $&#40;CFLAGS&#41;

LIBDIR =

PSPSDK=$&#40;shell psp-config --pspsdk-path&#41;
include $&#40;PSPSDK&#41;/lib/build.mak

psperror.c&#58;
	python generr.py
	
carlosedp
Posts: 21
Joined: Tue Jun 19, 2007 4:20 am
Location: Sao Paulo / Brazil

Post by carlosedp »

Guys,

No clue on why the time functions doesnt works... am I linking to the correct libraries?

Thanks
jimparis
Posts: 1145
Joined: Fri Jun 10, 2005 4:21 am
Location: Boston

Post by jimparis »

Looks like it, but as you noticed newlib already has all of the right code in there, so maybe there's something wrong with your build setup? Try a simpler test program maybe.
Insert_witty_name
Posts: 376
Joined: Wed May 10, 2006 11:31 pm

Post by Insert_witty_name »

I looked at this today as I need some of the newlib time functions...

It seems all the time functions from libcglue aren't being used, instead the functions from newlib-1.15.0/newlib/libc/time are used instead.

As a hack test I edited the newlib-1.15.0/newlib/libc/time/time.c file and removed the:

Code: Select all

time_t
_DEFUN &#40;time, &#40;t&#41;,
	time_t * t&#41;
&#123;
function entirely.

Re-compiled newlib and the time() function in libcglue worked perfectly.

I know virtually nothing on newlib or how to fix this issue. Maybe someone else could take a look at it?
darkness
Posts: 121
Joined: Sun Jun 15, 2008 8:42 pm

Post by darkness »

Why don't use sceRtcGetCurrentClockLocalTime funct?
I think is better!

Code: Select all

pspTime time;
sceRtcGetCurrentClockLocalTime&#40;&time&#41;;
printf&#40;"%2.2d/%2.2d   %2.2d&#58;%2.2d", time.day, time.month, time.hour, time.minutes&#41;;
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Insert_witty_name wrote:I looked at this today as I need some of the newlib time functions...

It seems all the time functions from libcglue aren't being used, instead the functions from newlib-1.15.0/newlib/libc/time are used instead.

As a hack test I edited the newlib-1.15.0/newlib/libc/time/time.c file and removed the:

Code: Select all

time_t
_DEFUN &#40;time, &#40;t&#41;,
	time_t * t&#41;
&#123;
function entirely.

Re-compiled newlib and the time() function in libcglue worked perfectly.

I know virtually nothing on newlib or how to fix this issue. Maybe someone else could take a look at it?
I ran into this with B2 - I wound up just inserting InitTimeZone() into my main and using sceKernelLibcTime(&rawtime) to get the time. Hopefully at some point, this will make it into newlib.
Insert_witty_name
Posts: 376
Joined: Wed May 10, 2006 11:31 pm

Post by Insert_witty_name »

It's easy to use sceKernelLibcTime() in place of time().

The point is that it doesn't work in newlib correctly so needs fixing :)
User avatar
Raphael
Posts: 646
Joined: Tue Jan 17, 2006 4:54 pm
Location: Germany
Contact:

Post by Raphael »

If I may say so.... libc and it's implementations (namely newlib) are all so clobbered with function redirections and functionname dissembling that it's just a freaking PITA to work with it or do any changes/fixes....
who the hell decided that the code must be so unreadable that only the ones that wrote it can actually understand it? Shoot that idiot!
</rant>
<Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki

Alexander Berl
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Raphael wrote:If I may say so.... libc and it's implementations (namely newlib) are all so clobbered with function redirections and functionname dissembling that it's just a freaking PITA to work with it or do any changes/fixes....
who the hell decided that the code must be so unreadable that only the ones that wrote it can actually understand it? Shoot that idiot!
</rant>
QFT. :D

I've settled for minor changes to code I KNOW gets included - like the change for a negative heap size.
Insert_witty_name
Posts: 376
Joined: Wed May 10, 2006 11:31 pm

Post by Insert_witty_name »

Ok I've committed a change to the newlib patch.

The problem was that gettimeofday() internally called sceKernelLibcGettimeofday() which was assumed to be the sce version of gettimeofday().

sceKernelLibcGettimeofday() actually returns sec and usec since 00:00 on that day only, not since the 1970 epoch.

I have changed gettimeofday() to use the values from sceKernelLibcTime(), and gettimeofday(), time() and tz_set() now seem to be working correctly.
J.F.
Posts: 2906
Joined: Sun Feb 22, 2004 11:41 am

Post by J.F. »

Insert_witty_name wrote:Ok I've committed a change to the newlib patch.

The problem was that gettimeofday() internally called sceKernelLibcGettimeofday() which was assumed to be the sce version of gettimeofday().

sceKernelLibcGettimeofday() actually returns sec and usec since 00:00 on that day only, not since the 1970 epoch.

I have changed gettimeofday() to use the values from sceKernelLibcTime(), and gettimeofday(), time() and tz_set() now seem to be working correctly.
Cool. I'll have to update and change B2 again. :)
Pirata Nervo
Posts: 409
Joined: Tue Oct 09, 2007 4:22 am

Post by Pirata Nervo »

@IWN, when did you update it?
Image
Upgrade your PSP
Insert_witty_name
Posts: 376
Joined: Wed May 10, 2006 11:31 pm

Post by Insert_witty_name »

Exactly two hours before you posted.
Pirata Nervo
Posts: 409
Joined: Tue Oct 09, 2007 4:22 am

Post by Pirata Nervo »

OK, I need to update my ubuntu then. thanks :)
Image
Upgrade your PSP
jimparis
Posts: 1145
Joined: Fri Jun 10, 2005 4:21 am
Location: Boston

Post by jimparis »

I made a fix to IWN's fix. gettimeofday() still needs to return microseconds, so now gettimeofday() will use sceKernelLibcGettimeofday() to get usecs and sceKernelLibcTime() to get epoch seconds, with some extra protection to avoid glitches if the usecs wrap around between calls. It should be correct now.
Post Reply