How to calculate someone's age elegantly? Does Duration work?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
18 messages Options
Reply | Threaded
Open this post in threaded view
|

How to calculate someone's age elegantly? Does Duration work?

Tim Mackinnon
Hi - I just ran a great MobProgramming session with Smalltalk for the XProLo group - and there was lots of great feedback and questions, however one of them really got me thinking…

We did a little exercise to create a Person class with name, dob - and then we TDD’d an age method… which seems simple on the surface but it gets to an interesting point - what about leap years? How old is someone on those years?

I thought that our plethora of Date/Duration classes might handle this - but I couldn’t spot something obvious and was wondering if someone had a neat answer.

Essentially if you try:

age

^Date today - self dob

You get a Duration,

But there isn’t :

^(Date today - self dob) asYears

There is is asDay

^(Date today - self dob) asDays

But then can you really

^(Date today - self dob) asDays / 365) truncated

But what about leap years… so

^(Date today - self dob) asDays / 365.25) truncated


It all feels a bit inelegant and I suspect there is a better Smalltalk way that is eluding me? Any suggestions?

Tim
Reply | Threaded
Open this post in threaded view
|

Re: How to calculate someone's age elegantly? Does Duration work?

Tim Mackinnon
Hmmm to compound my woes ) I notice that Timespan is broken - as the following fails:

testEndDateIsPreserved

        | startDate endDate |
        startDate := Date year: 2000 month: 2 day: 28.
   endDate := Date year: 2011 month: 2 day: 27.
     
        self assert: (Timespan starting: startDate ending: endDate) end equals: endDate.


> On 21 Jul 2017, at 00:58, Tim Mackinnon <[hidden email]> wrote:
>
> Hi - I just ran a great MobProgramming session with Smalltalk for the XProLo group - and there was lots of great feedback and questions, however one of them really got me thinking…
>
> We did a little exercise to create a Person class with name, dob - and then we TDD’d an age method… which seems simple on the surface but it gets to an interesting point - what about leap years? How old is someone on those years?
>
> I thought that our plethora of Date/Duration classes might handle this - but I couldn’t spot something obvious and was wondering if someone had a neat answer.
>
> Essentially if you try:
>
> age
>
> ^Date today - self dob
>
> You get a Duration,
>
> But there isn’t :
>
> ^(Date today - self dob) asYears
>
> There is is asDay
>
> ^(Date today - self dob) asDays
>
> But then can you really
>
> ^(Date today - self dob) asDays / 365) truncated
>
> But what about leap years… so
>
> ^(Date today - self dob) asDays / 365.25) truncated
>
>
> It all feels a bit inelegant and I suspect there is a better Smalltalk way that is eluding me? Any suggestions?
>
> Tim


Reply | Threaded
Open this post in threaded view
|

Re: How to calculate someone's age elegantly? Does Duration work?

K K Subbu
In reply to this post by Tim Mackinnon
Date>>ageOn: aDate
" assert: (self <= aDate)
| age |

age = aDate year - self year + 1.
aDate monthIndex < self monthIndex ifTrue: [ ^age - 1 ].
(aDate monthIndex = self monthIndex and: [aDate dayOfMonth < self
dayOfMonth]) ifTrue: [ ^age - 1 ].
^age

HTH .. Subbu

On Friday 21 July 2017 05:28 AM, Tim Mackinnon wrote:

> Hi - I just ran a great MobProgramming session with Smalltalk for the XProLo group - and there was lots of great feedback and questions, however one of them really got me thinking…
>
> We did a little exercise to create a Person class with name, dob - and then we TDD’d an age method… which seems simple on the surface but it gets to an interesting point - what about leap years? How old is someone on those years?
>
> I thought that our plethora of Date/Duration classes might handle this - but I couldn’t spot something obvious and was wondering if someone had a neat answer.
>
> Essentially if you try:
>
> age
>
> ^Date today - self dob
>
> You get a Duration,
>
> But there isn’t :
>
> ^(Date today - self dob) asYears
>
> There is is asDay
>
> ^(Date today - self dob) asDays
>
> But then can you really
>
> ^(Date today - self dob) asDays / 365) truncated
>
> But what about leap years… so
>
> ^(Date today - self dob) asDays / 365.25) truncated
>
>
> It all feels a bit inelegant and I suspect there is a better Smalltalk way that is eluding me? Any suggestions?
>
> Tim
>


Reply | Threaded
Open this post in threaded view
|

Re: How to calculate someone's age elegantly? Does Duration work?

Tim Mackinnon
Yes that's a good solution, however I'm really surprised that with the plethora of dates, durations, timespans (we are well served with a very rich time and date domain) that this isn't already in the image?

It seems very surprising. In fact the group I was working with (other language programmers) kept looking and looking for something as they felt certain they had overlooked it given all those promising classes.

I'm curious why it's not in there? And would we also expect to find its equivalent on a timespan (maybe delegating back to this date method? This assumes that timespan can be fixed as it loses precision unexpectedly).

Thanks for the reply.

Tim



Sent from my iPhone

> On 21 Jul 2017, at 06:41, K K Subbu <[hidden email]> wrote:
>
> Date>>ageOn: aDate
> " assert: (self <= aDate)
> | age |
>
> age = aDate year - self year + 1.
> aDate monthIndex < self monthIndex ifTrue: [ ^age - 1 ].
> (aDate monthIndex = self monthIndex and: [aDate dayOfMonth < self dayOfMonth]) ifTrue: [ ^age - 1 ].
> ^age
>
> HTH .. Subbu
>
>> On Friday 21 July 2017 05:28 AM, Tim Mackinnon wrote:
>> Hi - I just ran a great MobProgramming session with Smalltalk for the XProLo group - and there was lots of great feedback and questions, however one of them really got me thinking…
>> We did a little exercise to create a Person class with name, dob - and then we TDD’d an age method… which seems simple on the surface but it gets to an interesting point - what about leap years? How old is someone on those years?
>> I thought that our plethora of Date/Duration classes might handle this - but I couldn’t spot something obvious and was wondering if someone had a neat answer.
>> Essentially if you try:
>> age
>> ^Date today - self dob
>> You get a Duration,
>> But there isn’t :
>> ^(Date today - self dob) asYears
>> There is is asDay
>> ^(Date today - self dob) asDays
>> But then can you really
>> ^(Date today - self dob) asDays / 365) truncated
>> But what about leap years… so
>> ^(Date today - self dob) asDays / 365.25) truncated
>> It all feels a bit inelegant and I suspect there is a better Smalltalk way that is eluding me? Any suggestions?
>> Tim
>
>


Reply | Threaded
Open this post in threaded view
|

Re: How to calculate someone's age elegantly? Does Duration work?

K K Subbu
I suppose no one needed it that badly ;-). Age is the difference in
years except when the given date's julian is less than self's julian
when it is less by 1, so the code can be simplified to:

^aDate year - self year -
  (aDate dayOfYear < self dayOfYear) ifTrue: [ 1 ] ifFalse: [ 0 ])

BTW, the code has an off-by-one error. +1 should be dropped in first age
assignment.

Regards .. Subbu

On Friday 21 July 2017 12:55 PM, Tim Mackinnon wrote:

> Yes that's a good solution, however I'm really surprised that with the plethora of dates, durations, timespans (we are well served with a very rich time and date domain) that this isn't already in the image?
>
> It seems very surprising. In fact the group I was working with (other language programmers) kept looking and looking for something as they felt certain they had overlooked it given all those promising classes.
>
> I'm curious why it's not in there? And would we also expect to find its equivalent on a timespan (maybe delegating back to this date method? This assumes that timespan can be fixed as it loses precision unexpectedly).
>
> Thanks for the reply.
>
> Tim
>
>
>
> Sent from my iPhone
>
>> On 21 Jul 2017, at 06:41, K K Subbu <[hidden email]> wrote:
>>
>> Date>>ageOn: aDate
>> " assert: (self <= aDate)
>> | age |
>>
>> age = aDate year - self year + 1.
>> aDate monthIndex < self monthIndex ifTrue: [ ^age - 1 ].
>> (aDate monthIndex = self monthIndex and: [aDate dayOfMonth < self dayOfMonth]) ifTrue: [ ^age - 1 ].
>> ^age
>>
>> HTH .. Subbu
>>
>>> On Friday 21 July 2017 05:28 AM, Tim Mackinnon wrote:
>>> Hi - I just ran a great MobProgramming session with Smalltalk for the XProLo group - and there was lots of great feedback and questions, however one of them really got me thinking…
>>> We did a little exercise to create a Person class with name, dob - and then we TDD’d an age method… which seems simple on the surface but it gets to an interesting point - what about leap years? How old is someone on those years?
>>> I thought that our plethora of Date/Duration classes might handle this - but I couldn’t spot something obvious and was wondering if someone had a neat answer.
>>> Essentially if you try:
>>> age
>>> ^Date today - self dob
>>> You get a Duration,
>>> But there isn’t :
>>> ^(Date today - self dob) asYears
>>> There is is asDay
>>> ^(Date today - self dob) asDays
>>> But then can you really
>>> ^(Date today - self dob) asDays / 365) truncated
>>> But what about leap years… so
>>> ^(Date today - self dob) asDays / 365.25) truncated
>>> It all feels a bit inelegant and I suspect there is a better Smalltalk way that is eluding me? Any suggestions?
>>> Tim
>>
>>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: How to calculate someone's age elegantly? Does Duration work?

Tim Mackinnon
Actually that simplification doesn’t work - someone born on 1/Mar/2000 should be 11 on 1/Mar/2011 and this answers 10 (the previous version did work).

This does make me think its tricky enough to put this in the core - I may submit it along with the unit tests I borrowed from Stack Overflow (the shame)…

Its a good problem though. Thanks for discussing it with me.

Tim

On 21 Jul 2017, at 10:09, K K Subbu <[hidden email]> wrote:

^aDate year - self year -
(aDate dayOfYear < self dayOfYear) ifTrue: [ 1 ] ifFalse: [ 0 ])

Reply | Threaded
Open this post in threaded view
|

Re: How to calculate someone's age elegantly? Does Duration work?

K K Subbu
On Friday 21 July 2017 03:01 PM, Tim Mackinnon wrote:
> Actually that simplification doesn’t work - someone born on 1/Mar/2000
> should be 11 on 1/Mar/2011 and this answers 10 (the previous version did
> work).

You're right. The simplification does not take into account leap days.
Mea culpa. Original code (dropping +1) is readable and simple.

Regards .. Subbu

> This does make me think its tricky enough to put this in the core - I
> may submit it along with the unit tests I borrowed from Stack Overflow
> (the shame)…
>
> Its a good problem though. Thanks for discussing it with me.
>
> Tim
>
>> On 21 Jul 2017, at 10:09, K K Subbu <[hidden email]
>> <mailto:[hidden email]>> wrote:
>>
>> ^aDate year - self year -
>> (aDate dayOfYear < self dayOfYear) ifTrue: [ 1 ] ifFalse: [ 0 ])
>


Reply | Threaded
Open this post in threaded view
|

Re: How to calculate someone's age elegantly? Does Duration work?

Esteban A. Maringolo
In reply to this post by K K Subbu
Tim,

You might consider a full-fledged framework for it like Chalten:
https://github.com/ba-st/chalten

I don't know how it handles timezones, because the age calculation
might get trickier if you consider also the time of birth and you're
querying it from a different timezone ;-)

Regards!

Esteban A. Maringolo


2017-07-21 6:09 GMT-03:00 K K Subbu <[hidden email]>:

> I suppose no one needed it that badly ;-). Age is the difference in years
> except when the given date's julian is less than self's julian when it is
> less by 1, so the code can be simplified to:
>
> ^aDate year - self year -
>  (aDate dayOfYear < self dayOfYear) ifTrue: [ 1 ] ifFalse: [ 0 ])
>
> BTW, the code has an off-by-one error. +1 should be dropped in first age
> assignment.
>
> Regards .. Subbu
>
>
> On Friday 21 July 2017 12:55 PM, Tim Mackinnon wrote:
>>
>> Yes that's a good solution, however I'm really surprised that with the
>> plethora of dates, durations, timespans (we are well served with a very rich
>> time and date domain) that this isn't already in the image?
>>
>> It seems very surprising. In fact the group I was working with (other
>> language programmers) kept looking and looking for something as they felt
>> certain they had overlooked it given all those promising classes.
>>
>> I'm curious why it's not in there? And would we also expect to find its
>> equivalent on a timespan (maybe delegating back to this date method? This
>> assumes that timespan can be fixed as it loses precision unexpectedly).
>>
>> Thanks for the reply.
>>
>> Tim
>>
>>
>>
>> Sent from my iPhone
>>
>>> On 21 Jul 2017, at 06:41, K K Subbu <[hidden email]> wrote:
>>>
>>> Date>>ageOn: aDate
>>> " assert: (self <= aDate)
>>> | age |
>>>
>>> age = aDate year - self year + 1.
>>> aDate monthIndex < self monthIndex ifTrue: [ ^age - 1 ].
>>> (aDate monthIndex = self monthIndex and: [aDate dayOfMonth < self
>>> dayOfMonth]) ifTrue: [ ^age - 1 ].
>>> ^age
>>>
>>> HTH .. Subbu
>>>
>>>> On Friday 21 July 2017 05:28 AM, Tim Mackinnon wrote:
>>>> Hi - I just ran a great MobProgramming session with Smalltalk for the
>>>> XProLo group - and there was lots of great feedback and questions, however
>>>> one of them really got me thinking…
>>>> We did a little exercise to create a Person class with name, dob - and
>>>> then we TDD’d an age method… which seems simple on the surface but it gets
>>>> to an interesting point - what about leap years? How old is someone on those
>>>> years?
>>>> I thought that our plethora of Date/Duration classes might handle this -
>>>> but I couldn’t spot something obvious and was wondering if someone had a
>>>> neat answer.
>>>> Essentially if you try:
>>>> age
>>>> ^Date today - self dob
>>>> You get a Duration,
>>>> But there isn’t :
>>>> ^(Date today - self dob) asYears
>>>> There is is asDay
>>>> ^(Date today - self dob) asDays
>>>> But then can you really
>>>> ^(Date today - self dob) asDays / 365) truncated
>>>> But what about leap years… so
>>>> ^(Date today - self dob) asDays / 365.25) truncated
>>>> It all feels a bit inelegant and I suspect there is a better Smalltalk
>>>> way that is eluding me? Any suggestions?
>>>> Tim
>>>
>>>
>>>
>>
>>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: How to calculate someone's age elegantly? Does Duration work?

Tim Mackinnon
I hadn’t heard of that library - looks like one to keep in the back of my mind for more serious date related work.

I do think that age or ageOn: should be in the standard core particularly when we have so many date and duration related classes - but I’m not sure what the feeling is about adding methods. Certainly the group I saw learning smalltalk were very surprised it wasn’t there particularly when they saw the rich models we do have.

I am also wondering if the issue with Timespan is concerning - I was surprised that putting a start and end date left me something that didn’t answer my end date presumably down to rounding when it’s converted down to a duration (making me wonder if its better to keep a start and end date and calculate the duration on the fly).

Tim

> On 21 Jul 2017, at 13:58, Esteban A. Maringolo <[hidden email]> wrote:
>
> Tim,
>
> You might consider a full-fledged framework for it like Chalten:
> https://github.com/ba-st/chalten
>
> I don't know how it handles timezones, because the age calculation
> might get trickier if you consider also the time of birth and you're
> querying it from a different timezone ;-)
>
> Regards!
>
> Esteban A. Maringolo
>
>
> 2017-07-21 6:09 GMT-03:00 K K Subbu <[hidden email]>:
>> I suppose no one needed it that badly ;-). Age is the difference in years
>> except when the given date's julian is less than self's julian when it is
>> less by 1, so the code can be simplified to:
>>
>> ^aDate year - self year -
>> (aDate dayOfYear < self dayOfYear) ifTrue: [ 1 ] ifFalse: [ 0 ])
>>
>> BTW, the code has an off-by-one error. +1 should be dropped in first age
>> assignment.
>>
>> Regards .. Subbu
>>
>>
>> On Friday 21 July 2017 12:55 PM, Tim Mackinnon wrote:
>>>
>>> Yes that's a good solution, however I'm really surprised that with the
>>> plethora of dates, durations, timespans (we are well served with a very rich
>>> time and date domain) that this isn't already in the image?
>>>
>>> It seems very surprising. In fact the group I was working with (other
>>> language programmers) kept looking and looking for something as they felt
>>> certain they had overlooked it given all those promising classes.
>>>
>>> I'm curious why it's not in there? And would we also expect to find its
>>> equivalent on a timespan (maybe delegating back to this date method? This
>>> assumes that timespan can be fixed as it loses precision unexpectedly).
>>>
>>> Thanks for the reply.
>>>
>>> Tim
>>>
>>>
>>>
>>> Sent from my iPhone
>>>
>>>> On 21 Jul 2017, at 06:41, K K Subbu <[hidden email]> wrote:
>>>>
>>>> Date>>ageOn: aDate
>>>> " assert: (self <= aDate)
>>>> | age |
>>>>
>>>> age = aDate year - self year + 1.
>>>> aDate monthIndex < self monthIndex ifTrue: [ ^age - 1 ].
>>>> (aDate monthIndex = self monthIndex and: [aDate dayOfMonth < self
>>>> dayOfMonth]) ifTrue: [ ^age - 1 ].
>>>> ^age
>>>>
>>>> HTH .. Subbu
>>>>
>>>>> On Friday 21 July 2017 05:28 AM, Tim Mackinnon wrote:
>>>>> Hi - I just ran a great MobProgramming session with Smalltalk for the
>>>>> XProLo group - and there was lots of great feedback and questions, however
>>>>> one of them really got me thinking…
>>>>> We did a little exercise to create a Person class with name, dob - and
>>>>> then we TDD’d an age method… which seems simple on the surface but it gets
>>>>> to an interesting point - what about leap years? How old is someone on those
>>>>> years?
>>>>> I thought that our plethora of Date/Duration classes might handle this -
>>>>> but I couldn’t spot something obvious and was wondering if someone had a
>>>>> neat answer.
>>>>> Essentially if you try:
>>>>> age
>>>>> ^Date today - self dob
>>>>> You get a Duration,
>>>>> But there isn’t :
>>>>> ^(Date today - self dob) asYears
>>>>> There is is asDay
>>>>> ^(Date today - self dob) asDays
>>>>> But then can you really
>>>>> ^(Date today - self dob) asDays / 365) truncated
>>>>> But what about leap years… so
>>>>> ^(Date today - self dob) asDays / 365.25) truncated
>>>>> It all feels a bit inelegant and I suspect there is a better Smalltalk
>>>>> way that is eluding me? Any suggestions?
>>>>> Tim
>>>>
>>>>
>>>>
>>>
>>>
>>
>>
>


Reply | Threaded
Open this post in threaded view
|

Re: How to calculate someone's age elegantly? Does Duration work?

Esteban A. Maringolo
I remember this was discussed before in the mailing list, not in the
context of age calculation, but regarding the offset/duration vs
calendar based dates handling.

Pharo's core date classes are "incremental", which isn't suited for
calendar sensitive calculations. Java core class for those
calculations is the java.util.Calendar class which is "field" based.

See http://forum.world.st/Interesting-Date-Time-Thread-on-Squeak-Dev-tp4778652p4778970.html



Esteban A. Maringolo


2017-07-21 12:16 GMT-03:00 Tim Mackinnon <[hidden email]>:
> I hadn’t heard of that library - looks like one to keep in the back of my mind for more serious date related work.
>
> I do think that age or ageOn: should be in the standard core particularly when we have so many date and duration related classes - but I’m not sure what the feeling is about adding methods. Certainly the group I saw learning smalltalk were very surprised it wasn’t there particularly when they saw the rich models we do have.
>
> I am also wondering if the issue with Timespan is concerning - I was surprised that putting a start and end date left me something that didn’t answer my end date presumably down to rounding when it’s converted down to a duration (making me wonder if its better to keep a start and end date and calculate the duration on the fly).

>> On 21 Jul 2017, at 13:58, Esteban A. Maringolo <[hidden email]> wrote:
>> You might consider a full-fledged framework for it like Chalten:
>> https://github.com/ba-st/chalten

Reply | Threaded
Open this post in threaded view
|

Re: How to calculate someone's age elegantly? Does Duration work?

Paul DeBruicker
In reply to this post by Tim Mackinnon
Tim Mackinnon wrote
I am also wondering if the issue with Timespan is concerning - I was surprised that putting a start and end date left me something that didn’t answer my end date presumably down to rounding when it’s converted down to a duration (making me wonder if its better to keep a start and end date and calculate the duration on the fly).

Tim

The Timespans are half open intervals. (https://en.wikipedia.org/wiki/Interval_(mathematics))

Friday July 21st ends at 11:59:59.99999999999... etc etc etc ...9999PM and the 22nd starts at 12:00AM


If Timespans were closed intervals like you expect then we'd be out of whack with our corner of the universe.  That extra clock tick adds complexity.  

But I add a method to my image called #displayEnd because I also want them to print 3PM-4PM and not 3PM-3:59:59.999999999PM and use that in my print statements and rendering for Seaside.  

displayEnd
        ^ start + duration




Reply | Threaded
Open this post in threaded view
|

Re: How to calculate someone's age elegantly? Does Duration work?

Tim Mackinnon
In reply to this post by K K Subbu
As an aside - there is another way of doing it - but I’m not sure if its clearer (or more efficient):

^ ((aDate year * 10000 + (aDate monthIndex * 100) + aDate dayOfMonth
                - (self year * 10000 + (self monthIndex * 100) + self dayOfMonth)) / 10000) truncated


> On 21 Jul 2017, at 12:54, K K Subbu <[hidden email]> wrote:
>
> On Friday 21 July 2017 03:01 PM, Tim Mackinnon wrote:
>> Actually that simplification doesn’t work - someone born on 1/Mar/2000 should be 11 on 1/Mar/2011 and this answers 10 (the previous version did work).
>
> You're right. The simplification does not take into account leap days. Mea culpa. Original code (dropping +1) is readable and simple.
>
> Regards .. Subbu
>
>> This does make me think its tricky enough to put this in the core - I may submit it along with the unit tests I borrowed from Stack Overflow (the shame)…
>> Its a good problem though. Thanks for discussing it with me.
>> Tim
>>> On 21 Jul 2017, at 10:09, K K Subbu <[hidden email] <mailto:[hidden email]>> wrote:
>>>
>>> ^aDate year - self year -
>>> (aDate dayOfYear < self dayOfYear) ifTrue: [ 1 ] ifFalse: [ 0 ])
>
>


Reply | Threaded
Open this post in threaded view
|

Re: How to calculate someone's age elegantly? Does Duration work?

Tim Mackinnon
In reply to this post by Paul DeBruicker
Paul - this is very helpful, gosh you learn a lot from what seemed like simple question.

Your suggestion along with Subbu’s gives an easy workable solution - I also wonder if the method should be in the image along with the comment explaining half open intervals like you have. Do you think there is another name for that end method - displayEnd sounds like it actively displays - I wonder if boundedEnd or completeEnd or finiteEnd might be correct alternatives (or is displayEnd a decent convention that everyone understands?)

I really have to learn how to submit pull requests (although it seems rather complicated at the moment while the full git integration process is being sorted out).

Thanks everyone

Tim

> On 21 Jul 2017, at 16:40, Paul DeBruicker <[hidden email]> wrote:
>
> Tim Mackinnon wrote
>> I am also wondering if the issue with Timespan is concerning - I was
>> surprised that putting a start and end date left me something that didn’t
>> answer my end date presumably down to rounding when it’s converted down to
>> a duration (making me wonder if its better to keep a start and end date
>> and calculate the duration on the fly).
>>
>> Tim
>
>
> The Timespans are half open intervals.
> (https://en.wikipedia.org/wiki/Interval_(mathematics))
>
> Friday July 21st ends at 11:59:59.99999999999... etc etc etc ...9999PM and
> the 22nd starts at 12:00AM
>
>
> If Timespans were closed intervals like you expect then we'd be out of whack
> with our corner of the universe.  That extra clock tick adds complexity.  
>
> But I add a method to my image called #displayEnd because I also want them
> to print 3PM-4PM and not 3PM-3:59:59.999999999PM and use that in my print
> statements and rendering for Seaside.  
>
> displayEnd
> ^ start + duration
>
>
>
>
>
>
>
>
> --
> View this message in context: http://forum.world.st/How-to-calculate-someone-s-age-elegantly-Does-Duration-work-tp4955990p4956114.html
> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
>


Reply | Threaded
Open this post in threaded view
|

Re: How to calculate someone's age elegantly? Does Duration work?

Julián Maestri-2
Using https://github.com/ba-st/Chalten the solution was something like this:

Person>>ageOn: aDate
  | difference |
  difference := (aDate year distanceFrom: self dateOfBirth year).
  ^(aDate dayOfMonth < self dateOfBirth dayOfMonth)
    ifTrue: [difference - TimeUnits year unitaryMeasurement]
    ifFalse: [difference]
Test for that
testAge
| john |
john := Person namedFirst: 'John' last: 'Doe' born: March fourteenth , 1963.
self
assert: (john ageOn: March thirteenth , 2013) equals: (TimeUnits year with: 49);
assert: (john ageOn: March fourteenth , 2013) equals: (TimeUnits year with: 50);
assert: (john ageOn: March fifteenth , 2013) equals: (TimeUnits year with: 50) 

On 21 July 2017 at 14:25, Tim Mackinnon <[hidden email]> wrote:
Paul - this is very helpful, gosh you learn a lot from what seemed like simple question.

Your suggestion along with Subbu’s gives an easy workable solution - I also wonder if the method should be in the image along with the comment explaining half open intervals like you have. Do you think there is another name for that end method - displayEnd sounds like it actively displays - I wonder if boundedEnd or completeEnd or finiteEnd might be correct alternatives (or is displayEnd a decent convention that everyone understands?)

I really have to learn how to submit pull requests (although it seems rather complicated at the moment while the full git integration process is being sorted out).

Thanks everyone

Tim

> On 21 Jul 2017, at 16:40, Paul DeBruicker <[hidden email]> wrote:
>
> Tim Mackinnon wrote
>> I am also wondering if the issue with Timespan is concerning - I was
>> surprised that putting a start and end date left me something that didn’t
>> answer my end date presumably down to rounding when it’s converted down to
>> a duration (making me wonder if its better to keep a start and end date
>> and calculate the duration on the fly).
>>
>> Tim
>
>
> The Timespans are half open intervals.
> (https://en.wikipedia.org/wiki/Interval_(mathematics))
>
> Friday July 21st ends at 11:59:59.99999999999... etc etc etc ...9999PM and
> the 22nd starts at 12:00AM
>
>
> If Timespans were closed intervals like you expect then we'd be out of whack
> with our corner of the universe.  That extra clock tick adds complexity.
>
> But I add a method to my image called #displayEnd because I also want them
> to print 3PM-4PM and not 3PM-3:59:59.999999999PM and use that in my print
> statements and rendering for Seaside.
>
> displayEnd
>       ^ start + duration
>
>
>
>
>
>
>
>
> --
> View this message in context: http://forum.world.st/How-to-calculate-someone-s-age-elegantly-Does-Duration-work-tp4955990p4956114.html
> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
>



Reply | Threaded
Open this post in threaded view
|

Re: How to calculate someone's age elegantly? Does Duration work?

Peter Kenny

Julián

 

I don’t know Chalten, but I wonder whether your definition of Person>>ageOn: will work correctly. Could I suggest you add two extra assertions to your test:

 

assert: (john ageOn: February fifteenth , 2013) equals: (TimeUnits year with: 49);
assert: (john ageOn: April first , 2013) equals: (TimeUnits year with: 50);

 

Clearly these should be true, but I think they will not be – unless Date>>dayOfMonth works in a very counter-intuitive way.

 

HTH

 

Peter Kenny

 

 

From: Pharo-users [mailto:[hidden email]] On Behalf Of Julián Maestri
Sent: 27 July 2017 18:58
To: Any question about pharo is welcome <[hidden email]>
Subject: Re: [Pharo-users] How to calculate someone's age elegantly? Does Duration work?

 

Using https://github.com/ba-st/Chalten the solution was something like this:

 

Person>>ageOn: aDate
  | difference |
  difference := (aDate year distanceFrom: self dateOfBirth year).
  ^(aDate dayOfMonth < self dateOfBirth dayOfMonth)
    ifTrue: [difference - TimeUnits year unitaryMeasurement]
    ifFalse: [difference]

Test for that

testAge
| john |
john := Person namedFirst: 'John' last: 'Doe' born: March fourteenth , 1963.
self
assert: (john ageOn: March thirteenth , 2013) equals: (TimeUnits year with: 49);
assert: (john ageOn: March fourteenth , 2013) equals: (TimeUnits year with: 50);
assert: (john ageOn: March fifteenth , 2013) equals: (TimeUnits year with: 50) 

 

On 21 July 2017 at 14:25, Tim Mackinnon <[hidden email]> wrote:

Paul - this is very helpful, gosh you learn a lot from what seemed like simple question.

Your suggestion along with Subbu’s gives an easy workable solution - I also wonder if the method should be in the image along with the comment explaining half open intervals like you have. Do you think there is another name for that end method - displayEnd sounds like it actively displays - I wonder if boundedEnd or completeEnd or finiteEnd might be correct alternatives (or is displayEnd a decent convention that everyone understands?)

I really have to learn how to submit pull requests (although it seems rather complicated at the moment while the full git integration process is being sorted out).

Thanks everyone

Tim


> On 21 Jul 2017, at 16:40, Paul DeBruicker <[hidden email]> wrote:
>
> Tim Mackinnon wrote
>> I am also wondering if the issue with Timespan is concerning - I was
>> surprised that putting a start and end date left me something that didn’t
>> answer my end date presumably down to rounding when it’s converted down to
>> a duration (making me wonder if its better to keep a start and end date
>> and calculate the duration on the fly).
>>
>> Tim
>
>
> The Timespans are half open intervals.
> (https://en.wikipedia.org/wiki/Interval_(mathematics))
>
> Friday July 21st ends at 11:59:59.99999999999... etc etc etc ...9999PM and
> the 22nd starts at 12:00AM
>
>
> If Timespans were closed intervals like you expect then we'd be out of whack
> with our corner of the universe.  That extra clock tick adds complexity.
>
> But I add a method to my image called #displayEnd because I also want them
> to print 3PM-4PM and not 3PM-3:59:59.999999999PM and use that in my print
> statements and rendering for Seaside.
>
> displayEnd
>       ^ start + duration
>
>
>
>
>
>
>
>
> --
> View this message in context: http://forum.world.st/How-to-calculate-someone-s-age-elegantly-Does-Duration-work-tp4955990p4956114.html
> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
>

 

Reply | Threaded
Open this post in threaded view
|

Re: How to calculate someone's age elegantly? Does Duration work?

Julián Maestri-2
It still works, probably because dayOfMonth is not what you expected at first glance.

For a date, you have 3 accessors, and i think you were expecting #dayNumber

(January third, 1990) day. "Wednesday".
(January third, 1990) dayOfMonth. "January 3"
(January third, 1990) dayNumber. "3"



On 27 July 2017 at 16:43, PBKResearch <[hidden email]> wrote:

Julián

 

I don’t know Chalten, but I wonder whether your definition of Person>>ageOn: will work correctly. Could I suggest you add two extra assertions to your test:

 

assert: (john ageOn: February fifteenth , 2013) equals: (TimeUnits year with: 49);
assert: (john ageOn: April first , 2013) equals: (TimeUnits year with: 50);

 

Clearly these should be true, but I think they will not be – unless Date>>dayOfMonth works in a very counter-intuitive way.

 

HTH

 

Peter Kenny

 

 

From: Pharo-users [mailto:[hidden email]] On Behalf Of Julián Maestri
Sent: 27 July 2017 18:58
To: Any question about pharo is welcome <[hidden email]>
Subject: Re: [Pharo-users] How to calculate someone's age elegantly? Does Duration work?

 

Using https://github.com/ba-st/Chalten the solution was something like this:

 

Person>>ageOn: aDate
  | difference |
  difference := (aDate year distanceFrom: self dateOfBirth year).
  ^(aDate dayOfMonth < self dateOfBirth dayOfMonth)
    ifTrue: [difference - TimeUnits year unitaryMeasurement]
    ifFalse: [difference]

Test for that

testAge
| john |
john := Person namedFirst: 'John' last: 'Doe' born: March fourteenth , 1963.
self
assert: (john ageOn: March thirteenth , 2013) equals: (TimeUnits year with: 49);
assert: (john ageOn: March fourteenth , 2013) equals: (TimeUnits year with: 50);
assert: (john ageOn: March fifteenth , 2013) equals: (TimeUnits year with: 50) 

 

On 21 July 2017 at 14:25, Tim Mackinnon <[hidden email]> wrote:

Paul - this is very helpful, gosh you learn a lot from what seemed like simple question.

Your suggestion along with Subbu’s gives an easy workable solution - I also wonder if the method should be in the image along with the comment explaining half open intervals like you have. Do you think there is another name for that end method - displayEnd sounds like it actively displays - I wonder if boundedEnd or completeEnd or finiteEnd might be correct alternatives (or is displayEnd a decent convention that everyone understands?)

I really have to learn how to submit pull requests (although it seems rather complicated at the moment while the full git integration process is being sorted out).

Thanks everyone

Tim


> On 21 Jul 2017, at 16:40, Paul DeBruicker <[hidden email]> wrote:
>
> Tim Mackinnon wrote
>> I am also wondering if the issue with Timespan is concerning - I was
>> surprised that putting a start and end date left me something that didn’t
>> answer my end date presumably down to rounding when it’s converted down to
>> a duration (making me wonder if its better to keep a start and end date
>> and calculate the duration on the fly).
>>
>> Tim
>
>
> The Timespans are half open intervals.
> (https://en.wikipedia.org/wiki/Interval_(mathematics))
>
> Friday July 21st ends at 11:59:59.99999999999... etc etc etc ...9999PM and
> the 22nd starts at 12:00AM
>
>
> If Timespans were closed intervals like you expect then we'd be out of whack
> with our corner of the universe.  That extra clock tick adds complexity.
>
> But I add a method to my image called #displayEnd because I also want them
> to print 3PM-4PM and not 3PM-3:59:59.999999999PM and use that in my print
> statements and rendering for Seaside.
>
> displayEnd
>       ^ start + duration
>
>
>
>
>
>
>
>
> --
> View this message in context: http://forum.world.st/How-to-calculate-someone-s-age-elegantly-Does-Duration-work-tp4955990p4956114.html
> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
>

 


Reply | Threaded
Open this post in threaded view
|

Re: How to calculate someone's age elegantly? Does Duration work?

Peter Kenny

Julián

 

Sorry, I should have checked my facts before sounding off. I think defining dayOfMonth in the way you show is very counter-intuitive, but that is the definition and I should have checked.

 

From: Pharo-users [mailto:[hidden email]] On Behalf Of Julián Maestri
Sent: 28 July 2017 17:40
To: Any question about pharo is welcome <[hidden email]>
Subject: Re: [Pharo-users] How to calculate someone's age elegantly? Does Duration work?

 

It still works, probably because dayOfMonth is not what you expected at first glance.

 

For a date, you have 3 accessors, and i think you were expecting #dayNumber

 

(January third, 1990) day. "Wednesday".

(January third, 1990) dayOfMonth. "January 3"

(January third, 1990) dayNumber. "3"

 

 

 

On 27 July 2017 at 16:43, PBKResearch <[hidden email]> wrote:

Julián

 

I don’t know Chalten, but I wonder whether your definition of Person>>ageOn: will work correctly. Could I suggest you add two extra assertions to your test:

 

assert: (john ageOn: February fifteenth , 2013) equals: (TimeUnits year with: 49);
assert: (john ageOn: April first , 2013) equals: (TimeUnits year with: 50);

 

Clearly these should be true, but I think they will not be – unless Date>>dayOfMonth works in a very counter-intuitive way.

 

HTH

 

Peter Kenny

 

 

From: Pharo-users [mailto:[hidden email]] On Behalf Of Julián Maestri
Sent: 27 July 2017 18:58
To: Any question about pharo is welcome <[hidden email]>
Subject: Re: [Pharo-users] How to calculate someone's age elegantly? Does Duration work?

 

Using https://github.com/ba-st/Chalten the solution was something like this:

 

Person>>ageOn: aDate
  | difference |
  difference := (aDate year distanceFrom: self dateOfBirth year).
  ^(aDate dayOfMonth < self dateOfBirth dayOfMonth)
    ifTrue: [difference - TimeUnits year unitaryMeasurement]
    ifFalse: [difference]

Test for that

testAge
| john |
john := Person namedFirst: 'John' last: 'Doe' born: March fourteenth , 1963.
self
assert: (john ageOn: March thirteenth , 2013) equals: (TimeUnits year with: 49);
assert: (john ageOn: March fourteenth , 2013) equals: (TimeUnits year with: 50);
assert: (john ageOn: March fifteenth , 2013) equals: (TimeUnits year with: 50) 

 

On 21 July 2017 at 14:25, Tim Mackinnon <[hidden email]> wrote:

Paul - this is very helpful, gosh you learn a lot from what seemed like simple question.

Your suggestion along with Subbu’s gives an easy workable solution - I also wonder if the method should be in the image along with the comment explaining half open intervals like you have. Do you think there is another name for that end method - displayEnd sounds like it actively displays - I wonder if boundedEnd or completeEnd or finiteEnd might be correct alternatives (or is displayEnd a decent convention that everyone understands?)

I really have to learn how to submit pull requests (although it seems rather complicated at the moment while the full git integration process is being sorted out).

Thanks everyone

Tim


> On 21 Jul 2017, at 16:40, Paul DeBruicker <[hidden email]> wrote:
>
> Tim Mackinnon wrote
>> I am also wondering if the issue with Timespan is concerning - I was
>> surprised that putting a start and end date left me something that didn’t
>> answer my end date presumably down to rounding when it’s converted down to
>> a duration (making me wonder if its better to keep a start and end date
>> and calculate the duration on the fly).
>>
>> Tim
>
>
> The Timespans are half open intervals.
> (https://en.wikipedia.org/wiki/Interval_(mathematics))
>
> Friday July 21st ends at 11:59:59.99999999999... etc etc etc ...9999PM and
> the 22nd starts at 12:00AM
>
>
> If Timespans were closed intervals like you expect then we'd be out of whack
> with our corner of the universe.  That extra clock tick adds complexity.
>
> But I add a method to my image called #displayEnd because I also want them
> to print 3PM-4PM and not 3PM-3:59:59.999999999PM and use that in my print
> statements and rendering for Seaside.
>
> displayEnd
>       ^ start + duration
>
>
>
>
>
>
>
>
> --
> View this message in context: http://forum.world.st/How-to-calculate-someone-s-age-elegantly-Does-Duration-work-tp4955990p4956114.html
> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
>

 

 

Reply | Threaded
Open this post in threaded view
|

Re: How to calculate someone's age elegantly? Does Duration work?

Tim Mackinnon
This continues to be a fascination little problem with many angles and solutions.

Tim

Sent from my iPhone

On 28 Jul 2017, at 21:31, PBKResearch <[hidden email]> wrote:

Julián

 

Sorry, I should have checked my facts before sounding off. I think defining dayOfMonth in the way you show is very counter-intuitive, but that is the definition and I should have checked.

 

From: Pharo-users [[hidden email]] On Behalf Of Julián Maestri
Sent: 28 July 2017 17:40
To: Any question about pharo is welcome <[hidden email]>
Subject: Re: [Pharo-users] How to calculate someone's age elegantly? Does Duration work?

 

It still works, probably because dayOfMonth is not what you expected at first glance.

 

For a date, you have 3 accessors, and i think you were expecting #dayNumber

 

(January third, 1990) day. "Wednesday".

(January third, 1990) dayOfMonth. "January 3"

(January third, 1990) dayNumber. "3"

 

 

 

On 27 July 2017 at 16:43, PBKResearch <[hidden email]> wrote:

Julián

 

I don’t know Chalten, but I wonder whether your definition of Person>>ageOn: will work correctly. Could I suggest you add two extra assertions to your test:

 

assert: (john ageOn: February fifteenth , 2013) equals: (TimeUnits year with: 49);
assert: (john ageOn: April first , 2013) equals: (TimeUnits year with: 50);

 

Clearly these should be true, but I think they will not be – unless Date>>dayOfMonth works in a very counter-intuitive way.

 

HTH

 

Peter Kenny

 

 

From: Pharo-users [mailto:[hidden email]] On Behalf Of Julián Maestri
Sent: 27 July 2017 18:58
To: Any question about pharo is welcome <[hidden email]>
Subject: Re: [Pharo-users] How to calculate someone's age elegantly? Does Duration work?

 

Using https://github.com/ba-st/Chalten the solution was something like this:

 

Person>>ageOn: aDate
  | difference |
  difference := (aDate year distanceFrom: self dateOfBirth year).
  ^(aDate dayOfMonth < self dateOfBirth dayOfMonth)
    ifTrue: [difference - TimeUnits year unitaryMeasurement]
    ifFalse: [difference]

Test for that

testAge
| john |
john := Person namedFirst: 'John' last: 'Doe' born: March fourteenth , 1963.
self
assert: (john ageOn: March thirteenth , 2013) equals: (TimeUnits year with: 49);
assert: (john ageOn: March fourteenth , 2013) equals: (TimeUnits year with: 50);
assert: (john ageOn: March fifteenth , 2013) equals: (TimeUnits year with: 50) 

 

On 21 July 2017 at 14:25, Tim Mackinnon <[hidden email]> wrote:

Paul - this is very helpful, gosh you learn a lot from what seemed like simple question.

Your suggestion along with Subbu’s gives an easy workable solution - I also wonder if the method should be in the image along with the comment explaining half open intervals like you have. Do you think there is another name for that end method - displayEnd sounds like it actively displays - I wonder if boundedEnd or completeEnd or finiteEnd might be correct alternatives (or is displayEnd a decent convention that everyone understands?)

I really have to learn how to submit pull requests (although it seems rather complicated at the moment while the full git integration process is being sorted out).

Thanks everyone

Tim


> On 21 Jul 2017, at 16:40, Paul DeBruicker <[hidden email]> wrote:
>
> Tim Mackinnon wrote
>> I am also wondering if the issue with Timespan is concerning - I was
>> surprised that putting a start and end date left me something that didn’t
>> answer my end date presumably down to rounding when it’s converted down to
>> a duration (making me wonder if its better to keep a start and end date
>> and calculate the duration on the fly).
>>
>> Tim
>
>
> The Timespans are half open intervals.
> (https://en.wikipedia.org/wiki/Interval_(mathematics))
>
> Friday July 21st ends at 11:59:59.99999999999... etc etc etc ...9999PM and
> the 22nd starts at 12:00AM
>
>
> If Timespans were closed intervals like you expect then we'd be out of whack
> with our corner of the universe.  That extra clock tick adds complexity.
>
> But I add a method to my image called #displayEnd because I also want them
> to print 3PM-4PM and not 3PM-3:59:59.999999999PM and use that in my print
> statements and rendering for Seaside.
>
> displayEnd
>       ^ start + duration
>
>
>
>
>
>
>
>
> --
> View this message in context: http://forum.world.st/How-to-calculate-someone-s-age-elegantly-Does-Duration-work-tp4955990p4956114.html
> Sent from the Pharo Smalltalk Users mailing list archive at Nabble.com.
>