Reputation: 1879
In objective-c, how can I convert an integer (representing seconds) to days, minutes, an hours?
Thanks!
Upvotes: 26
Views: 85861
Reputation: 800
Initially I worked out a solution similar to fish's answer:
const secondsToString = s => {
const secondsOfYear = 60 * 60 * 24 * 365;
const secondsOfDay = 60 * 60 * 24;
const secondsOfHour = 60 * 60;
const secondsOfMinute = 60;
let y = ~~(s / secondsOfYear); s %= secondsOfYear;
let d = ~~(s / secondsOfDay); s %= secondsOfDay;
let h = ~~(s / secondsOfHour); s %= secondsOfHour;
let m = ~~(s / secondsOfMinute); s %= secondsOfMinute;
y = (y > 0 ? (y + 'y ') : '');
d = (d > 0 ? (d + 'd ') : '');
h = (h > 0 ? (h + 'h ') : '');
m = (m > 0 ? (m + 'm ') : '');
s = (s > 0 ? (s + 's ') : '');
return y + d + h + m + s;
}
I noticed that it could be generalized with array map()
and reduce()
functions since it includes some iterations and recursions.
const intervalToLevels = (interval, levels) => {
const cbFun = (d, c) => {
let bb = d[1] % c[0],
aa = (d[1] - bb) / c[0];
aa = aa > 0 ? aa + c[1] : '';
return [d[0] + aa, bb];
};
let rslt = levels.scale.map((d, i, a) => a.slice(i).reduce((d, c) => d * c))
.map((d, i) => ([d, levels.units[i]]))
.reduce(cbFun, ['', interval]);
return rslt[0];
};
const TimeLevels = {
scale: [365, 24, 60, 60, 1],
units: ['y ', 'd ', 'h ', 'm ', 's ']
};
const secondsToString = interval => intervalToLevels(interval, TimeLevels);
Easily you could extend the function intervalToLevels()
to other measurement levels, such as liquid mass, length, and so on.
const LengthLevels = {
scale: [1760, 3, 12, 1],
units: ['mi ', 'yd ', 'ft ', 'in ']
};
const inchesToString = interval => intervalToLevels(interval, LengthLevels);
const LiquidsLevels = {
scale: [4, 2, 2, 8, 1],
units: ['gal ', 'qt ', 'pt ', 'cup ', 'fl_oz ']
};
const ouncesToString = interval => intervalToLevels(interval, LiquidsLevels);
Upvotes: 1
Reputation: 21
This is my algorithm for converting seconds to seconds, minutes and hours (only using the total amount of seconds and the relation between each of them):
int S = totalSeconds % BaseSMH
int M = ((totalSeconds - totalSeconds % BaseSMH) % BaseSMH ^ 2) / BaseSMH
int H = (totalSeconds - totalSeconds % BaseSMH - ((totalSeconds - totalSeconds % BaseSMH) % BaseSMH ^ 2)) / BaseSMH ^ 2
And here follows my explanation of it:
Test time converted to seconds: HH:MM:SS = 02:20:10 => totalSeconds = 2 * 3600 + 20 * 60 + 10 = 7200 + 1200 + 10 = 8410
The base between seconds -> minutes and minutes -> hours is 60 (from seconds -> hours it's 60 ^ 2 = 3600).
int totalSeconds = 8410
const int BaseSMH = 60
Each unit (here represented by a variable) can be calculated by removing the previous unit (expressed in seconds) from the total amount of seconds and divide it by its relation between seconds and the unit we are trying to calculate. This is what each calulation looks like using this algorithm:
int S = totalSeconds % BaseSMH
int M = ((totalSeconds - S) % BaseSMH ^ 2) / BaseSMH
int H = (totalSeconds - S - M * BaseSMH) / BaseSMH ^ 2
As with all math we can now substitute each unit in the minutes and hours calculations with how we calculated the previous unit and each calculation will then look like this (remember that dividing with BaseSMH in the M calculation and multiplying by BaseSMH in the H calulation cancels each other out):
int S = totalSeconds % BaseSMH
int M = ((totalSeconds - totalSeconds % BaseSMH) % BaseSMH ^ 2) / BaseSMH
int H = (totalSeconds - totalSeconds % BaseSMH - ((totalSeconds - totalSeconds % BaseSMH) % BaseSMH ^ 2)) / BaseSMH ^ 2
Testing with the "totalSeconds" and "BaseSMH" from above will look like this:
int S = 8410 % 60
int M = ((8410 - 8410 % 60) % 60 ^ 2) / 60
int H = (8410 - 8410 % 60 - ((8410 - 8410 % 60) % 60 ^ 2)) / 60 ^ 2
Calculating S:
int S = 8410 % 60 = 10
Calculating M:
int M = ((8410 - 8410 % 60) % 60 ^ 2) / 60
= ((8410 - 10) % 3600) / 60
= (8400 % 3600) / 60
= 1200 / 60
= 20
Calculating H:
int H = (8410 - 8410 % 60 - ((8410 - 8410 % 60) % 60 ^ 2)) / 60 ^ 2
= (8410 - 10 - ((8410 - 10) % 3600)) / 3600
= (8400 - (8400 % 3600)) / 3600
= (8400 - 1200) / 3600
= 7200 / 3600
= 2
With this you can add whichever unit you want, you just need to calculate what the relation is between seconds and the unit you want. Hope you understand my explanations of each step. If not, just ask and I can explain further.
Upvotes: 1
Reputation: 1
You will get days,hours,minutes and seconds from total seconds(self.secondsLeft)
days = self.secondsLeft/86400;
hours = (self.secondsLeft %86400)/3600;
minutes = (self.secondsLeft % 3600) / 60;
seconds = (self.secondsLeft %3600) % 60;
Code ......
[NSTimer scheduledTimerWithTimeInterval: 1.0 target:self selector:@selector(updateCountdown) userInfo:nil repeats: YES];
-(void) updateCountdown {
int days,hours,minutes,seconds;
self.secondsLeft--;
days = self.secondsLeft/86400;
hours = (self.secondsLeft %86400)/3600;
minutes = (self.secondsLeft % 3600) / 60;
seconds = (self.secondsLeft %3600) % 60;
NSLog(@"Time Remaining =%@",[NSString stringWithFormat:@"%02d:%02d:%02d:%02d",days, hours, minutes,seconds]);
}
Upvotes: 0
Reputation: 1
Try doing the following:
x=int(input("enter a positive integer: "))
sec = int(x % 60);
minu =int((x % 3600) / 60);
ho =int((x % 86400) / 3600);
days =int(x / (60 * 60 * 24));
print(int(days),"days", ho,"hours", minu , "minutes" , sec ,"seconds" )
Upvotes: -1
Reputation: 437
The most preferred way in objective-c might be this one, as recommend by Apple in their doc.
NSDate *startDate = [NSDate date];
NSDate *endDate = [NSDate dateWithTimeInterval:(365*24*60*60*3+24*60*60*129) sinceDate:startDate];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents *components = [gregorian components:unitFlags
fromDate:startDate
toDate:endDate options:0];
NSInteger years = [components year];
NSInteger months = [components month];
NSInteger days = [components day];
NSLog(@"years = %ld months = %ld days = %ld",years,months,days);
Make sure not to retrieve components not defined with the unitFlags, integer will be "undefined".
Upvotes: 7
Reputation: 278
Just a bit modification for both compatible with 32 bit & 64 bit. Using NSInteger
the system will automatically convert to int or long basing on 32/64 bit.
NSInteger seconds = 10000;
NSInteger remainder = seconds % 3600;
NSInteger hours = seconds / 3600;
NSInteger minutes = remainder / 60;
NSInteger forSeconds = remainder % 60;
By the same way you can convert to days, weeks, months, years
Upvotes: 3
Reputation: 97
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
Date dateObj1=null;
Date dateObj2=null;
try {
// String format = "MM/dd/yyyy hh:mm:ss";
dateObj1 = sdf.parse(Appconstant.One_One_time);
dateObj2 = sdf.parse(Appconstant.One_Two_time);
Log.e(TAG, "dateObj12" + dateObj1.toString() + "---" + dateObj2.toString());
DecimalFormat crunchifyFormatter = new DecimalFormat("###,###");
long diff = dateObj2.getTime() - dateObj1.getTime();
/*int diffDays = (int) (diff / (24 * 60 * 60 * 1000));
System.out.println("difference between days: " + diffDays);
int diffhours = (int) (diff / (60 * 60 * 1000));
System.out.println("difference between hours: "
+ crunchifyFormatter.format(diffhours));
int diffmin = (int) (diff / (60 * 1000));
System.out.println("difference between minutes: "
+ crunchifyFormatter.format(diffmin));*/
int diffsec = (int) (diff / (1000));
System.out.println("difference between seconds:"
+ crunchifyFormatter.format(diffsec));
Upvotes: 0
Reputation: 452
I know this is an old post but I wanted to share anyway. The following code is what I use.
int seconds = (totalSeconds % 60);
int minutes = (totalSeconds % 3600) / 60;
int hours = (totalSeconds % 86400) / 3600;
int days = (totalSeconds % (86400 * 30)) / 86400;
First line - We get the remainder of seconds when dividing by number of seconds in a minutes.
Second line - We get the remainder of seconds after dividing by the number of seconds in an hour. Then we divide that by seconds in a minute.
Third line - We get the remainder of seconds after dividing by the number of seconds in a day. Then we divide that by the number of seconds in a hour.
Fourth line - We get the remainder of second after dividing by the number of seconds in a month. Then we divide that by the number of seconds in a day. We could just use the following for Days...
int days = totalSeconds / 86400;
But if we used the above line and wanted to continue on and get months we would end up with 1 month and 30 days when we wanted to get just 1 month.
Open up a Playground in Xcode and try it out.
Upvotes: 17
Reputation: 31
Use the built-in function strftime():
static char timestr[80];
char * HHMMSS ( time_t secs )
{
struct tm ts;
ts = *localtime(&secs);
strftime(timestr, sizeof(timestr), "%a %b %d %H:%M:%S %Y %Z", &ts); // "Mon May 1, 2012 hh:mm:ss zzz"
return timestr;
}
Upvotes: 3
Reputation: 2034
try this,
int forHours = seconds / 3600,
remainder = seconds % 3600,
forMinutes = remainder / 60,
forSeconds = remainder % 60;
and you can use it to get more details as days, weeks, months, and years by following the same procedure
Upvotes: 37
Reputation: 2010
In this case, you simply need to divide.
days = num_seconds / (60 * 60 * 24);
num_seconds -= days * (60 * 60 * 24);
hours = num_seconds / (60 * 60);
num_seconds -= hours * (60 * 60);
minutes = num_seconds / 60;
For more sophisticated date calculations, such as the number of days within the ten million seconds after 3pm on January 19th in 1983, you would use the NSCalendar class along with NSDateComponents. Apple's date and time programming guide helps you here.
Upvotes: 49