mirror of
https://git.faggot-chan.online/timetolocal/
synced 2026-11-04 23:35:43 +01:00
124 lines
3.4 KiB
C
124 lines
3.4 KiB
C
#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;
|
|
}
|