aboutsummaryrefslogtreecommitdiff
path: root/timetolocal.c
blob: 0b96bf84063fa87b6acd9b16c8e141b0ee9d41c4 (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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include <stdlib.h>
#include <ctype.h>
#include "tztable.h"

/*it's not case sensitive
returns the offset
returns -1 if it doesn't find it*/
int findintable(char *what){
    for(size_t i = 0; i < TZTABLE_LENGHT; i++){
        if((strcasecmp(what, tz_table[i].zn)) == 0){
        return tz_table[i].offset; 
        }
    }
return -1; 
}

/*parses H or H:M (24hs)
returns 0 on success, -1 if it's not a valid time*/
int strtimetoint(const char *whattimeisit, davidtime *out) {
    if (whattimeisit == NULL || out == NULL) return -1;

    char *end;
    long hour = strtol(whattimeisit, &end, 10);
    if (end == whattimeisit) return -1;

    long minutes = 0;
    if (*end == ':') {
        const char *mstart = end + 1;
        minutes = strtol(mstart, &end, 10);
        if (end == mstart) return -1;
    }
    if (*end != '\0') return -1;

    if (hour < 0 || hour > 23 || minutes < 0 || minutes > 59) return -1;

    out->hour = (int)hour;
    out->minutes = (int)minutes;
    return 0;
}

char* gethhmm(char* buffer, size_t max_size) {
    time_t raw_time;
    struct tm* time_info;

    time(&raw_time);
    time_info = localtime(&raw_time);

    strftime(buffer, max_size, "%H:%M", time_info);
    return buffer;
}

/*tozone = 0 time is in zone, print it as local time
tozone = 1 time is local time, print it in zone
returns 0 ok -1 zone not found and -2 if invalid time*/
int convert(char *timey, char *zone, int tozone){
    time_t rawtime = time(NULL);
    struct tm utc = *gmtime(&rawtime); //gmtime uses a static buffer so it just copies 

    utc.tm_isdst = -1;
    time_t gmt = mktime(&utc);
    int offset = difftime(rawtime, gmt) / 60;
    //this sould take even daylight savings too, i stole it from stack overflow i've been trying to not use llms to code shit like this

    //tmzn hour --> utc00 --> local time 
    int zntime = findintable(zone);
    if(zntime == -1)return -1; 

    davidtime eugh;
    if(strtimetoint(timey, &eugh) == -1) return -2;
    int mins = eugh.hour * 60 + eugh.minutes;
    int total = tozone ? mins - offset + zntime : mins - zntime + offset; //ok this is better yeah
    
    int day = 0;
    while (total < 0){
        total += 1440; day--; 
    }
    while (total >= 1440){
        total -= 1440; day++;
    }

    printf("%02d:%02d", total / 60, total % 60);
    if(day) printf(" %+dd", day);  
    printf("\n");
    return 0;
} 


int main (int argc, char **argv){

    if((argc <= 1) || (argc > 3)){
        printf("%s: usage: %s [TIME (24hs)] [ZONE]\ne.g: %s 7:15 est\n\nalso get relative times like %s [ZONE]\ne.g: %s est\n", argv[0], argv[0], argv[0], argv[0], argv[0]);
        exit(1);
    }

    char timestr[16];
    gethhmm(timestr, sizeof(timestr));
    if (argc == 2) {
        if (isdigit((unsigned char)argv[1][0])) {
            printf("timezones don't have numbers in them\n");
            return 1;
        }
        if (convert(timestr, argv[1], 1) == -1) {
            printf("%s: time zone not found, did you write it correctly?\n", argv[0]);
            return 1;
        }
        return 0;
    }

    int res = convert(argv[1], argv[2], 0);
    if (res == -1) {
        printf("%s: time zone not found, did you write it correctly?\n", argv[0]);
        return 1;
    }
    if (res == -2) {
        printf("%s: invalid time, use 24hs format like 7:15\n", argv[0]);
        return 1;
    }
    return 0;
}