#include #include #include #include #include #include #include #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; } int gettimeandstuff(void){ time_t rawtime = time(NULL); struct tm utc = *gmtime(&rawtime); /*copy, gmtime uses a static buffer*/ utc.tm_isdst = -1; time_t gmt = mktime(&utc); return difftime(rawtime, gmt) / 60; } /*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){ int offset = gettimeandstuff(); //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; } /*takes in a single argument and returns whatever timezones allign with the input*/ int convert2(char *timey){ /*it should fist get the offset between local time and input it should probably round up to ~5 minutes so multiples of 5 input is like 7:32 rounds down to 7:30 finds the closest match, on many matches it just presents the first in the list*/ int localoffset = gettimeandstuff(); davidtime hi; if(strtimetoint(timey, &hi) == -1) return -2; char nowstr[16]; davidtime now; gethhmm(nowstr, sizeof(nowstr)); strtimetoint(nowstr, &now); int inmins = hi.hour * 60 + hi.minutes; int nowmins = now.hour * 60 + now.minutes; inmins -= inmins % 5; /*round down to multiples of 5*/ nowmins -= nowmins % 5; //offset of the zone that has the input as its current time int target = localoffset + (inmins - nowmins); int best = -1, bestdist = 1441; for(size_t i = 0; i < TZTABLE_LENGHT; i++){ //distance on the 24h clock so +13 and -11 count as the same time int d = ((tz_table[i].offset - target) % 1440 + 1440) % 1440; if(d > 720) d = 1440 - d; if(d < bestdist){ bestdist = d; best = (int)i; } } if(best == -1) return -1; int off = tz_table[best].offset; printf("%s (UTC%c%02d:%02d)\n", tz_table[best].zn, off < 0 ? '-' : '+', abs(off) / 60, abs(off) % 60); 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\nor find which zone has a given time right now like %s [TIME (24hs)]\ne.g: %s 17:00\n", argv[0], argv[0], 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])) { int res2 = convert2(argv[1]); if (res2 == -2) { printf("%s: invalid time, use 24hs format like 7:15\n", argv[0]); return 1; } if (res2 == -1) { printf("%s: no time zones to match against\n", argv[0]); return 1; } return 0; } 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; }