This week's book giveaways are in the Scala and Android forums.
We're giving away four copies each of Machine Learning Systems: Designs that scale and Xamarin in Action: Creating native cross-platform mobile apps and have the authors on-line!
See this thread and this one for details.
Win a copy of Machine Learning Systems: Designs that scale this week in the Scala forum
or Xamarin in Action: Creating native cross-platform mobile apps in the Android forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Date/Calendar without Year requirement  RSS feed

 
Rancher
Posts: 4686
7
Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've implemented a birthdate field for a person as

protected Date birth_date;

with proper SQL field defined as

birthdate date default NULL,


All works great, until the boss says that some people don't want make their age public, but will list their birthdate as month and year. For example, Facebook does this.

So now I need a Date-kinda field that has an optional year. I can trivially store the date as a six character string, and add an implied year if the string length is 4. But I want to be able to use usual Date/Timestamp/Calendar functions to figure out day of week, is today the birthdate, etc. I really don't want to reimplement one of these non-trivial classes

Any words of wisdom?
 
Sheriff
Posts: 21328
87
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You could just set the year to something you know won't be possible, like 1600. If the year is then this "bogus" year you can ignore it.

Another obvious choice is keep three separate fields for the month, day of month and year. Omitting the year is simply keeping its value at NULL. Creating a Calendar object is trivial with these three values (just remember that Calendar months start at 0, not 1), and therefore so is creating a Date object.
 
Pat Farrell
Rancher
Posts: 4686
7
Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I thought about the bogus year idea, but most Date implementations start in 1970, and even I am older than that.
Rationally, the separate month/day/year fields should be integers, which makes testing for null a bit of a challenge.

Since every person has a birthdate, and nearly all personel/social sites store it, someone has to have implemented this before me. I hate reinventing the wheel.
 
Rob Spoor
Sheriff
Posts: 21328
87
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Pat Farrell wrote:I thought about the bogus year idea, but most Date implementations start in 1970, and even I am older than that.


Ah, but java.util.Date allows negative times - the number of milliseconds before the epoch. You can go -Long.MIN_VALUE milliseconds back, or almost 300,000 centuries.

Rationally, the separate month/day/year fields should be integers, which makes testing for null a bit of a challenge.


Why? NULL != 0. ResultSet has a method called wasNull(). Combine this with getInt() and you can find out if your 0 is really a 0 or NULL. Or you could just let your database months start at 1 like the days, so values of 0 are non-values. Just remember to subtract 1 when passing the month to a Calendar object.
 
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you do use an "impossible" year from the past, be sure to use a leap year, so that Feb 29 is representable. 1600 is indeed a leap year, so this would be a fine choice.

As far as existing implementations, you might want to look at JodaTime. I think what you want is best represented as a Partial with only month and day specified. Alternately you may want to check out the JSR-310 Early Draft Review - they have a MonthDay that represents this particular concept more concisely. With luck, this may yet make it into JDK 7. And they could use the feedback. Note that a lot of JSR-310 is based on JodaTime, as Stephen Colbourne created JodaTime and is the primary force behind the JSR-310 implementation. JSR-310 builds on lessons learned from Joda, and has a lot more feedback from the community. But it's still in flux at this point. Either one is, frankly, a lot better than the existing Java API.
 
Pat Farrell
Rancher
Posts: 4686
7
Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks, I looked at Joda time, but didn't see Partial. Thanks for the link.

I've written some code today, using 1899 as the year for folks who don't want a real year associated with the birthdate. I had not thought about Feb 29, nice catch.
I can as easily use 1896.

I completely agree that the JDK's Date/Calendar/Timestamp/java.sql.Date stuff is a mess. It should be blown up and removed, IMHO, but that will never happen.

Once downside that I see in Joda-time is that its design predates Java 1.5, so its not setup for generics.

Luckily, for me, I don't have to deal with any calendars other than current GregorianCalendars.

Obscure Trivia on dates and calendars, the Russian Czars did not like the Gregorian Calendar, so they kept on a separate one, I think Julian based, up until the Communists came in during the Russian Revolution, and then the new Government switched to the Gregorian Calendar. So Months and dates in the early 1900s don't map well to our current thinking.
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Pat Farrell wrote:Obscure Trivia on dates and calendars, the Russian Czars did not like the Gregorian Calendar, so they kept on a separate one, I think Julian based, up until the Communists came in during the Russian Revolution, and then the new Government switched to the Gregorian Calendar. So Months and dates in the early 1900s don't map well to our current thinking.


Indeed - the October Revolution ("Red October") is actually named after an event that occurred on November 7, 1917, by our current Gregorian calendar. But it occurred on October 25, 1917, in the Julian calendar used at the time. Interesting that the Bolsheviks managed to force the calendar change, but the event is still known by the old calendar system.

Meanwhile, the Russian Orthodox Church continues to observe the original Julian calendar, which results in their celebrating Christmas on our January 7 (for the next century or so). Some other Orthodox churches do the same, while others have moved to the Revised Julian Calendar, which will be the same as the Gregorian Calendar until 2800, then it will diverge again.

Back to Java now. While I've often badmouthed Java's date/time stuff, I do have to acknowledge that GregorianCalendar is pretty sophisticated in many ways. It's complex and error-prone, true. But I'd say about 80% of that is because human calendaring systems are inherently complex and error-prone. Which starts with the fact that the Earth's period of revolution is not an integer multiple of its period of rotation. And is further exacerbated by various human stupidities over the course of history. Another 10% of the problem with Java's date/time stuff is simply because Java didn't originally have modern enums, and they made do with int constants. Yuck. While the remaining 10% was - how can I put this nicely? - sheer stupidity on the part of the implementors. (No, it's true - I didn't really try very hard.)

But, aside from that (how was your trip to Dallas, Mrs. Kennedy?) - I do want to acknowledge that GregorianCalendar has some very complex yet very robust code, that handles many of these issues for us. If we know how to ask it to. In particular, the setGregorianChange() method is a powerful tool for customizing a GregorianCalendar to many of the more vexing variations that exist for that system. Human calendars are messy, and the job of modeling them in software is far from trivial. So while Java's traditional date/time classes may leave much to be desired, they aren't completely worthless - and they're a substantial improvement over what most programmers might have cobbled together on their own, if they didn't have a standard library to fall back on.
 
Pat Farrell
Rancher
Posts: 4686
7
Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Mike Simmons wrote: I do want to acknowledge that GregorianCalendar has some very complex yet very robust code, that handles many of these issues for us. ....- and they're a substantial improvement over what most programmers might have cobbled together on their own, if they didn't have a standard library to fall back on.



For sure, calendars are complex. Just try to algorithmically find Easter. Or Passover. and I'm sure that there are other cultures that have similar differences that I've never even been exposed to.

I think we were very lucky that 2000 was actually a leap year, because zillions of programmers have trivially decided that dividing by 4 is good enough. Its not, but 2000 happened to be divisible by 400, so it was. I assume that by 2100, whoever is programming will have a very robust Calendar library that even knows about Martian and Klingon calendars.
 
Bartender
Posts: 11445
18
Android Eclipse IDE Google Web Toolkit Java Mac Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Pat Farrell wrote: I assume that by 2100, whoever is programming will have a very robust Calendar library that even knows about Martian and Klingon calendars.


Martians dont have calendars; they prefer to live out every individual day, without worrying about the future or the past! Some interesting stuff being discussed here. I got to learn something new.

Back to the original question. After reading the posts and looking at who wrote them, I think I am pretty sure I am misunderstanding the original problem, but here goes. Why do you want to tweak your DB? Is it not possible for you to manipulate this on the UI level? I mean mask out the year and just expose the month and date to the user on the UI? Or am I being dense?
 
Pat Farrell
Rancher
Posts: 4686
7
Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Not dense. Sometimes folks will be willing to enter the year as part of the date. If so, we want to be able to use it. But if they don't, and we won't ask why, we still want to do assorted Date/Calendar aritimetic so we can tell which day of the week the date is, calculate differences, etc. So having a Date or Calendar is useful.
 
Rob Spoor
Sheriff
Posts: 21328
87
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Pat Farrell wrote:I can as easily use 1896.


But there are still people around on this world who are born in the 19th century. That's why I picked 1600 - no way anyone who was born in that century is still going to be alive. No, zombies are not alive.
 
Pat Farrell
Rancher
Posts: 4686
7
Linux Mac OS X VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Rob Prime wrote:But there are still people around on this world who are born in the 19th century.


Technically true, but there are not many of them. They'd have to be 110 or more. Just making it to 100 gets you on Willard's weather forecast. I pulled it back to the leap year, 1896, which requires them to be 114. I claim that's enough.

BTW: tried to get Woflram ALpha to tell me how many people over 110 years old are in the world, no luck
 
What are you doing? You are supposed to be reading this tiny ad!
Rocket Oven Kickstarter - from the trailboss
https://coderanch.com/t/695773/Rocket-Oven-Kickstarter-trailboss
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!