153 lines
3.0 KiB
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;
|
|
}
|