evermeer / PassportScanner

Scan the MRZ code of a passport and extract the firstname, lastname, passport number, nationality, date of birth, expiration date and personal numer.
BSD 3-Clause "New" or "Revised" License
457 stars 101 forks source link

DOB Format #30

Closed Dhillon22 closed 5 years ago

Dhillon22 commented 5 years ago

How are you differentiating if a person is born in 20th century or 21st century. DOB format in MRZ is YYMMdd...how are you calculating year as YYYY?

evermeer commented 5 years ago

Hmm... I see the problem here, I'm using a standard date formatter for that. Which means that you can't be born before 1950 because it will return a date in the future. so 490522 will return May 22 2049 I guess I have to fix by checking if the dat is in the future and then subtracting 100 year

The code I currently use is:

    class func dateFromString(_ value: String) -> Date? {
        var date: Date?
        let dateStringFormatter = DateFormatter()
        dateStringFormatter.dateFormat = "YYMMdd"
        dateStringFormatter.locale = Locale(identifier: "en_US_POSIX")
        let d = dateStringFormatter.date(from: value)
        if d != nil {
            date = Date(timeInterval:0, since:d!)
        }
        return date
    }
evermeer commented 5 years ago

I have just pushed a fix version 4.3.0 that will subtract 100 year if the date is in the future.

Dhillon22 commented 5 years ago

Still, How will you differentiate if a person is born in 2015 or in 1905 if the dob is 050201. For 050201, it may be 1st Jan 2015 or 1st Jan 1905. So how are you differentiating it?

evermeer commented 5 years ago

There is no way to detect if someone is older than 100 years old. So you will only get users between the age of 0 and 99.

Mattijah commented 5 years ago

@Dhillon22 How can you get 2015 from 05? On top of that it's not even January but February. For 05 you should go with 2005 as there is bigger chance of someone being born in 2005 than 1905. Unfortunately as mentioned in the previous comment you can't get the precise year.

All this is by the way resolved in the MRZ parser which I suggested to setup last time https://github.com/Mattijah/QKMRZParser

Dhillon22 commented 5 years ago

Thanks

evermeer commented 5 years ago

I guess it's a typo from @Dhillon22. He probably meant 2005 or 1905.

I see that QKMRZParser is using similar technique as I now do. But then it only differentiate between 19 and 20 centile. Which mean his code will have a problem the moment we go to the 21 centile 😉 In my case I just get the date with the format YYMMDD and subtract a century if it's in the future.

Mattijah commented 5 years ago

Which mean his code will have a problem the moment we go to the 21 centile

Are you sure this is something to really worry about? 😁That's at least 80 years far away (for the birthdate). I can't even see us using this format at this time anymore and I have doubts about existence of his codebase too 😁.

In my case I just get the date with the format YYMMDD and subtract a century if it's in the future.

That's the thing. You use DateFormatter to parse dates (*year) unlike QKMRZParser. The way how DateFormatter works is not clear to me and it may depend on user's (device) settings too. You don't really know what century you get back, do you? 1905 or 2005? On other hand logic set in QKMRZParser regarding birthdates is pretty clear. Same applies to the expiry date.

evermeer commented 5 years ago

It does not matter what logic is used to define the century with YYMMDD. It will never be more than 100 years from now. If it's in the past, then it's ok, if it's in the future I subtract 100 years. That way it does not matter what the switch year is for the centile. I only do that for birthdates. Other dates are left alone. So this logic will always get the correct date in the last 100 years. Even if its the year 2105.

Currently Apple is using 50 as the centile switch. This is fine for things like expiration dates. Expiration dates will probably never be more than a decade away from the current date anyway. QKMRZParser always set the date in the current centile (20)

Mattijah commented 5 years ago

QKMRZParser always set the date in the current centile (20)

No, the parser does differentiate between dates and sets either 19 or 20 centile.

Reasons for having hardcode 19-20 centile:

evermeer commented 5 years ago

No, the parser does differentiate between dates and sets either 19 or 20 centile.

For expiry dates it goes to a range between 1970 and 2070 and when using the dateformatter like I do it will be between the current year -50 year and + 50 years. So actually the results are quite similar at the moment but will change in a couple of years.

For birthdates it goes to the current year to -100 years which is the same logic as I have. It's only implemented differently. And in my case it keeps on working after 2100 which is actually a none issue. But then again, remember the Y2K issue?

Conclusion: I still think that the way I do it is better.

Mattijah commented 5 years ago

 QKMRZParser is using GMT which is just as wrong as specifying any other timezone. The moment of your birthdate changes depending on where you are on the world. If you move to the other side of the world, then your birthday will be shifted 12 hours. So actually you should use the timezone where the device is in. Then your birthdate should comply to that timezone. This is what I use.

QKMRZParser sets GMT to +0:00 in order to avoid any shifting of the date.

So actually you should use the timezone where the device is in. Then your birthdate should comply to that timezone. This is what I use...

Are you saying it's ok to be born let's say on the 1st of January 2000 but then on the other side of the world see this as December 31 1999? That's how it currently works in your case. Since when should birthdates (without any time details) comply to time-zones? Don't tell me that's ok 😁