summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/divelist.c4
-rw-r--r--core/load-git.c6
-rw-r--r--core/planner.c2
-rw-r--r--core/save-git.c8
-rw-r--r--core/save-html.c2
-rw-r--r--core/save-xml.c2
-rw-r--r--core/statistics.c6
-rw-r--r--core/time.c72
-rw-r--r--core/uemis-downloader.c1
9 files changed, 69 insertions, 34 deletions
diff --git a/core/divelist.c b/core/divelist.c
index 52545af1a..1ac19bd3f 100644
--- a/core/divelist.c
+++ b/core/divelist.c
@@ -504,7 +504,7 @@ void dump_trip_list(void)
printf("%s trip %d to \"%s\" on %04u-%02u-%02u %02u:%02u:%02u (%d dives - %p)\n",
trip->autogen ? "autogen " : "",
++i, trip->location,
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
+ tm.tm_year, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
trip->nrdives, trip);
last_time = trip->when;
}
@@ -531,7 +531,7 @@ dive_trip_t *find_matching_trip(timestamp_t when)
utc_mkdate(trip->when, &tm);
printf("found trip %p @ %04d-%02d-%02d %02d:%02d:%02d\n",
trip,
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
}
#endif
diff --git a/core/load-git.c b/core/load-git.c
index 339621c63..be7fac7d8 100644
--- a/core/load-git.c
+++ b/core/load-git.c
@@ -126,7 +126,7 @@ static void update_date(timestamp_t *when, const char *line)
if (sscanf(line, "%04u-%02u-%02u", &yyyy, &mm, &dd) != 3)
return;
utc_mkdate(*when, &tm);
- tm.tm_year = yyyy - 1900;
+ tm.tm_year = yyyy;
tm.tm_mon = mm - 1;
tm.tm_mday = dd;
*when = utc_mktime(&tm);
@@ -1199,7 +1199,7 @@ static dive_trip_t *create_new_trip(int yyyy, int mm, int dd)
static bool validate_date(int yyyy, int mm, int dd)
{
- return yyyy > 1970 && yyyy < 3000 &&
+ return yyyy > 1930 && yyyy < 3000 &&
mm > 0 && mm < 13 &&
dd > 0 && dd < 32;
}
@@ -1308,7 +1308,7 @@ static int dive_directory(const char *root, const git_tree_entry *entry, const c
tm.tm_hour = h;
tm.tm_min = m;
tm.tm_sec = s;
- tm.tm_year = yyyy - 1900;
+ tm.tm_year = yyyy;
tm.tm_mon = mm-1;
tm.tm_mday = dd;
diff --git a/core/planner.c b/core/planner.c
index a58c698ab..e67033dd8 100644
--- a/core/planner.c
+++ b/core/planner.c
@@ -51,7 +51,7 @@ void dump_plan(struct diveplan *diveplan)
utc_mkdate(diveplan->when, &tm);
printf("\nDiveplan @ %04d-%02d-%02d %02d:%02d:%02d (surfpres %dmbar):\n",
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
+ tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec,
diveplan->surface_pressure);
dp = diveplan->dp;
diff --git a/core/save-git.c b/core/save-git.c
index 08161f3de..0620a3f3d 100644
--- a/core/save-git.c
+++ b/core/save-git.c
@@ -215,7 +215,7 @@ static void show_date(struct membuffer *b, timestamp_t when)
utc_mkdate(when, &tm);
put_format(b, "date %04u-%02u-%02u\n",
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
+ tm.tm_year, tm.tm_mon + 1, tm.tm_mday);
put_format(b, "time %02u:%02u:%02u\n",
tm.tm_hour, tm.tm_min, tm.tm_sec);
}
@@ -535,7 +535,7 @@ static void create_dive_name(struct dive *dive, struct membuffer *name, struct t
utc_mkdate(dive->when, &tm);
if (tm.tm_year != dirtm->tm_year)
- put_format(name, "%04u-", tm.tm_year + 1900);
+ put_format(name, "%04u-", tm.tm_year);
if (tm.tm_mon != dirtm->tm_mon)
put_format(name, "%02u-", tm.tm_mon+1);
@@ -734,7 +734,7 @@ static int save_trip_description(git_repository *repo, struct dir *dir, dive_tri
struct membuffer desc = { 0 };
put_format(&desc, "date %04u-%02u-%02u\n",
- tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
+ tm->tm_year, tm->tm_mon + 1, tm->tm_mday);
put_format(&desc, "time %02u:%02u:%02u\n",
tm->tm_hour, tm->tm_min, tm->tm_sec);
@@ -949,7 +949,7 @@ static int create_git_tree(git_repository *repo, struct dir *root, bool select_o
/* Create the date-based hierarchy */
utc_mkdate(trip ? trip->when : dive->when, &tm);
- tree = mktree(repo, root, "%04d", tm.tm_year + 1900);
+ tree = mktree(repo, root, "%04d", tm.tm_year);
tree = mktree(repo, tree, "%02d", tm.tm_mon + 1);
if (trip) {
diff --git a/core/save-html.c b/core/save-html.c
index 2d0ea9cf3..4f811558a 100644
--- a/core/save-html.c
+++ b/core/save-html.c
@@ -201,7 +201,7 @@ void put_HTML_date(struct membuffer *b, struct dive *dive, const char *pre, cons
{
struct tm tm;
utc_mkdate(dive->when, &tm);
- put_format(b, "%s%04u-%02u-%02u%s", pre, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, post);
+ put_format(b, "%s%04u-%02u-%02u%s", pre, tm.tm_year, tm.tm_mon + 1, tm.tm_mday, post);
}
void put_HTML_quoted(struct membuffer *b, const char *text)
diff --git a/core/save-xml.c b/core/save-xml.c
index 80dda63b8..c9b6a5b99 100644
--- a/core/save-xml.c
+++ b/core/save-xml.c
@@ -323,7 +323,7 @@ static void show_date(struct membuffer *b, timestamp_t when)
utc_mkdate(when, &tm);
put_format(b, " date='%04u-%02u-%02u'",
- tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
+ tm.tm_year, tm.tm_mon + 1, tm.tm_mday);
put_format(b, " time='%02u:%02u:%02u'",
tm.tm_hour, tm.tm_min, tm.tm_sec);
}
diff --git a/core/statistics.c b/core/statistics.c
index 6a05cffc1..1b9865443 100644
--- a/core/statistics.c
+++ b/core/statistics.c
@@ -160,10 +160,10 @@ void process_all_dives(struct dive *dive, struct dive **prev_dive)
/* yearly statistics */
utc_mkdate(dp->when, &tm);
if (current_year == 0)
- current_year = tm.tm_year + 1900;
+ current_year = tm.tm_year;
- if (current_year != tm.tm_year + 1900) {
- current_year = tm.tm_year + 1900;
+ if (current_year != tm.tm_year) {
+ current_year = tm.tm_year;
process_dive(dp, &(stats_yearly[++year_iter]));
stats_yearly[year_iter].is_year = true;
} else {
diff --git a/core/time.c b/core/time.c
index 0893f19d8..9992658b6 100644
--- a/core/time.c
+++ b/core/time.c
@@ -2,6 +2,24 @@
#include "dive.h"
/*
+ * The date handling internally works in seconds since
+ * Jan 1, 1900. That avoids negative numbers which avoids
+ * some silly problems.
+ *
+ * But we then use the same base epoch base (Jan 1, 1970)
+ * that POSIX uses, so that we can use the normal date
+ * handling functions for getting current time etc.
+ *
+ * There's 25567 dats from Jan 1, 1900 to Jan 1, 1970.
+ *
+ * NOTE! The SEC_PER_DAY is not so much because the
+ * number is complicated, as to make sure we always
+ * expand the type to "timestamp_t" in the arithmetic.
+ */
+#define SEC_PER_DAY ((timestamp_t) 24*60*60)
+#define EPOCH_OFFSET (25567 * SEC_PER_DAY)
+
+/*
* Convert 64-bit timestamp to 'struct tm' in UTC.
*
* On 32-bit machines, only do 64-bit arithmetic for the seconds
@@ -24,7 +42,14 @@ void utc_mkdate(timestamp_t timestamp, struct tm *tm)
memset(tm, 0, sizeof(*tm));
- /* seconds since 1970 -> minutes since 1970 */
+ // Midnight at Jan 1, 1970 means "no date"
+ if (!timestamp)
+ return;
+
+ /* Convert to seconds since 1900 */
+ timestamp += EPOCH_OFFSET;
+
+ /* minutes since 1900 */
tm->tm_sec = timestamp % 60;
val = timestamp /= 60;
@@ -34,19 +59,21 @@ void utc_mkdate(timestamp_t timestamp, struct tm *tm)
tm->tm_hour = val % 24;
val /= 24;
- /* Jan 1, 1970 was a Thursday (tm_wday=4) */
- tm->tm_wday = (val + 4) % 7;
+ /* Jan 1, 1900 was a Monday (tm_wday=1) */
+ tm->tm_wday = (val + 1) % 7;
/*
- * Now we're in "days since Jan 1, 1970". To make things easier,
- * let's make it "days since Jan 1, 1968", since that's a leap-year
+ * Now we're in "days since Jan 1, 1900". To make things easier,
+ * let's make it "days since Jan 1, 1904", since that's a leap-year.
+ * 1900 itself was not. The following logic will get 1900-1903
+ * wrong. If you were diving back then, you're kind of screwed.
*/
- val += 365 + 366;
+ val -= 365*4;
/* This only works up until 2099 (2100 isn't a leap-year) */
leapyears = val / (365 * 4 + 1);
val %= (365 * 4 + 1);
- tm->tm_year = 68 + leapyears * 4;
+ tm->tm_year = 1904 + leapyears * 4;
/* Handle the leap-year itself */
mp = mdays_leap;
@@ -75,24 +102,33 @@ timestamp_t utc_mktime(struct tm *tm)
int year = tm->tm_year;
int month = tm->tm_mon;
int day = tm->tm_mday;
+ int days_since_1900;
+ timestamp_t when;
/* First normalize relative to 1900 */
- if (year < 70)
+ if (year < 50)
year += 100;
else if (year > 1900)
year -= 1900;
- /* Normalized to Jan 1, 1970: unix time */
- year -= 70;
-
- if (year < 0 || year > 129) /* algo only works for 1970-2099 */
- return -1;
+ if (year < 0 || year > 129) /* algo only works for 1900-2099 */
+ return 0;
if (month < 0 || month > 11) /* array bounds */
- return -1;
- if (month < 2 || (year + 2) % 4)
+ return 0;
+ if (month < 2 || (year && year % 4))
day--;
if (tm->tm_hour < 0 || tm->tm_min < 0 || tm->tm_sec < 0)
- return -1;
- return (year * 365 + (year + 1) / 4 + mdays[month] + day) * 24 * 60 * 60UL +
- tm->tm_hour * 60 * 60 + tm->tm_min * 60 + tm->tm_sec;
+ return 0;
+
+ /* This works until 2099 */
+ days_since_1900 = year * 365 + (year - 1) / 4;
+
+ /* Note the 'day' fixup for non-leapyears above */
+ days_since_1900 += mdays[month] + day;
+
+ /* Now add it all up, making sure to do this part in "timestamp_t" */
+ when = days_since_1900 * SEC_PER_DAY;
+ when += tm->tm_hour * 60 * 60 + tm->tm_min * 60 + tm->tm_sec;
+
+ return when - EPOCH_OFFSET;
}
diff --git a/core/uemis-downloader.c b/core/uemis-downloader.c
index b9b532303..925783a6d 100644
--- a/core/uemis-downloader.c
+++ b/core/uemis-downloader.c
@@ -86,7 +86,6 @@ static void uemis_ts(char *buffer, void *_when)
&tm.tm_year, &tm.tm_mon, &tm.tm_mday,
&tm.tm_hour, &tm.tm_min, &tm.tm_sec);
tm.tm_mon -= 1;
- tm.tm_year -= 1900;
*when = utc_mktime(&tm);
}