How to Display a Time Interval


Dave
 

Objective-C, Mac.

Hi,

I’m trying to display a countdown to a date in the future e.g. the number of years, weeks and days to 1/1/2021.

I have the Time Interval between now and the future date in seconds, but I can’t seem to find any methods to display this in terms of years. months, weeks, days etc.

Is there a method or class somewhere that does this or do I need to roll my own?

All the Best
Dave


Owen Hartnett
 

Look at the NSDate and NSDateFormatter classes.

-Owen

On May 19, 2019, at 6:02 AM, Dave <dave@...> wrote:

Objective-C, Mac.

Hi,

I’m trying to display a countdown to a date in the future e.g. the number of years, weeks and days to 1/1/2021.

I have the Time Interval between now and the future date in seconds, but I can’t seem to find any methods to display this in terms of years. months, weeks, days etc.

Is there a method or class somewhere that does this or do I need to roll my own?

All the Best
Dave




Shane Stanley
 

On 19 May 2019, at 8:02 pm, Dave <dave@...> wrote:

I have the Time Interval between now and the future date in seconds, but I can’t seem to find any methods to display this in terms of years. months, weeks, days etc.
There's NSDateComponentsFormatter, although it's fairly limited.

--
Shane Stanley <sstanley@...>
<www.macosxautomation.com/applescript/apps/>, <latenightsw.com>


Marco S Hyman
 

I have the Time Interval between now and the future date in seconds, but I can’t seem to find any methods to display this in terms of years. months, weeks, days etc.
Can not be done accurately using only a Time Interval in seconds. You also need either the start or end date to figure out leap year complications.

Is there a method or class somewhere that does this or do I need to roll my own?
Don’t know of any. I’d probably roll my own.

Marc


Gary L. Wade
 

Use NSCalendar’s method:

- (NSDateComponents *)components:(NSCalendarUnit)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSCalendarOptions)opts;


On May 19, 2019, at 3:02 AM, Dave <dave@...> wrote:

Objective-C, Mac.

Hi,

I’m trying to display a countdown to a date in the future e.g. the number of years, weeks and days to 1/1/2021.

I have the Time Interval between now and the future date in seconds, but I can’t seem to find any methods to display this in terms of years. months, weeks, days etc.

Is there a method or class somewhere that does this or do I need to roll my own?

All the Best
Dave


Marco S Hyman
 

Ooops, I’m wrong...

Can not be done accurately using only a Time Interval in seconds. You also need either the start or end date to figure out leap year complications.
Leap year complications should be part of the time interval and be ignored.

My programming history got the better of my knowledge... the first ever COBOL program I wrote figured out how many days until my military enlistment was over -- and it was off by one because of a leap year.


Gary L. Wade
 

Sorry, forgot the last part.  After you get the components using the calendar you wish to use with your two dates, then call NSDateComponentsFormatter.  For a simple case, you could get by with:

+ (nullable NSString *)localizedStringFromDateComponents:(NSDateComponents *)components unitsStyle:(NSDateComponentsFormatterUnitsStyle) unitsStyle;


On May 19, 2019, at 11:13 AM, Gary L. Wade <garywade@...> wrote:

Use NSCalendar’s method:

- (NSDateComponents *)components:(NSCalendarUnit)unitFlags fromDate:(NSDate *)startingDate toDate:(NSDate *)resultDate options:(NSCalendarOptions)opts;


On May 19, 2019, at 3:02 AM, Dave <dave@...> wrote:

Objective-C, Mac.

Hi,

I’m trying to display a countdown to a date in the future e.g. the number of years, weeks and days to 1/1/2021.

I have the Time Interval between now and the future date in seconds, but I can’t seem to find any methods to display this in terms of years. months, weeks, days etc.

Is there a method or class somewhere that does this or do I need to roll my own?

All the Best
Dave



Shane Stanley
 

On 20 May 2019, at 4:20 am, Gary L. Wade <garywade@...> wrote:

After you get the components using the calendar you wish to use with your two dates, then call NSDateComponentsFormatter.
If he has a time interval, why not just use NSDateComponentsFormatter's -stringFromTimeInterval:?

Either way, be aware that NSDateComponentsFormatter doesn't cope with an interval of 2^32 or above. Which seems a bit extraordinary, given it didn't appear until macOS 10.10.

--
Shane Stanley <sstanley@...>
<www.macosxautomation.com/applescript/apps/>, <latenightsw.com>


Dave
 

Hi,

As far as I know I don’t have to worry about leap years, get the Interval between now and some future date, this includes all the leap years in between. I am displaying it at the moment by dividing by the number of seconds in a year, week, hours and minute which is accurate enough for this applications.

Here is a method to do it:


#define kLTWTimeSecondsPerMinute 60
#define kLTWTimeMinutesPerHour 60
#define kLTWTimeSecondsPerHour (kLTWTimeSecondsPerMinute * kLTWTimeMinutesPerHour)
#define kLTWTimeHoursPerDay 24
#define kLTWTimeDaysPerWeek 7
#define kLTWTimeWeeksPerYear 52

#define kLTWTimeSecondsPerDay (kLTWTimeSecondsPerHour * kLTWTimeHoursPerDay)
#define kLTWTimeSecondsPerWeek (kLTWTimeSecondsPerDay * kLTWTimeDaysPerWeek)
#define kLTWTimeSecondsPerYear (kLTWTimeSecondsPerWeek * kLTWTimeWeeksPerYear)


-(NSString*) newIntevalStringWithDateString:(NSString*) theDateString andTitleString:(NSString*) theTitleString
{
NSDateFormatter* myDateFormatter;
NSDate* myIntevalDate;
NSString* myIntevalString;
NSTimeInterval myWorkTimeInteval;
NSInteger myNumberOfYears;
NSInteger myNumberOfWeeks;
NSInteger myNumberOfDays;
NSInteger myNumberOfHours;
NSInteger myNumberOfMinutes;

myDateFormatter = [[NSDateFormatter alloc] init];
[myDateFormatter setDateFormat:@"yyyy-MM-dd"];
myIntevalDate = [myDateFormatter dateFromString:theDateString];
myWorkTimeInteval = [myIntevalDate timeIntervalSinceNow];

myNumberOfYears = myWorkTimeInteval / kLTWTimeSecondsPerYear;
myWorkTimeInteval = myWorkTimeInteval - (myNumberOfYears * kLTWTimeSecondsPerYear);

myNumberOfWeeks = myWorkTimeInteval / kLTWTimeSecondsPerWeek;
myWorkTimeInteval = myWorkTimeInteval - (myNumberOfWeeks * kLTWTimeSecondsPerWeek);

myNumberOfDays = myWorkTimeInteval / kLTWTimeSecondsPerDay;
myWorkTimeInteval = myWorkTimeInteval - (myNumberOfDays * kLTWTimeSecondsPerDay);

myNumberOfHours = myWorkTimeInteval / kLTWTimeSecondsPerHour;
myWorkTimeInteval = myWorkTimeInteval - (myNumberOfHours * kLTWTimeSecondsPerHour);

myNumberOfMinutes = myWorkTimeInteval / kLTWTimeSecondsPerMinute;
myWorkTimeInteval = myWorkTimeInteval - (myNumberOfMinutes * kLTWTimeSecondsPerMinute);

myIntevalString = [[NSString alloc] initWithFormat:@"%@ - Years: %zd  Weeks: %2zd   Days: %zd   Hours: %zd   Minutes: %zd",theTitleString,myNumberOfYears,myNumberOfWeeks,myNumberOfDays,myNumberOfHours,myNumberOfMinutes];

return myIntevalString;
}

All the Best
Dave

On 19 May 2019, at 19:45, Marco S Hyman <marc@...> wrote:


I have the Time Interval between now and the future date in seconds, but I can’t seem to find any methods to display this in terms of years. months, weeks, days etc.

Can not be done accurately using only a Time Interval in seconds.  You also need either the start or end date to figure out leap year complications.

Is there a method or class somewhere that does this or do I need to roll my own?

Don’t know of any.  I’d probably roll my own.

Marc




Steve Mills
 

On May 20, 2019, at 04:26:31, Dave <dave@...> wrote:

As far as I know I don’t have to worry about leap years, get the Interval between now and some future date, this includes all the leap years in between. I am displaying it at the moment by dividing by the number of seconds in a year, week, hours and minute which is accurate enough for this applications.

Here is a method to do it:


#define kLTWTimeSecondsPerMinute 60
#define kLTWTimeMinutesPerHour 60
#define kLTWTimeSecondsPerHour (kLTWTimeSecondsPerMinute * kLTWTimeMinutesPerHour)
#define kLTWTimeHoursPerDay 24
#define kLTWTimeDaysPerWeek 7
#define kLTWTimeWeeksPerYear 52

#define kLTWTimeSecondsPerDay (kLTWTimeSecondsPerHour * kLTWTimeHoursPerDay)
#define kLTWTimeSecondsPerWeek (kLTWTimeSecondsPerDay * kLTWTimeDaysPerWeek)
#define kLTWTimeSecondsPerYear (kLTWTimeSecondsPerWeek * kLTWTimeWeeksPerYear)
*snip*

I'm not sure why you needed to reinvent the wheel when NSCalendar and NSDateComponents already does this via:

-(NSDateComponents*) components:(NSCalendarUnit)unitFlags fromDate:(NSDate*)startingDate toDate:(NSDate*)resultDate options:(NSCalendarOptions)opts;

All you need to do is format the string, like you did. Plus, you didn't display months, and most people would want to see that rather than having to do math in their head.

--
Steve Mills
Drummer, Mac geek


Dave
 

They wanted the number of weeks - I didn’t ask questions, plus the Total Number of Weeks and Total Number of days.

Cheers
Dave

On 20 May 2019, at 14:50, Steve Mills via Groups.Io <sjmills@...> wrote:

On May 20, 2019, at 04:26:31, Dave <dave@...> wrote:

As far as I know I don’t have to worry about leap years, get the Interval between now and some future date, this includes all the leap years in between. I am displaying it at the moment by dividing by the number of seconds in a year, week, hours and minute which is accurate enough for this applications.

Here is a method to do it:


#define kLTWTimeSecondsPerMinute 60
#define kLTWTimeMinutesPerHour 60
#define kLTWTimeSecondsPerHour (kLTWTimeSecondsPerMinute * kLTWTimeMinutesPerHour)
#define kLTWTimeHoursPerDay 24
#define kLTWTimeDaysPerWeek 7
#define kLTWTimeWeeksPerYear 52

#define kLTWTimeSecondsPerDay (kLTWTimeSecondsPerHour * kLTWTimeHoursPerDay)
#define kLTWTimeSecondsPerWeek (kLTWTimeSecondsPerDay * kLTWTimeDaysPerWeek)
#define kLTWTimeSecondsPerYear (kLTWTimeSecondsPerWeek * kLTWTimeWeeksPerYear)
*snip*

I'm not sure why you needed to reinvent the wheel when NSCalendar and NSDateComponents already does this via:

-(NSDateComponents*) components:(NSCalendarUnit)unitFlags fromDate:(NSDate*)startingDate toDate:(NSDate*)resultDate options:(NSCalendarOptions)opts;

All you need to do is format the string, like you did. Plus, you didn't display months, and most people would want to see that rather than having to do math in their head.

--
Steve Mills
Drummer, Mac geek




Peter Hudson
 

Hi Dave


I seem to remember using NSCalendatDate and the descriptionWithCalendarFormat: method to get what you want.
NSCalendarDate is now deprecated - the docs advocate the use of NSDate, NSCalendar, NSDateComponents to do the job now.
You have to roll the final string yourself - as far as I can see...

Peter

On 19 May 2019, at 11:02, Dave <dave@...> wrote:

Objective-C, Mac.

Hi,

I’m trying to display a countdown to a date in the future e.g. the number of years, weeks and days to 1/1/2021.

I have the Time Interval between now and the future date in seconds, but I can’t seem to find any methods to display this in terms of years. months, weeks, days etc.

Is there a method or class somewhere that does this or do I need to roll my own?

All the Best
Dave




 



On May 19, 2019, at 3:42 AM, Peter Hudson via Groups.Io <Peter.hudson@...> wrote:

I seem to remember using NSCalendatDate  and the descriptionWithCalendarFormat:   method to get what you want.
NSCalendarDate is now deprecated - the docs advocate the use of NSDate, NSCalendar, NSDateComponents to do the job now.
You have to roll the final string yourself - as far as I can see...

You want NSDateComponentsFormatter:

/* NSDateComponentsFormatter provides locale-correct and flexible string formatting of quantities of time, such as "1 day" or "1h 10m", as specified by NSDateComponents. For formatting intervals of time (such as "2PM to 5PM"), see NSDateIntervalFormatter. NSDateComponentsFormatter is thread-safe, in that calling methods on it from multiple threads will not cause crashes or incorrect results, but it makes no attempt to prevent confusion when one thread sets something and another thread isn't expecting it to change.


Gary L. Wade
 

As has been discussed before, you most likely won’t have to roll your own with the modern, non-deprecated frameworks. If you do need something that seems basic but you can’t find it, please write a bug and include its number here. I’m sure there are some, but that’s how you get things changed.
--
Gary

On May 19, 2019, at 3:42 AM, Peter Hudson via Groups.Io <Peter.hudson@...> wrote:

You have to roll the final string yourself - as far as I can see...