Thread overview | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 15, 2017 Convert duration to years? | ||||
---|---|---|---|---|
| ||||
Hi, I would simply like to get someone's age, but I am a little lost with time and date functions. I can already get the duration, but after reading the documentation it's unclear to me how to convert that into years. See following code: import std.stdio; void getAge(int yyyy, int mm, int dd) { import std.datetime; SysTime t1 = SysTime(Date(yyyy, mm, dd)); SysTime t2 = Clock.currTime(); writeln(t2 - t1); } int main() { try getAge(1980, 1, 1); catch(Exception e) { writefln("%s.\n(%s, line %s)", e.msg, e.file, e.line); } } Notice getAge should return ubyte instead of void, only I haven't been able to find how to do it. Any suggestion would be welcome. Thanks in advance. |
January 15, 2017 Re: Convert duration to years? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nestor | On Sunday, 15 January 2017 at 03:43:32 UTC, Nestor wrote:
> Hi,
>
> I would simply like to get someone's age, but I am a little lost with time and date functions. I can already get the duration, but after reading the documentation it's unclear to me how to convert that into years. See following code:
>
> import std.stdio;
>
> void getAge(int yyyy, int mm, int dd) {
> import std.datetime;
> SysTime t1 = SysTime(Date(yyyy, mm, dd));
> SysTime t2 = Clock.currTime();
> writeln(t2 - t1);
> }
>
> int main() {
> try
> getAge(1980, 1, 1);
> catch(Exception e) {
> writefln("%s.\n(%s, line %s)", e.msg, e.file, e.line);
> }
> }
>
> Notice getAge should return ubyte instead of void, only I haven't been able to find how to do it. Any suggestion would be welcome.
>
> Thanks in advance.
Does this do what you want?
import std.stdio;
uint getAge(int yyyy, int mm, int dd) {
import std.datetime;
SysTime t1 = SysTime(Date(yyyy, mm, dd));
SysTime t2 = Clock.currTime();
return( (t2.year - t1.year));
}
void main() {
auto age = getAge(1980, 1, 1);
writefln("age is %s", age);
}
|
January 15, 2017 Re: Convert duration to years? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dave Chapman | On Sunday, 15 January 2017 at 06:23:56 UTC, Dave Chapman wrote:
> Does this do what you want?
> import std.stdio;
>
> uint getAge(int yyyy, int mm, int dd) {
> import std.datetime;
> SysTime t1 = SysTime(Date(yyyy, mm, dd));
> SysTime t2 = Clock.currTime();
> return( (t2.year - t1.year));
> }
>
> void main() {
> auto age = getAge(1980, 1, 1);
> writefln("age is %s", age);
> }
It seems to work, but not very accurately, see variation:
import std.stdio;
uint getAge() {
import std.datetime;
SysTime t1 = SysTime(Date(2000, 12, 31));
SysTime t2 = SysTime(Date(2001, 1, 1));
return((t2.year - t1.year));
}
void main() {
auto age = getAge();
writefln("age is %s", age);
}
I eventually came up with this, but it seems an ugly hack:
import std.stdio;
uint getAge(int yyyy, ubyte mm, ubyte dd) {
ubyte correction;
import std.datetime;
SysTime t = Clock.currTime();
if (t.month < mm) correction = 1;
else if (t.month == mm) correction = (t.day < dd) ? 1 : 0;
else correction = 0;
return (t.year - yyyy - correction);
}
void main() {
try
writefln("Edad: %s años.", getAge(1958, 1, 21));
catch(Exception e) {
writefln("%s.\n(%s, line %s)", e.msg, e.file, e.line);
}
}
Isn't there a built-in function to do this?
|
January 15, 2017 Re: Convert duration to years? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nestor | On 15/01/2017 4:43 PM, Nestor wrote: > Hi, > > I would simply like to get someone's age, but I am a little lost with > time and date functions. I can already get the duration, but after > reading the documentation it's unclear to me how to convert that into > years. See following code: > > import std.stdio; > > void getAge(int yyyy, int mm, int dd) { > import std.datetime; > SysTime t1 = SysTime(Date(yyyy, mm, dd)); > SysTime t2 = Clock.currTime(); > writeln(t2 - t1); > } > > int main() { > try > getAge(1980, 1, 1); > catch(Exception e) { > writefln("%s.\n(%s, line %s)", e.msg, e.file, e.line); > } > } > > Notice getAge should return ubyte instead of void, only I haven't been > able to find how to do it. Any suggestion would be welcome. > > Thanks in advance. So I had a go at this and found I struggled looking at "magic" functions and methods. Turns out there is a much simpler answer. int getAge(int yyyy, int mm, int dd) { import std.datetime; auto t1 = cast(DateTime)SysTime(Date(yyyy, mm, dd)); auto t2 = cast(DateTime)Clock.currTime(); int numYears; while(t2 > t1) { t1.add!"years"(1); numYears++; } return numYears; } |
January 15, 2017 Re: Convert duration to years? | ||||
---|---|---|---|---|
| ||||
Posted in reply to rikki cattermole | On Sunday, 15 January 2017 at 07:25:26 UTC, rikki cattermole wrote:
> So I had a go at this and found I struggled looking at "magic" functions and methods.
> Turns out there is a much simpler answer.
>
> int getAge(int yyyy, int mm, int dd) {
> import std.datetime;
> auto t1 = cast(DateTime)SysTime(Date(yyyy, mm, dd));
> auto t2 = cast(DateTime)Clock.currTime();
>
> int numYears;
> while(t2 > t1) {
> t1.add!"years"(1);
> numYears++;
> }
>
> return numYears;
> }
Well... correct me if I am wrong, but isn't t1.add!"years"(1) simply adding one year to t1?
|
January 15, 2017 Re: Convert duration to years? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nestor | I cleaned up the function a little, but it still feels like a hack: uint getAge(uint yyyy, uint mm, uint dd) { import std.datetime; SysTime t = Clock.currTime; ubyte correction = 0; if( (t.month < mm) || ( (t.month == mm) && (t.day < dd) ) ) correction += 1; return (t.year - yyyy - correction); } Isn't there anything better? |
January 15, 2017 Re: Convert duration to years? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nestor | On 15/01/2017 9:40 PM, Nestor wrote:
> I cleaned up the function a little, but it still feels like a hack:
>
> uint getAge(uint yyyy, uint mm, uint dd) {
> import std.datetime;
> SysTime t = Clock.currTime;
> ubyte correction = 0;
> if(
> (t.month < mm) ||
> ( (t.month == mm) && (t.day < dd) )
> ) correction += 1;
> return (t.year - yyyy - correction);
> }
>
> Isn't there anything better?
The problem with this is that it won't take into account leap years.
|
January 15, 2017 Re: Convert duration to years? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nestor | On Sunday, 15 January 2017 at 08:40:37 UTC, Nestor wrote:
> I cleaned up the function a little, but it still feels like a hack:
>
> uint getAge(uint yyyy, uint mm, uint dd) {
> import std.datetime;
> SysTime t = Clock.currTime;
> ubyte correction = 0;
> if(
> (t.month < mm) ||
> ( (t.month == mm) && (t.day < dd) )
> ) correction += 1;
> return (t.year - yyyy - correction);
> }
>
> Isn't there anything better?
It doesn't feel like a hack to me, because it's simple and correct code that comply with the common definition of a person's age. The only inaccuracy I can think of is about people born on February 29th...
|
January 15, 2017 Re: Convert duration to years? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nestor | On 01/15/2017 07:58 AM, Nestor wrote: > I eventually came up with this, but it seems an ugly hack: > > import std.stdio; > > uint getAge(int yyyy, ubyte mm, ubyte dd) { > ubyte correction; > import std.datetime; > SysTime t = Clock.currTime(); > if (t.month < mm) correction = 1; > else if (t.month == mm) correction = (t.day < dd) ? 1 : 0; > else correction = 0; > return (t.year - yyyy - correction); > } > > void main() { > try > writefln("Edad: %s años.", getAge(1958, 1, 21)); > catch(Exception e) { > writefln("%s.\n(%s, line %s)", e.msg, e.file, e.line); > } > } That's the better approach, I think. Years have variable lengths. Determining "age" in years works by comparing dates, not durations. I would write it like this, but as far as I see yours does the same thing: ---- int getAge(int yyyy, int mm, int dd) { import std.datetime; immutable SysTime now = Clock.currTime(); immutable int years = now.year - yyyy; return mm > now.month || mm == now.month && dd > now.day ? years - 1 // birthday hasn't come yet this year : years; // birthday has already been this year } void main() { import std.stdio; /* Day of writing: 2017-01-15 */ writeln(getAge(1980, 1, 1)); /* 37 */ writeln(getAge(1980, 1, 15)); /* 37 (birthday is today) */ writeln(getAge(1980, 1, 30)); /* 36 */ writeln(getAge(1980, 6, 1)); /* 36 */ } ---- > Isn't there a built-in function to do this? If there is, finding it in std.datetime would take me longer than writing it myself. |
January 15, 2017 Re: Convert duration to years? | ||||
---|---|---|---|---|
| ||||
Posted in reply to biozic | On Sunday, 15 January 2017 at 11:01:28 UTC, biozic wrote:
> On Sunday, 15 January 2017 at 08:40:37 UTC, Nestor wrote:
>> I cleaned up the function a little, but it still feels like a hack:
>>
>> uint getAge(uint yyyy, uint mm, uint dd) {
>> import std.datetime;
>> SysTime t = Clock.currTime;
>> ubyte correction = 0;
>> if(
>> (t.month < mm) ||
>> ( (t.month == mm) && (t.day < dd) )
>> ) correction += 1;
>> return (t.year - yyyy - correction);
>> }
>>
>> Isn't there anything better?
>
> It doesn't feel like a hack to me, because it's simple and correct code that comply with the common definition of a person's age. The only inaccuracy I can think of is about people born on February 29th...
I know. I thought about it as well, but it's not something you can deal with cleanly.
For example, take a baby born in february 29 of year 2000 (leap year). In february 28 of 2001 that baby was one day short to one year.
Family can make a concession and celebrate birthdays in february 28 of non-leap years, but march 1 is the actual day when the year of life completes. Which one to choose?
Another way to deal with this is modifying the function to take a parameter which allows to do a relaxed calculation in non-leap years if one so desires.
|
Copyright © 1999-2021 by the D Language Foundation