mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 12:32:40 +02:00
Added support for timezones, hence localtime() will now return actual localtime. Added timeToCalendarTimeWithMyRule and TimeCalendarTime/TimeCalendarAdditionalInfo, which are used for timezones support.
This commit is contained in:
parent
dc011024f9
commit
4fb364060c
@ -17,6 +17,24 @@ typedef enum {
|
||||
TimeType_Default = TimeType_UserSystemClock,
|
||||
} TimeType;
|
||||
|
||||
typedef struct {
|
||||
u16 year;
|
||||
u8 month;
|
||||
u8 day;
|
||||
u8 hour;
|
||||
u8 minute;
|
||||
u8 second;
|
||||
u8 pad;
|
||||
} TimeCalendarTime;
|
||||
|
||||
typedef struct {
|
||||
u32 wday; ///< 0-based day-of-week.
|
||||
u32 yday; ///< 0-based day-of-year.
|
||||
char timezoneName[8]; ///< Timezone name string.
|
||||
u32 DST; ///< 0 = no DST, 1 = DST.
|
||||
s32 offset; ///< Seconds relative to UTC for this timezone.
|
||||
} TimeCalendarAdditionalInfo;
|
||||
|
||||
Result timeInitialize(void);
|
||||
void timeExit(void);
|
||||
|
||||
@ -31,3 +49,6 @@ Result timeGetCurrentTime(TimeType type, u64 *timestamp);
|
||||
* @return Result code.
|
||||
*/
|
||||
Result timeSetCurrentTime(TimeType type, u64 timestamp);
|
||||
|
||||
Result timeToCalendarTimeWithMyRule(u64 timestamp, TimeCalendarTime *caltime, TimeCalendarAdditionalInfo *info);
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/iosupport.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/lock.h>
|
||||
@ -31,12 +33,17 @@ static struct _reent* __libnx_get_reent(void) {
|
||||
return tv->reent;
|
||||
}
|
||||
|
||||
//TODO: timeGetCurrentTime() returns UTC time. How to handle timezones?
|
||||
static u64 __boottime;
|
||||
static u64 __bootticks;
|
||||
|
||||
// setup boot time variables
|
||||
void __libnx_init_time(void) {
|
||||
TimeCalendarAdditionalInfo info;
|
||||
char envstr[64];
|
||||
char *strptr;
|
||||
bool is_west=0;
|
||||
s32 tmp_offset, hour, minute, second;
|
||||
|
||||
Result rc = timeGetCurrentTime(__nx_time_type, &__boottime);
|
||||
if (R_FAILED(rc) && __nx_time_type != TimeType_Default) rc = timeGetCurrentTime(TimeType_Default, &__boottime);
|
||||
if (R_FAILED(rc)) {
|
||||
@ -44,6 +51,43 @@ void __libnx_init_time(void) {
|
||||
} else {
|
||||
__bootticks = armGetSystemTick();
|
||||
}
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = timeToCalendarTimeWithMyRule(__boottime, NULL, &info);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
info.timezoneName[7] = 0;
|
||||
tmp_offset = info.offset;
|
||||
if (tmp_offset < 0) {
|
||||
is_west = 1;
|
||||
tmp_offset = -tmp_offset;
|
||||
}
|
||||
|
||||
second = tmp_offset % 60;
|
||||
tmp_offset /= 60;
|
||||
minute = tmp_offset % 60;
|
||||
tmp_offset /= 60;
|
||||
hour = tmp_offset % 24;
|
||||
|
||||
memset(envstr, 0, sizeof(envstr));
|
||||
|
||||
//Avoid using *printf.
|
||||
strncpy(envstr, info.timezoneName, sizeof(envstr)-1);
|
||||
strptr = &envstr[strlen(envstr)];
|
||||
*strptr++ = is_west ? '+' : '-';
|
||||
|
||||
*strptr++ = '0' + (hour / 10);
|
||||
*strptr++ = '0' + (hour % 10);
|
||||
*strptr++ = ':';
|
||||
|
||||
*strptr++ = '0' + (minute / 10);
|
||||
*strptr++ = '0' + (minute % 10);
|
||||
*strptr++ = ':';
|
||||
|
||||
*strptr++ = '0' + (second / 10);
|
||||
*strptr++ = '0' + (second % 10);
|
||||
|
||||
setenv("TZ", envstr, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static const u64 nsec_clockres = 1000000000ULL / 19200000ULL;
|
||||
|
@ -191,3 +191,41 @@ Result timeSetCurrentTime(TimeType type, u64 timestamp) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result timeToCalendarTimeWithMyRule(u64 timestamp, TimeCalendarTime *caltime, TimeCalendarAdditionalInfo *info) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 timestamp;
|
||||
} *raw;
|
||||
|
||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 101;
|
||||
raw->timestamp = timestamp;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_timeTimeZoneService);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
ipcParse(&r);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
TimeCalendarTime caltime;
|
||||
TimeCalendarAdditionalInfo info;
|
||||
} *resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && caltime) memcpy(caltime, &resp->caltime, sizeof(TimeCalendarTime));
|
||||
if (R_SUCCEEDED(rc) && info) memcpy(info, &resp->info, sizeof(TimeCalendarAdditionalInfo));
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user