/*
* Copyright (C) 2012 Andy Spencer <andy753421@gmail.com>
- *
+ *
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Time Keeping Bugs Abound! */
+#define _POSIX_C_SOURCE 200112L
+
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <time.h>
+#include "util.h"
+#include "conf.h"
#include "date.h"
/* Global data */
-year_t YEAR;
-month_t MONTH;
-day_t DAY;
+date_t NOW;
+date_t SEL;
/* Initialize */
void date_init(void)
{
- time_t sec = time(NULL);
- struct tm *tm = localtime(&sec);
+ /* Sync current time */
+ NOW = get_date(0);
- YEAR = tm->tm_year+1900;
- MONTH = tm->tm_mon;
- DAY = tm->tm_mday-1;
+ /* Sync selection */
+ SEL.year = NOW.year;
+ SEL.month = NOW.month;
+ SEL.day = NOW.day;
+}
- /* Testing */
- //YEAR = 2009;
- //MONTH = MAY;
- //DAY = 1;
+void date_config(const char *group, const char *name, const char *key, const char *value)
+{
+ if (match(group, "date") && match(key, "timezone") && value)
+ setenv("TZ", get_string(value), 1);
+}
+
+void date_sync(void)
+{
+ NOW = get_date(0);
}
/* Time functions */
void add_days(year_t *year, month_t *month, day_t *day, int days)
{
- time_t time = mktime(&(struct tm){
- .tm_year = *year-1900,
- .tm_mon = *month,
- .tm_mday = *day+1,
- .tm_hour = 12});
- time += days*24*60*60;
- struct tm *tm = localtime(&time);
- *year = tm->tm_year+1900;
- *month = tm->tm_mon;
- *day = tm->tm_mday-1;
+ date_t date = {
+ .year = *year,
+ .month = *month,
+ .day = *day,
+ .hour = 12
+ };
+ stamp_t stamp = get_stamp(date);
+ date_t then = get_date(stamp + days*24*60*60);
+ *year = then.year;
+ *month = then.month;
+ *day = then.day;
}
void add_months(year_t *year, month_t *month, int months)
*month = total % 12;
}
-stamp_t get_time(date_t *date)
+/* Date functions */
+date_t get_date(stamp_t stamp)
{
- return mktime(&(struct tm){
- .tm_year = date->year-1900,
- .tm_mon = date->month,
- .tm_mday = date->day+1,
- .tm_hour = date->hour,
- .tm_min = date->min});
+ time_t t = stamp ? stamp : time(NULL);
+ struct tm *tm = localtime(&t);
+ date_t date = {
+ .year = tm->tm_year+1900,
+ .month = tm->tm_mon,
+ .day = tm->tm_mday-1,
+ .hour = tm->tm_hour,
+ .min = tm->tm_min,
+ .sec = tm->tm_sec,
+ };
+ return date;
+}
+
+stamp_t get_stamp(date_t date)
+{
+ struct tm tm = {
+ .tm_year = date.year-1900,
+ .tm_mon = date.month,
+ .tm_mday = date.day+1,
+ .tm_hour = date.hour,
+ .tm_min = date.min,
+ .tm_sec = date.sec,
+ };
+ time_t t = mktime(&tm);
+ return (stamp_t)t;
}
int get_mins(date_t *start, date_t *end)
{
- return (get_time(end)-get_time(start))/60;
+ return (get_stamp(*end)-get_stamp(*start))/60;
}
-int before(date_t *start, int year, int month, int day, int hour, int min)
+int compare(date_t *a, date_t *b)
{
- int rval = start->year < year ? 1 : start->year > year ? 0 :
- start->month < month ? 1 : start->month > month? 0 :
- start->day < day ? 1 : start->day > day ? 0 :
- start->hour < hour ? 1 : start->hour > hour ? 0 :
- start->min < min ? 1 : start->min > min ? 0 : 0;
+ int rval = a->year < b->year ? -1 : a->year > b->year ? 1 :
+ a->month < b->month ? -1 : a->month > b->month ? 1 :
+ a->day < b->day ? -1 : a->day > b->day ? 1 :
+ a->hour < b->hour ? -1 : a->hour > b->hour ? 1 :
+ a->min < b->min ? -1 : a->min > b->min ? 1 : 0;
return rval;
}
+int same_day(date_t *a, date_t *b)
+{
+ return a->year == b->year &&
+ a->month == b->month &&
+ a->day == b->day;
+}
+
+int before(date_t *start, int year, int month, int day, int hour, int min)
+{
+ return compare(start, &(date_t){year, month, day, hour, min}) < 0;
+}
+
+int all_day(date_t *start, date_t *end)
+{
+ date_t test = *start;
+ add_days(&test.year, &test.month, &test.day, 1);
+ return compare(&test, end) <= 0;
+}
+
+int no_date(date_t *date)
+{
+ return date->year == 0;
+}
+
/* Debug functions */
const char *month_to_str(month_t month)
{
/* Test functions */
void date_test(void)
{
+ setenv("TZ", "US/Central", 1);
+
+ time_t timet = time(NULL);
+ date_t date = get_date(timet);
+ stamp_t stamp = get_stamp(date);
+
+ printf("Time\n");
+ printf(" time %ld\n", timet);
+ printf(" stamp %lld\n", stamp);
+ printf(" date %04d-%02d-%02d %02d:%02d %02ds\n",
+ date.year, date.month, date.day,
+ date.hour, date.min, date.sec);
+
printf("Info\n");
- printf(" Year Month Start Weeks Days\n");
+ printf(" Year Month Start Weeks Days\n");
for (int y = 2012; y <= 2012; y++)
for (int m = JAN; m <= DEC; m++) {
printf(" %-5d", y);