represent a birth date as a positive decimal number with the least digits

I am wanting to represent a birth date as a positive decimal number with the least digits. Assuming no one living was born before 1894 (120 years old), we can represent someone's birthday in pseudo code as:
   1/1/1894 + NumberOfDays
In VB:
   dateadd("d", NumberOfDays,#1/1/1894#)
In Java:
   var d = new Date("1/1/1894");
   d.setDate(d.getDate() + NumberOfDays);

In this case, the least number of digits would be 5:
   1/1/1894 + 44119 = 10/18/2014

Anybody have any tricks to get it down to 4 or even 3 digits? You can only use the numbers between 0 and 9 (what's on a telephone keypad).

TIA
LVL 39
thenelsonAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

GaryCommented:
How could you possibly get it below the digits in the number of days?
0
Ray PaseurCommented:
Huh?  Why not just ask them to enter the year of their birth, followed by the month of their birth, followed by the day?  You'll get three data elements like this:

$Y = 1960
$m = 9
$d = 15

And you can turn that into a normalized and ISO-8601 standard date string with strtotime() and date().  Something like this (PHP mktime() is also useful here)...

$iso_date = date('c', strtotime("$Y-$m-$d"));

Details about how to handle date/time values in PHP are available here:
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/A_201-Handling-date-and-time-in-PHP-and-MySQL.html
0
Dave BaldwinFixer of ProblemsCommented:
Putting it in a non-standard format is just the start of problems.  When you do that, you can't use any of the date arithmetic or manipulation routines that already exist.  You have to re-invent all those wheels all over again without the knowledge that teams of people have put into the standard routines.

If you are getting the info over the phone, I would split it up into parts.  That's the same thing I do on a PHP form because it prevents people from entering random unusable formats.
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

thenelsonAuthor Commented:
So you all are indirectly asking why I am asking this.

I want to put a serial number on prescriptions so that the pharmacist can verify the prescription as valid by calling a phone number, enter the serial number and get the birth date of the patient, the, date the prescription was written and the quantity of pills. Right now, this would be a 12 digit number: 5 for the birth date, 3 for the date the prescription was written (the reference date will roll over each year to January 1 of 2 years ago), 3 for the pill count and 1 digit for up to 10 prescriptions per person per day. This is a lot of digits to type into the phone.  Realize the POST phone doesn't understand computer standards. And I am not wanting someone to enter their birth date, I am want someone to enter a somewhat cryptic number and get a birth date.

So any ideas to represent a birth date, a date less than 1 year ago (prescriptions are good for a maximum of 1 year) and a pill count of less than 300 in less than 11 digits would be helpful.

I realize that I could upload the details of a prescription to a database and use a 4 digit number for the index field of the record (deleting records as 4 digits roll over) but this would require a lot more programming and the doctor doesn't always have internet access when he creates and prints the prescription. And yes, I know there are escripting solutions but, again, the doctor doesn't always have internet access when he creates and prints the prescription and most escripting doesn't support controlled substances (a few do but very few pharmacies support them yet).
0
Ray PaseurCommented:
I'm going to step away from this question.  

You need to get medical professionals, UX designers and data architects involved, and you may require legal counsel to get government approval for a system like this.  You're dealing with people's lives and health here, and there are trial lawyers circling applications like this one, as if they were sharks waiting for your blood in the water.  If the design ever fails, even for reasons that are beyond your control, the story is likely to unfold in ways that have unlimited personal liability.

Best of luck with the project, and I wish you well, ~Ray
0
thenelsonAuthor Commented:
I have been a systems engineer/programmer for 45 years and have been writing software for the healthcare industry for 20+ years. I have copious legal counsel just down the hall and government approval is not needed for this piece of the puzzle. So I think I have that covered but thanks for your concern.

I also have several very clever programmers working with me and we have brainstormed this. I am just reaching out for someone more clever than everyone I have that may have a very clever suggestion before we put this in place.
0
CPColinSenior Java ArchitectCommented:
The number of possible years, 120, fits into seven bits. The number of possible months, 12, fits into four bits. The number of possible days, 31, fits into five bits. (The number of possible days in a year, 366, fits into nine bits, so you wouldn't save any space over keeping the month and day separate.) That's sixteen bits total.

Since 2^16 = 65536, you're pretty much stuck with using five digits to represent the date of birth (or the date the prescription was written).
0
dpearsonCommented:
The maximum number of possible unique values expressed in 4 digits is 10^4 = 10,000.
The number of unique days in 121 years is 121*365 = 44,165 (ignoring leap years).

So it's not possible that a packing could exist that will represent 44,000 unique values using a representation that only includes 10,000 unique values.  Certain values in the 4 digit representation would have to map to multiple dates.

i.e. There is no possibility that a representation using less than 5 digits exists.

So if you want less than 5 digits, the only way is to express a range of birth dates with a value (e.g. encode the birth week, not the birth day).  

Doug
0
akbCommented:
Is the birth date all that important or is the aim just to help ensure you have the correct person?
It is possible that two people have the same birth date so even knowing the birth date isn't a guarantee that you have the right person.
What about using an algorithm that produces a 3 or 4 digit number based on the date? You wouldn't be able to extract the date from it but you would be able to reproduce the same number from the same date - a bit like a check digit on a barcode.
If you make the number 4 digits then there would only be 4 or 5 other dates in the last 120 years which would generate the same number.

Another possibility is to calculate the number based on days from 1/1/1894, 1/1/1921, 1/1/1948, 1/1/1975 or 1/1/2002 using a 4 digit number. If the person is standing in from of you then it's going to be pretty obvious if they are 10 years old, 37 years old, 64 years old, etc.
0
ozoCommented:
44165 values * 366 values * 300 values = 4849317000 values, which fits in 10 digits
0
akbCommented:
As ozo said, multiply all the values and end up with a ten digit number.

Then generate a 4 digit checksum. Only one chance in 10,000 of getting that wrong.
Or make it a 5 or 6 digit checksum for greater security.
0
CEHJCommented:
So you all are indirectly asking why I am asking this.

I want to put a serial number on prescriptions so that the pharmacist can verify the prescription as valid ...

Are you sure that's all your goal is? If that's the case, all they need is to look up the serial number in a database to verify its existence don't they? The greater the number of digits of the serial number that are entered, the greater the probability of a match

http://technojeeves.com/joomla/index.php/free/117-smart-questions
0
ozoCommented:
A 4, 5 or 6 digit checksum could as easily be generated from more than 10 digits, so you might as well include the year the prescription was written, so an number from last year doesn't inappropriately match, and the name of the patient and the doctor, so that people born on the same day don't cause inappropriately matches.
But  a 4 digit checksum can have more than one chance in 10,000 of getting that wrong when more than one number is in the database, so you may want to add more digits to reduce the chance of collisions.
0
CEHJCommented:
I suspect part of the goal/use case is actually authentication, which has quite different considerations
0
GaryCommented:
valid by calling a phone number, enter the serial number and get the birth date of the patient, the, date the prescription was written and the quantity of pills
Multiplying the numbers gets you nowhere.

Being stuck with only numbers as the output restricts you to pretty much the length of the numbers.
300 can only be represented by 300 - thats 3 digits either way, even if it was only 10 how do you know it is 10, what do you have to do to know that the pills only take 2 digits and not 3 digits.

You could mix up the numbers with a predefined pattern that would be easy to unscamble but not so easy to crack by the average Joe.
0
thenelsonAuthor Commented:
>44165 values * 366 values * 300 values = 4849317000 values, which fits in 10 digits
>As ozo said, multiply all the values and end up with a ten digit number.
Then how would I get the values back out?

>all they need is to look up the serial number in a database to verify its existence
As I stated earlier, using a database is not viable.

>I suspect part of the goal/use case is actually authentication, which has quite different considerations
Exactly right
0
akbCommented:
I didn't read your explanation thoroughly enough so didn't consider needing to get the data back out.
How about this: you need 17 bits to represent 44165 possible birth dates, 10 bits to represent day of year and 10 bits to represent quantity. That's 37 bits in total. 37 bits can be represented by 11 digits - 68,719,476,736 is the maximum number. Still more digits than you really want but you can shuffle the bits any way you like to "pseudo" randomise the number. You can then extract what you want by "unshuffling" the bits.
I also thought about using * and # as part of the serial number. These can be entered on a telephone keypad and would allow you to use base 12 instead of base 10 to generate the number. Unfortunately you'd still need 11 digits but the idea may give you something else to consider.
0
CEHJCommented:
>I suspect part of the goal/use case is actually authentication, which has quite different considerations
Exactly right
I think you should probably talk more about that. For one thing, presenting a birthdate as a token of authentication (if that's the plan) is weak, to say the least.
0
GaryCommented:
11 numbers for the birthday, prescription date and number of pills
Scramble them up if need be.

<?php

$sDate = new DateTime("1894/12/31"); // start date

$bDate = new DateTime("1960/05/25"); // birthday

$pDate = str_pad(date('z',strtotime("2014/02/15"))+1, 3, "0", STR_PAD_LEFT); // prescription date

$pills = str_pad(50, 3, "0", STR_PAD_LEFT); // no. of pills, 50 in this case

$diff = $sDate->diff($bDate)->format("%a");

echo "The result: " . $diff.$pDate.$pills

Open in new window

;
0
dpearsonCommented:
If you just want something short than can be used as a way to verify that a person is most likely the correct one - you could just use the day of the year instead of the full birthday.

That reduces your original problem from 5 digits down to 3 (1-365).

Simple to use, easy to make sure it's correct and unlikely to be accidentally duplicated.
0
ozoCommented:
totalvalue = (birthvalue * 366 + prescriptionvalue) * 300 + pillvalue
Then how would I get the values back out?
pillvalue = totalvalue % 300

prescriptionvalue = floor(totalvalue/300) % 366

birthvalue = floor(totalvalue/300/366)
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ozoCommented:
unlikely to be accidentally duplicated.
The authentication question is different from the get the values back out question, so we need to be clear which issue we are discussing.
If we are discussing the authentication issue, we should probably establish exactly how unlikely we require an accidental duplication to be.
We should also understand how interested we would be in detecting deliberate duplication.
0
awking00Commented:
Have you given any thought to using something like base-32? It would not necessarily be exact, but would be a close approximation. For example, Looking at a maximum of 366 days ago for the pills, 366 using Crockford's Base32 would be BE, so even if the intent was to enter BD or BF on the telephone dial, the difference would only be one day. Dialing the 7 or 9 that would represent PQRS and WXYZ, respectively would only be a difference of three days maximum. Just a thought.
0
thenelsonAuthor Commented:
ozo,

I tried your formula:
totalvalue = (birthvalue * 366 + prescriptionvalue) * 300 + pillvalue

Using a birthdate of 6/1/1950 and the reference date of 1/1/1894, the birthvalue would be 22065
Using a script written date of 10/21/2014 and the reference date of 1/1/2013, the prescriptionvalue would be 658
(I am using the reference date of Jan 1 of the year before the current year to avoid problems of scripts written near the beginning of the year - any script more than 1 year old is invalid.)
Using 150 as pillvalue:

(22065*366+658)*300+150 = 2422934550

pillvalue = totalvalue % 300
2422934550 % 300 = 150    correct

prescriptionvalue = floor(totalvalue/300) % 366
floor(2422934550/300)%366 = 292    incorrect

birthvalue = floor(totalvalue/300/366)
floor(totalvalue/300/366) = 22066  incorrect: one digit off

I tried a few other values with the same result.
Am I understanding this wrong?
0
ozoCommented:
The prescriptionvalue should be a number from 0 to 365, since there are 366 possible values for the date.
0
thenelsonAuthor Commented:
>The prescriptionvalue should be a number from 0 to 365, since there are 366 possible values for the date.
There is a problem with that since a prescription for a Class 4 medication is good for a year. Let's say we use a reference date of 1/1/2014 for the prescriptionvalue. Then 10/21/2014 be 293 which would work. But if the pharmacist checked the script on 1/3/2015, the code would return 10/21/2015 which would be incorrect. If the verification system only returned the month and day, then a forger could change the 2014 to 2015 on the script (which has been done) and have a script that passes verification.

This is the reason I am using the reference date of Jan 1 of the year before the current year.
0
ozoCommented:
So how many possible values would there be for the  prescriptionvalue?
44165 * 658 * 300 would still fit in 10  digits.
Is it possible to reduce the number of possible values for pillvalue?
I would not imagine that prescriptions for 271 pills would be common.
0
thenelsonAuthor Commented:
Not uncommon: a 90 day supply of 1 pill 4 times a day = 360 or a 90 day supply of 2 pills 3 times a day = 540.

It is sounding like 11 digits is the least.
0
ozoCommented:
Neither 90*4 nor 90*2*3 would give a pill count of 271, but earlier you said  "a pill count of less than 300"
Can we require, say, that the pill count is either less than 30 or a multiple of 10?
And you didn't clarify what the number of possible values should be for prescriptionvalue?
0
thenelsonAuthor Commented:
Ozo,

This is a work in progress. I thought  pill count would be less than 300 but just wrote a script for 450 two days ago. I guess 999 would be the limit and I think my original idea would be the best way to go.

However you taught me a very useful technique for combining several numbers to compress and sort of encrypt them and getting the original numbers back out. This will probably prove useful for me sometime so I thank you and give you the points.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.