Essentially the program I've made adds time when the times are listed in the kind of military format (eg. 2300 is equal to 11pm) and then a duration is added (eg. 345, 3 hours 45 minutes.)
I've come across an issue in that when you add time to something that surpasses midnight it will continue to add past that. So for instance if you add 2 hours (200) to 11pm (2300) you will get a result of 2500 which is illogical for this purpose.
What I need my program to do is reach 2400 (midnight) and then reset to 0 but continue to add the remaining amount that needed to be added.
I've been trying to figure this out but I cannot figure out how I'm going to make it add what remains after you reset it to 0.
Since minutes are added modulo 60 and hours modulo 24, you need to handle them separately.
Something like
int add_time(int old_time, int addition)
{
/* Calculate minutes */
int total_minutes = (old_time % 100) + (addition % 100);
int new_minutes = total_minutes % 60;
/* Calculate hours, adding in the "carry hour" if it exists */
int additional_hours = addition / 100 + total_minutes / 60;
int new_hours = (old_time / 100 + additional_hours) % 24;
/* Put minutes and hours together */
return new_hours * 100 + new_minutes;
}
Break 24 hour/minute encode as a 4-digit int into hours and minutes. Avoid assuming values are in their primary range.
Add
Re-form time into the primary range.
Example
typedef struct {
int hour; // Normal range 0 - 23
int minute; // Normal range 0 - 59
} hhmm;
hhmm int_to_hhmm(int src) {
src %= 2400;
if (src < 0) src += 2400;
hhmm dest = { src / 100, src % 100 };
return dest;
}
int hhmm_to_int(hhmm src) {
src.hour += src.minute / 60;
src.minute %= 60;
if (src.minute < 0) {
src.minute += 60;
src.hour--;
}
src.hour %= 24;
if (src.hour < 0) {
src.hour += 24;
}
return src.hour * 100 + src.minute;
}
int add_mill_format_times(int t0, int t1) {
hhmm hhmm0 = int_to_hhmm(t0);
hhmm hhmm1 = int_to_hhmm(t1);
hhmm sum = { hhmm0.hour + hhmm1.hour, hhmm0.minute + hhmm1.minute };
return hhmm_to_int(sum);
}
you can do
addTime(int time1,int time2{
int first,last,addH,addM
last = func1(time1) + func2(time2);
last=last1+last2;
if(last > 60){
addH=last/60;
addM=last%60;
}
first=func2(time1)+func2(time2);
first+= addH;
last += addM;
first/=24;
return first*100 + addM;
}
func2(int time){
int i;
for(i=0;i<2;i++)
time/=10;
return time;
}
func1(int time){
int l=time%10;
time/=10;
int m=time%10;
return m*10 + l;
}
Related
I've spent a good hour on this, but I can't create a formula that works for my c program. (I have a new programmer).
I have to convert UTC time to its respective time in a particular city. My code works perfectly except here. Here it gives me the wrong answer. I can't wrap my head around it (I created a formula but it makes no sense to me).
In my program, time is entered as 24 hour time. 9AM = 900, 12PM = 1200, 12am = 0 etc.
If we are asked to convert 2359 to Eucla time (UTC +845) my program outputs 804. The correct answer is 844.
I figured out how to calculate 844, but I make no sense of it.
2359 + 845 = 3204 (adding the timezone offset 845 to the UTC time)
3204 - 60 = 3144 (minus 60 for some reason [I followed my time overflow formula]
3144 - 2400 = 2400 (minus 2400 because time cannot be more than 2359)
How my program works
First plus UTC and offset time
calculatedTime = UTC + offset;
Then under that
if (calculatedTime < 2359) {
calculatedTime = calculatedTime - 2400;
}
I also have another function which checks for overflow time underneath
if (((calculatedTime > 59) && (calculatedTime < 99)) || ((calculatedTime > 159) && (calculatedTime < 199))) {
// All the way to 2359
calculatedTime = calculatedTime - 60 + 100;
}
You need to separate the time into hours and minutes. Then add the time zone offsets to the hours and minutes separately. Handle roll-over. Finally, recombine the hours and minutes into the final answer.
Like this:
int main(void)
{
// inputs
int time = 2359;
int zone = 845;
// separate hours and minutes
int timeHours = time / 100;
int timeMinutes = time % 100;
int zoneHours = zone / 100;
int zoneMinutes = zone % 100;
// add the hours and minutes
int hours = timeHours + zoneHours;
int minutes = timeMinutes + zoneMinutes;
// handle the rollover conditions
if (minutes > 60) {
minutes -= 60;
hours++;
}
if (hours > 24) {
hours -= 24;
}
// recombine the hours and minutes
int adjustedTime = hours * 100 + minutes;
printf("%d\n", adjustedTime);
}
Note that this code only works for timezones with positive offsets. You'll need to figure out how to make it work for negative time zones.
OP's code has various off-by-one errors.
// if (((calculatedTime > 59) && (calculatedTime < 99)) ||
// ((calculatedTime > 159) && (calculatedTime < 199))) {
if (((calculatedTime > 59) && (calculatedTime < 100)) ||
((calculatedTime > 159) && (calculatedTime < 200))) {
// if (hours > 24) {
// hours -= 24;
// }
if (hours >= 24) {
hours -= 24;
}
Also code has more clarity using values like 60, 100
if (((calculatedTime >= 60) && (calculatedTime < 100)) ||
((calculatedTime >= 60*2) && (calculatedTime < 100*2))) {
Yet OP's approach fails with negative numbers.
To cope with positive and negative time values, split the "hhmm" time into a hours and minutes. Look for conditions of "minute" overflow. I recommend 2 helper functions to split and combine results.
#include <stdio.h>
#include <stdlib.h>
void hhmm_split(int hhmm, int *hour, int *min) {
*hour = hhmm / 100;
*min = hhmm % 100;
}
/* `min` may be outside the primary range of (-60 ... 60) */
int hhmm_combine(int hour, int min) {
hour += min / 60;
min %= 60;
if (hour < 0 && min > 0) {
min -= 60;
hour++;
} else if (hour > 0 && min < 0) {
min += 60;
hour--;
}
hour %= 24;
return hour * 100 + min;
}
Test code
void hhmm_add(int t1, int t2) {
int t1_hh, t1_mm, t2_hh, t2_mm;
hhmm_split(t1, &t1_hh, &t1_mm);
hhmm_split(t2, &t2_hh, &t2_mm);
int sum = hhmm_combine(t1_hh + t2_hh, t1_mm + t2_mm);
printf("t1:% 05d + t2:% 05d = sum:% 05d\n", t1, t2, sum);
}
int main(void) {
hhmm_add(2359, 845);
hhmm_add(2359, -845);
hhmm_add(-2359, 845);
hhmm_add(-2359, -845);
}
Output:
t1: 2359 + t2: 0845 = sum: 0844
t1: 2359 + t2:-0845 = sum: 1514
t1:-2359 + t2: 0845 = sum:-1514
t1:-2359 + t2:-0845 = sum:-0844
My target is to compare two u_long timestamps, delivered by a GPS device. A long integer like 16290212 has the following structure:
hhmmssµµ
The following code snippet shows an approach how to parse a long integer to an integer array. But I think this is not very efficient. What would be the quickest way to compare two timestamps? I would love to use an UNIX timestamp, but it is not possible in this context.
u_long timestamp_old = 16290212;
u_long base = 1000000;
/* arr[0]: hours
* arr[1]: minutes
* arr[2]: seconds
* arr[3]: miliseconds */
int arr[4];
int i=0;
// parse timestamp_old
while(base >= 1)
{
arr[i++] = (timestamp_old / base);
timestamp_old = (timestamp_old % base);
base /= 100;
}
Your timestamps are u_longs; compare them the same way you compare any 2 u_longs, something like <.
What would be the quickest way to compare two timestamps?
I want to check if the difference is smaller than 400 ms
Perhaps not the fastest yet at least a starting point with a quick worst case. Note that ssµµµ is the same as µµµµµ.
int32_t GPS_to_ms(u_long timestamp) {
int32_t ms = timestamp%100000;
int32_t hhmm = timestamp / 100000;
ms += (hhmm%100)*60*1000;
int32_t hh = hhmm / 100;
ms += hh*60*60*1000;
return ms;
}
if (GPS_to_ms(timestamp_later) - GPS_to_ms(timestamp_first) < 400) {
// timestamps are in close succession.
}
To speed things up on average, 1) assume timestamp_later >= timestamp_first
is usually true 2) timestamps typically have the same hhmm
bool GPS_compare_400(u_long first, u_long later) {
int32_t ms1 = first%100000;
int32_t hhmm1 = first/100000;
int32_t ms2 = later%100000;
int32_t hhmm2 = later/100000;
if (hhmm1 == hhmm2) {
return ms2 - ms1 < 400;
}
return GPS_to_ms(timestamp_later) - GPS_to_ms(timestamp_first) < 400;
}
I assume the input is a string gpstime of the form "hhmmssµµµ". I assume that trailing zeros are always present such that there are always exactly three digits for the microseconds part.
1.
int h, m, s, us;
double t;
if(sscanf(gpstime, "%2d%2d%2d%3d", &h, &m, &s, &us) == 4)
t = (h * 60L + m) * 60 + s + us/1000.;
else {
/* parse error */
t = 0;
}
If that's not efficient enough, here's something down-and-dirty, eschewing scanf:
2.
#define Ctod(c) ((c) - '0')
int h = 10 * Ctod(utctime[0]) + Ctod(utctime[1]);
int m = 10 * Ctod(utctime[2]) + Ctod(utctime[3]);
int s = 10 * Ctod(utctime[4]) + Ctod(utctime[5]);
int us = 100 * Ctod(utctime[6]) + 10 * Ctod(utctime[7]) + Ctod(utctime[8]);
double t = (h * 60L + m) * 60 + s + us/1000.;
In either case, once you've got your t values, just subtract and compare as usual.
If you don't want to use floating point, change t to long int, change the scaling factors as appropriate, and compare your final difference to 400 instead of 0.4.
(But with all of this said, I wouldn't worry about efficiency too much. 10 Hz may sound fast to a pitiful human, but a tenth of a second is a hell of a long time for a decent computer.)
I am currently trying to create a program where the user gives two values (times, hh:mm:ss) and gets the difference between the two times. This works, if one would only use 12h formats; however, using the 24h format is a must.
My current time struct looks like the following:
typedef struct time {
int hours;
int minutes;
int seconds;
} time;
And my current function to calculate the difference looks like this:
time calculateTimeDiff(time time1, time time2) {
time timeResult;
timeResult.hours = time1.hours - time2.hours;
if(time1.minutes != 00 && time2.minutes != 00) {
timeResult.minutes = time1.minutes - time2.minutes;
}
else {
timeResult.minutes = 00;
}
if(time1.seconds != 00 && time2.seconds != 00) {
timeResult.seconds = time1.seconds - time2.seconds;
}
else {
timeResult.seconds = 00;
}
while(timeResult.seconds > 60) {
timeResult.seconds -= 60;
timeResult.minutes += 1;
}
while(timeResult.minutes > 60) {
timeResult.minutes -= 60;
timeResult.hours += 1;
}
return timeResult;
}
My attempts to support the 24h format have been to add 12 hours to the time if the hours "exceed" the 12 hour format, and to divide the time by two (haven't been far from complete shots in the dark, just to see what works and what wouldn't work). However, this has only resulted in getting incorrect results.
Any and all answers appreciated!
How to get the time difference between two times (24h format)
Although code could use many if-then-else's as in OP's code, it would be simple to convert the h:m:s time into seconds, subtract, and convert back to h:m:s. So I recommend a re-write:
typedef struct time {
int hours;
int minutes;
int seconds;
} time;
long time_sec(time t) {
return (t.hours * 60L + t.minutes)*60 + t.seconds;
}
time sec_time(long s) {
time t;
t.hours = s / 3600;
s %= 3600;
t.minutes = s / 60;
t.seconds = s %= 60;
return t;
}
time calculateTimeDiff(time time1, time time2) {
long t1 = time_sec(time1);
long t2 = time_sec(time2);
long diff = t1 - t2;
return sec_time(diff);
}
#include <stdio.h>
void test(time t1, time t2) {
printf("t1: %3d:%3d:%3d, ", t1.hours, t1. minutes, t1.seconds);
printf("t2: %3d:%3d:%3d, ", t2.hours, t2. minutes, t2.seconds);
time t3 = calculateTimeDiff(t1, t2);
printf("t1-t2: %3d:%3d:%3d, ", t3.hours, t3. minutes, t3.seconds);
t3 = calculateTimeDiff(t2, t1);
printf("t2-t1: %3d:%3d:%3d\n", t3.hours, t3. minutes, t3.seconds);
}
int main(void) {
test((time){14,00,00}, (time){13,00,00});
test((time){22,00,00}, (time){04,00,00});
}
Output
t1: 14: 0: 0, t2: 13: 0: 0, t1-t2: 1: 0: 0, t2-t1: -1: 0: 0
t1: 22: 0: 0, t2: 4: 0: 0, t1-t2: 18: 0: 0, t2-t1: -18: 0: 0
Note that the difference may result in negative values for the members of time returned in calculateTimeDiff().
You can change to time structure instead of both start and end time integer value
#include<iostream>
using namespace std;
void difftime(int startTime, int iRecordEndTime)
{
int duration_min = 0;
cout<<"iRecordEndTime = "<<iRecordEndTime<<endl;
cout<<"startTime = "<<startTime<<endl;
if ( (iRecordEndTime/100 < startTime/100) || ((iRecordEndTime/100 == startTime/100) && (iRecordEndTime%100 <= startTime%100)) )
{
duration_min = ((iRecordEndTime / 100 + 24)*60 + iRecordEndTime%100) - ((startTime/100)*60 + startTime%100);
}
else
{
duration_min = (iRecordEndTime / 100 - startTime/100)*60 + (iRecordEndTime%100 - startTime%100);
}
cout<<"duration_min = "<<duration_min<<endl;
}
int main()
{
cout<<"enter the start time Hour:Minutes xxxx"<<endl;
int startTime{0};
cin>>startTime;
cout<<"enter the End time Hour:Minutes xxxx"<<endl;
int iRecordEndTime{0};
cin>>iRecordEndTime;
difftime(startTime, iRecordEndTime );
}
Output
enter the start time Hour:Minutes xxxx\
2300\
enter the End time Hour:Minutes xxxx\
0000\
iRecordEndTime = 0\
startTime = 2300\
duration_min = 60
I'm new to coding and trying to figure out how to get code to round up to the next hour. The only method I've been able to think up (i.e. the only method I've been taught) is to just make else if statements for every hour. Clearly this isn't efficient at all and i know there's probably something much simpler. I was given a clue that there's a math equation involved?
Here's what i coded up so far:
#include <stdio.h>
int main()
{
//listens for value of "cost"
float cost;
printf("How much does this go-kart location charge per hour?\n");
scanf("%f", &cost);
//listens for value of "time"
float time;
printf("How many minutes can you spend there?\n");
scanf("%f", &time);
// i have to get it to round time to values of 60 (round up to next hour)
//really overcomplicated lack of knowledge workaround.txt
if (time < 60 && time > 0){
time = 1;
} else if(time > 61 && time < 70){
time = 2;
} else if(time > 71 && time < 80){
time = 3;
} else if(time > 81 && time < 90){
time = 4;
} else if(time > 91 && time < 100){
time = 5;
} else if(time > 101 && time < 160){
time = 6;
}
//etc etc
float total = cost * time;
printf("Your total will be $%f\n", total);
return 0;
}
For non regular intervals, one could do something like
int times[] = { 60; 70; 80; 90; 100; 160; INT_MAX }; // INT_MAX is to avoid segfault for bad input
int facts[] = { 1; 2; 3; 4; 5; 6; -1 }; // -1 is value for bad input
int it = 0;
while(times[it] < time) ++it;
int result = facts[it];
Note that you code doesnt have valid results for time = 60, 70, etc ... you should check the wanted behaviour
int hour = time/60;
if(60*hour < time)
++hour;
This is fairly basic math.
time / 60 would round down to to give you the hour.
Therefore (time / 60) + 1 rounds up.
If the maximum is 6 hours then simply check:
hour = time/60 + 1;
if (hour > 6) hour = 6;
Of course I'm assuming that time is an int. If it's a float then you can use floor or ceil to round up or down:
hour = floor(time/60 +1);
or
hour = ceil(time/60);
I think this is not bad
time = (time % 60) ? time / 60 + 1 : time / 60
I need to know how can I add 2 "hours" as integer?
It is 24-h format
int add2Hours(int _time1,int _time2)
{
}
sample: 13:45 is: (hhmm) 1345
1345 + 30 returns 1415
Your time is in hhmm format, separate the hh and mm part. Then add the parts separately.
int add2hours(int _time1, int _time2)
{
int hh1, hh2, mm1, mm2;
int rHH,rMM, res;
hh1 = _time1/100;
hh2 = _time2/100;
mm1 = _time1 % 100;
mm2 = _time2 % 100;
rMM = mm1 + mm2;
rHH = rMM/60;
rMM = rMM % 60;
rHH = rHH + hh1 + hh2;
res = rHH*100 + rMM;
return res;
}
NOTE: This will not handle any time greater than 24hrs. e.g. if the inputs are 2345 and 30, the output will be 2415 instead of 15(0015). You have to handle it if you need.
If the function for adding time is declared as follows,
int add2Hours(int _time1,int _time2);
and the syntax of passing time is as follows,
hhmm (For example 2230)
Then you can add the times as follow,
temp1= _time1;
temp2= _time2;
m1 = temp1 % 100;
m2 = temp2 % 100;
h1 = temp1 / 100;
h2 = temp2 / 100;
m3 = m1 + m2;
m3 > 59 ? m3=m3%60, h3=1 : h3=0;
h3 = h1 + h2 + h3;
h3 > 23 ? h3=h3%24, d=1 : d=0; /* If more than 23 hours */
printf("\nThe time is %d-%d-%d",d,h3,m3);
First convert the time to a common domain(sec/millisec...). Then add and make the result to the required format.
How about this?
int add2Hours(int _time1,int _time2)
{
int minutes = (_time1%100 + _time2%100)
int time = (((minutes/60)+(_time1/100 + _time2/100))%24)*100 + minutes%60;
return time;
}
Add the hours together. 13 + 0.
Get the minutes of each time by subtracting the time with the time/100*100. Note that integer arithmetic in C truncates. Example:
m = time - (time/100*100)
m = 1345 - (1345/100*100)
m = 1345 - (13*100)
m = 1345 - 1300
m = 45
Add the minutes together. 45 + 30 = 75.
Add "the minute sum/60" hours to the result. I.e. 75/60 = 1.
Then add "the minute sum modulo 60" minutes to the same result. I.e. 75%60 = 15.
Thanks guys... here is my function!
int Add2Times (int _time1, int _time2)
{
int hour = _time1 / 100 + _time2 / 100;
int min = _time1 % 100 + _time2 % 100;
hour += min / 60;
min = min % 60;
hour = hour % 24;
return hour * 100 + min;
}