amiga-tz/library/time_time.c

153 lines
3.0 KiB
C

#include "time_header.h"
#include <dos/var.h>
#include <devices/timer.h>
#include <libraries/locale.h>
// 2922 is the number of days between 1.1.1970 and 1.1.1978
// (2 leap years and 6 normal)
// 2922 * 24 * 60 * 60 = 252460800
#define AMIGAOFFSET 252460800L
struct state *adj_lclptr;
struct tm adj_tm;
long gmtoffset_c(struct timeval *tv)
{
time_t time = (time_t)tv->tv_secs;
if (!lcl_is_set)
return 0;
if (zonechg || lclptr != adj_lclptr) {
localtime_rz(lclptr, &time, &adj_tm);
adj_lclptr = lclptr;
zonechg = 0;
}
// TODO: include logic to detect dst change
return -adj_tm.tm_gmtoff;
}
/**
* @brief
* The time () function returns the value of time in seconds since 0 hours,
* 0 minutes, 0 seconds, January 1, 1970, Coordinated Universal Time. If an
* error occurs, time () returns 0.
*
* The return value is also stored in * tloc , provided that tloc is non-null.
*
*/
time_t time(time_t *tloc)
{
long zone;
time_t time;
struct timeval tv;
if (CreateTimer() != 0) {
return 0;
}
GetSysTime(&tv);
zone = gmtoffset_c(&tv);
time = (time_t)(tv.tv_secs + AMIGAOFFSET + zone);
if (tloc) {
*tloc = time;
}
DeleteTimer();
return time;
}
int gettimeofday(struct timeval *tv, const timezone_t tz)
{
long zone;
time_t time;
struct tm tm;
if (CreateTimer() != 0) {
return -1;
}
zone = gmtoffset_c(tv);
TimeRequest->tr_node.io_Command = TR_GETSYSTIME;
DoIO((struct IORequest*)TimeRequest);
tv->tv_secs = (long)TimeRequest->tr_time.tv_secs + AMIGAOFFSET + zone;
tv->tv_micro = TimeRequest->tr_time.tv_micro;
time = tv->tv_secs;
if (tz) {
gmtime_r(&time, &tm);
tv->tv_secs = mktime_z(tz, &tm);
}
DeleteTimer();
return 0;
}
int settimeofday(const struct timeval *tv, const timezone_t tz)
{
long zone;
if (CreateTimer() != 0) {
return -1;
}
zone = gmtoffset_c((struct timeval*)tv);
// TODO: Include timezone in logic
TimeRequest->tr_node.io_Command = TR_SETSYSTIME;
TimeRequest->tr_time.tv_secs = (long)tv->tv_secs - AMIGAOFFSET - zone;
TimeRequest->tr_time.tv_micro = tv->tv_micro;
DoIO((struct IORequest*)TimeRequest);
DeleteTimer();
return 0;
}
int getsystime(struct timeval *tv)
{
struct timeval tv1;
if (CreateTimer() != 0) {
tv->tv_secs = 0;
tv->tv_micro = 0;
return -1;
}
GetSysTime(&tv1);
*tv = tv1;
DeleteTimer();
return 0;
}
int setsystime(struct timeval *tv)
{
if (CreateTimer() != 0) {
return -1;
}
TimeRequest->tr_node.io_Command = TR_SETSYSTIME;
TimeRequest->tr_time.tv_secs = (long)tv->tv_secs;
TimeRequest->tr_time.tv_micro = tv->tv_micro;
DoIO((struct IORequest*)TimeRequest);
DeleteTimer();
return 0;
}
int gmtoffset(time_t locale_time)
{
struct tm tm;
time_t time = locale_time;
localtime_rz(lclptr, &time, &tm);
mktime(&tm);
return tm.tm_gmtoff;
}