Skip to content

Seamlessly Read/Write datetime.date Objects #18

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from

Conversation

riggsd
Copy link

@riggsd riggsd commented Dec 4, 2014

Pyshp's API is able to cast Python string/byte/unicode values, as well as numeric values. Its handling of Date fields is not so seamless. Users are expected to write exactly eight characters in YYYYMMDD format, then get handed a tuple of [year, month, day] ints when reading.

This patch allows writing values as datetime.date (or any subclass, eg. datetime.datetime). It also maintains backwards compatibility allowing the user to write a string value. It changes reading behavior, however, in that it now passes back a datetime.date object rather than a [year, month, day] int tuple. Reader does not handle NULL date fields, because I didn't want to clobber the patch I submitted with PR #16 ; so I'll note here that this code will raise an exception when reading a 'D' field with value "00000000" - I can amend this PR if you prefer.

This PR also adds a helper function Writer.fieldDate(name) so that users don't need to care about the underlying dBase storage whatsoever. I'd be happy to contribute more helper functions like this for other typical data types if you like.

A unit test is included; however I used the Python 2.1+ standard library's 'unittest' framework rather than grafting more doctests to the README file. Documentation has not been updated.

…ields. This makes the pyshp API considerably friendlier than strfmt'ing back and forth. Values are persisted exactly as before, as ASCII 'YYYYMMDD'.

Also adds a helper function `Writer.fieldDate()` for creating a 'D' field with the exact size needed.
…failing, and because the README is getting very unwieldy, I've used the Python 2.1+ stdlib 'unittest' framework. It would be nice to start building a robust unit testing suite anyway!
@GeospatialPython
Copy link
Owner

Great idea. I'm going to play with this change some more before merging.

size = int(size)
decimal = int(decimal)
if fieldType == 'D' and size < 8:
raise ShapefileException("Date fields require min size of 8 (%d is too small)" % size)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens when you have a date with size > 8? In my tests it seems to result in corrupt shapefiles. If I save a date with a size bigger than 8, then open the shapefile in arcmap and try to edit it, the data in the dbf file become corrupted.

Might it be better to mandate a size of exactly 8?

@micahcochran
Copy link
Contributor

I just ran across dates being represented by a list when reading a shapefile. Can this PR please be revisited?

@karimbahgat
Copy link
Collaborator

Reimplemented datetime.date reading/writing in #60, along with backwards compatibility for writing with date list, and reading and writing NULL dates.

Agree that users shouldn't have to worry about the size of the date field, but special methods for adding specific field types might get cluttery. Instead opted for forcing to correct size when adding date fields.

@karimbahgat
Copy link
Collaborator

Correction, I meant #71.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants