summaryrefslogtreecommitdiff
path: root/src/mytime.c
blob: e71259bda5b560d7dd05ef41fdff077a021831eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "mytime.h"

#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

bool fake_time;
struct timespec global_time;

struct timespec get_current_time() {
	if(fake_time) {
		return global_time;
	}

	struct timespec val;
	if(clock_gettime(CLOCK_REALTIME, &val) != 0) {
		abort();
	}

	return val;
}

void enable_fake_time() {
	assert(!fake_time);

	global_time = (struct timespec){
		.tv_sec = 0,
		.tv_nsec = 0,
	};
	fake_time = true;
}

void progress_time(uint64_t diff) {
	assert(fake_time);

	// Right now the diff is only seconds resolution
	global_time.tv_sec += diff;
}

struct timespec time_from_double(double t) {
	double fraction;
	double integral;
	fraction = modf(t, &integral);
	return (struct timespec) {
		.tv_sec = integral,
			.tv_nsec = fraction * 1000000000.0,
	};
}

struct formatted_time format_time(struct timespec time) {
	struct formatted_time res = {0};

	struct tm tm;
	gmtime_r(&time.tv_sec, &tm);
	if(strftime(res.buf, 32, "%Y-%m-%d %H:%M:%S", &tm) >= 32) {
		abort();
	}

	return res;
}

struct formatted_time format_duration(struct timespec time) {
	struct formatted_time res = {0};

	int hours = time.tv_sec / 3600;
	int mins = (time.tv_sec % 3600) / 60;
	int secs = time.tv_sec % 60;

	if (hours > 0) {
		snprintf(res.buf, 32, "%dh %02dm %02ds", hours, mins, secs);
	} else if (mins > 0) {
		snprintf(res.buf, 32, "%dm %02ds", mins, secs);
	} else {
		snprintf(res.buf, 32, "%ds", secs);
	}
	

	return res;
}

struct timespec time_sub(const struct timespec *t1, const struct timespec *t2) {
	assert(t1);
	assert(t2);
	struct timespec diff = {
		.tv_sec = t1->tv_sec - t2->tv_sec,
		.tv_nsec = t1->tv_nsec - t2->tv_nsec
	};
	if (diff.tv_nsec < 0) {
		diff.tv_nsec += 1000000000;
		diff.tv_sec--;
	}
	return diff;
}