Added tzconvert function.

This commit is contained in:
dfs
2007-07-08 16:57:47 +00:00
parent 629e287526
commit 09d11d36c3
7 changed files with 134 additions and 16 deletions

View File

@@ -11,7 +11,7 @@
/* */
/***************************************************************/
/* $Id: custom.h,v 1.37 2007-07-01 14:49:47 dfs Exp $ */
/* $Id: custom.h,v 1.38 2007-07-08 16:57:47 dfs Exp $ */
/*---------------------------------------------------------------------*/
/* LAT_DEG, LAT_MIN and LAT_SEC: Latitude of your location */

View File

@@ -10,7 +10,7 @@
/* */
/***************************************************************/
/* $Id: err.h,v 1.4 2000-02-18 03:45:51 dfs Exp $ */
/* $Id: err.h,v 1.5 2007-07-08 16:57:47 dfs Exp $ */
/* Note that not all of the "errors" are really errors - some are just
messages for information purposes. Constants beginning with M_ should
@@ -118,6 +118,7 @@
#define M_QUEUED 96
#define E_EXPECTING_NUMBER 97
#define M_BAD_WARN_FUNC 98
#define E_CANT_CONVERT_TZ 99
#ifdef MK_GLOBALS
#undef EXTERN
@@ -230,7 +231,8 @@ EXTERN char *ErrMsg[]
"No reminders.",
"%d reminder(s) queued for later today.\n",
"Expecting number",
"Bad function in WARN clause"
"Bad function in WARN clause",
"Can't convert between time zones"
}
#endif /* MK_GLOBALS */
;

View File

@@ -12,7 +12,7 @@
/***************************************************************/
#include "config.h"
static char const RCSID[] = "$Id: funcs.c,v 1.14 2007-06-29 01:52:36 dfs Exp $";
static char const RCSID[] = "$Id: funcs.c,v 1.15 2007-07-08 16:57:47 dfs Exp $";
#include <stdio.h>
@@ -127,6 +127,7 @@ static int FRealnow (void);
static int FRealtoday (void);
static int FToday (void);
static int FTrigger (void);
static int FTzconvert (void);
static int CheckArgs (Operator *f, int nargs);
static int CleanUpAfterFunc (void);
static int SunStuff (int rise, double cosz, int jul);
@@ -252,6 +253,7 @@ Operator Func[] = {
{ "trigtime", 0, 0, FTrigtime },
{ "trigvalid", 0, 0, FTrigvalid },
{ "typeof", 1, 1, FTypeof },
{ "tzconvert", 2, 3, FTzconvert },
{ "upper", 1, 1, FUpper },
{ "value", 1, 2, FValue },
{ "version", 0, 0, FVersion },
@@ -2285,3 +2287,108 @@ static int FDatepart(void)
RetVal.v.val = DATEPART(ARG(0));
return OK;
}
/***************************************************************/
/* */
/* FTz */
/* */
/* Conversion between different timezones. */
/* */
/***************************************************************/
static int tz_set_tz(char const *tz)
{
int r;
if (tz == NULL) {
r = unsetenv("TZ");
} else {
r = setenv("TZ", tz, 1);
}
tzset();
return r;
}
static int tz_convert(int year, int month, int day,
int hour, int minute,
char const *src_tz, char const *tgt_tz,
struct tm *tm)
{
int r;
time_t t;
struct tm *res;
char *old_tz;
/* init tm struct */
tm->tm_sec = 0;
tm->tm_min = minute;
tm->tm_hour = hour;
tm->tm_mday = day;
tm->tm_mon = month;
tm->tm_year = year - 1900;
tm->tm_wday = 0; /* ignored by mktime */
tm->tm_yday = 0; /* ignored by mktime */
tm->tm_isdst = -1; /* information not available */
/* backup old TZ env var */
old_tz = getenv("TZ");
if (tgt_tz == NULL) {
tgt_tz = old_tz;
}
/* set source TZ */
r = tz_set_tz(src_tz);
if (r == -1) {
return -1;
}
/* create timestamp in UTC */
t = mktime(tm);
/* set target TZ */
r = tz_set_tz(tgt_tz);
if (r == -1) {
tz_set_tz(old_tz);
return -1;
}
/* convert to target TZ */
res = localtime_r(&t, tm);
/* restore old TZ */
tz_set_tz(old_tz);
/* return result */
if (res == NULL) {
return -1;
} else {
return 1;
}
}
static int FTzconvert(void)
{
int year, month, day, hour, minute, r;
int jul, tim;
struct tm tm;
if (ARG(0).type != DATETIME_TYPE ||
ARG(1).type != STR_TYPE) return E_BAD_TYPE;
if (Nargs == 3 && ARG(2).type != STR_TYPE) return E_BAD_TYPE;
FromJulian(DATEPART(ARG(0)), &year, &month, &day);
r = TIMEPART(ARG(0));
hour = r / 60;
minute = r % 60;
if (Nargs == 2) {
r = tz_convert(year, month, day, hour, minute, ARG(1).v.str, NULL,
&tm);
} else {
r = tz_convert(year, month, day, hour, minute,
ARG(1).v.str, ARG(2).v.str,
&tm);
}
if (r == -1) return E_CANT_CONVERT_TZ;
jul = Julian(tm.tm_year + 1900, tm.tm_mon, tm.tm_mday);
tim = tm.tm_hour * 60 + tm.tm_min;
RetVal.type = DATETIME_TYPE;
RetVal.v.val = jul * MINUTES_PER_DAY + tim;
return OK;
}

View File

@@ -16,7 +16,7 @@
/* */
/***************************************************************/
/* $Id: finnish.h,v 1.12 2007-07-03 03:42:46 dfs Exp $ */
/* $Id: finnish.h,v 1.13 2007-07-08 16:57:49 dfs Exp $ */
/* The very first define in a language support file must be L_LANGNAME: */
#define L_LANGNAME "Finnish"
@@ -308,7 +308,8 @@ EXTERN char *ErrMsg[] =
"Ei viestej\xE4.",
"%d viesti(\xE4) t\xE4m\xE4n p\xE4iv\xE4n jonossa.\n",
"Numero puuttuu",
"Virheellinen funktio WARN-lausekkeessa"
"Virheellinen funktio WARN-lausekkeessa",
"Can't convert between time zones"
#elif IBMEXTENDED
"Ok",
@@ -409,7 +410,8 @@ EXTERN char *ErrMsg[] =
"Ei viestej\x84.",
"%d viesti(\x84) t\x84m\x84n p\x84iv\x84n jonossa.\n",
"Numero puuttuu"
"Virheellinen funktio WARN-lausekkeessa"
"Virheellinen funktio WARN-lausekkeessa",
"Can't convert between time zones"
#else
"Ok",
"Puuttuva ']'",
@@ -509,7 +511,9 @@ EXTERN char *ErrMsg[] =
"Ei viestej{.",
"%d viesti({) t{m{n p{iv{n jonossa.\n",
"Numero puuttuu",
"Virheellinen funktio WARN-lausekkeessa"
"Virheellinen funktio WARN-lausekkeessa",
"Can't convert between time zones"
#endif
};
#endif /* MK_GLOBALS */

View File

@@ -15,7 +15,7 @@
/* */
/***************************************************************/
/* $Id: french.h,v 1.10 2007-07-03 03:42:46 dfs Exp $ */
/* $Id: french.h,v 1.11 2007-07-08 16:57:49 dfs Exp $ */
/* The very first define in a language support file must be L_LANGNAME: */
#define L_LANGNAME "French"
@@ -245,7 +245,8 @@ EXTERN char *ErrMsg[] =
"Pas de rappels.",
"%d rappel(s) en file pour aujourd'hui.\n",
"Nombre attendu",
"Fonction ill\351gale apr\350s WARN"
"Fonction ill\351gale apr\350s WARN",
"Can't convert between time zones"
#else /* ISOLATIN1 */
"Ok",
"']' manquant",
@@ -345,7 +346,8 @@ EXTERN char *ErrMsg[] =
"Pas de rappels.",
"%d rappel(s) en file pour aujourd'hui.\n",
"Nombre attendu",
"Fonction illegale apres WARN"
"Fonction illegale apres WARN",
"Can't convert between time zones"
#endif /* ISOLATIN1 */
};
#endif /* MK_GLOBALS */

View File

@@ -14,7 +14,7 @@
/* */
/***************************************************************/
/* $Id: polish.h,v 1.10 2007-07-03 03:42:46 dfs Exp $ */
/* $Id: polish.h,v 1.11 2007-07-08 16:57:49 dfs Exp $ */
/* The very first define in a language support file must be L_LANGNAME: */
#define L_LANGNAME "Polish"
@@ -280,7 +280,8 @@ EXTERN char *ErrMsg[] =
"Brak przypomnie\361.",
"%d Przypomnienia zakolejkowane na p\363\274niej.\n",
"Spodziewana liczba",
"Illegal function in WARN clause (NEEDS TRANSLATION TO POLISH)"
"Illegal function in WARN clause (NEEDS TRANSLATION TO POLISH)",
"Can't convert between time zones"
#else /* ISOLATIN1 */
"OK",
"Brakujacy ']'",
@@ -380,7 +381,8 @@ EXTERN char *ErrMsg[] =
"Brak przypomnien.",
"%d Przypomnienia zakolejkowane na pozniej.\n",
"Spodziewana liczba",
"Illegal function in WARN clause (NEEDS TRANSLATION TO POLISH)"
"Illegal function in WARN clause (NEEDS TRANSLATION TO POLISH)",
"Can't convert between time zones"
#endif /* ISOLATIN1 */
};
#endif /* MK_GLOBALS */

View File

@@ -15,7 +15,7 @@
/* */
/***************************************************************/
/* $Id: portbr.h,v 1.9 2007-07-03 03:42:46 dfs Exp $ */
/* $Id: portbr.h,v 1.10 2007-07-08 16:57:49 dfs Exp $ */
/* The very first define in a language support file must be L_LANGNAME: */
#define L_LANGNAME "Brazilian Portuguese"
@@ -246,7 +246,8 @@ EXTERN char *ErrMsg[] =
"Sem compromissos.",
"%d compromisso(s) colocados na fila para mais tarde.\n",
"Esperando numero",
"Funcao ilegal na clausula WARN"
"Funcao ilegal na clausula WARN",
"Can't convert between time zones"
};
#endif /* MK_GLOBALS */