Skip to content

Commit

Permalink
Add --date-format and --datetime-format options to set strptime forma…
Browse files Browse the repository at this point in the history
…t strings.
  • Loading branch information
James McKinney committed Jan 28, 2017
1 parent 508c14e commit 71fac81
Show file tree
Hide file tree
Showing 13 changed files with 27 additions and 11 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Improvements:
* Add a :code:`--version` flag.
* Add a :code:`--skip-lines` option to skip initial lines (e.g. comments, copyright notices, empty rows).
* Add a :code:`--locale` option to set the locale of any formatted numbers.
* Add a :code:`--date-format` option to set a strptime date format string.
* Add a :code:`--datetime-format` option to set a strptime datetime format string.
* :code:`-I` is the short option for :code:`--no-inference`.
* :doc:`/scripts/csvjoin` supports :code:`--snifflimit` and :code:`--no-inference`.
* :doc:`/scripts/csvstat` adds a :code:`--freq-count` option to set the maximum number of frequent values to display.
Expand Down
10 changes: 8 additions & 2 deletions csvkit/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,12 @@ def _init_common_parser(self):
if 'S' not in self.override_flags:
self.argparser.add_argument('-S', '--skipinitialspace', dest='skipinitialspace', action='store_true',
help='Ignore whitespace immediately following the delimiter.')
if 'date-format' not in self.override_flags:
self.argparser.add_argument('--date-format', dest='date_format',
help='Specify a strptime date format string like "%%m/%%d/%%Y".')
if 'datetime-format' not in self.override_flags:
self.argparser.add_argument('--datetime-format', dest='datetime_format',
help='Specify a strptime datetime format string like "%%m/%%d/%%Y %%I:%%M %%p".')
if 'H' not in self.override_flags:
self.argparser.add_argument('-H', '--no-header-row', dest='no_header_row', action='store_true',
help='Specify that the input CSV file has no header row. Will create default headers (a,b,c,...).')
Expand Down Expand Up @@ -288,8 +294,8 @@ def get_column_types(self):
agate.Boolean(),
agate.Number(locale=self.args.locale),
agate.TimeDelta(),
agate.Date(),
agate.DateTime(),
agate.Date(date_format=self.args.date_format),
agate.DateTime(datetime_format=self.args.datetime_format),
text_type
])

Expand Down
2 changes: 1 addition & 1 deletion csvkit/utilities/csvclean.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

class CSVClean(CSVKitUtility):
description = 'Fix common errors in a CSV file.'
override_flags = ['H', 'L']
override_flags = ['H', 'L', 'date-format', 'datetime-format']

def add_arguments(self):
self.argparser.add_argument('-n', '--dry-run', dest='dryrun', action='store_true',
Expand Down
2 changes: 1 addition & 1 deletion csvkit/utilities/csvcut.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

class CSVCut(CSVKitUtility):
description = 'Filter and truncate CSV files. Like the Unix "cut" command, but for tabular data.'
override_flags = ['L']
override_flags = ['L', 'date-format', 'datetime-format']

def add_arguments(self):
self.argparser.add_argument('-n', '--names', dest='names_only', action='store_true',
Expand Down
2 changes: 1 addition & 1 deletion csvkit/utilities/csvformat.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

class CSVFormat(CSVKitUtility):
description = 'Convert a CSV file to a custom output format.'
override_flags = ['l', 'zero', 'H', 'L']
override_flags = ['l', 'zero', 'H', 'L', 'date-format', 'datetime-format']

def add_arguments(self):
self.argparser.add_argument('-D', '--out-delimiter', dest='out_delimiter',
Expand Down
2 changes: 1 addition & 1 deletion csvkit/utilities/csvgrep.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

class CSVGrep(CSVKitUtility):
description = 'Search CSV files. Like the Unix "grep" command, but for tabular data.'
override_flags = ['L']
override_flags = ['L', 'date-format', 'datetime-format']

def add_arguments(self):
self.argparser.add_argument('-n', '--names', dest='names_only', action='store_true',
Expand Down
2 changes: 1 addition & 1 deletion csvkit/utilities/csvjson.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def add_arguments(self):
self.argparser.add_argument('-y', '--snifflimit', dest='sniff_limit', type=int,
help='Limit CSV dialect sniffing to the specified number of bytes. Specify "0" to disable sniffing entirely.')
self.argparser.add_argument('-I', '--no-inference', dest='no_inference', action='store_true',
help='Disable type inference when parsing CSV input.')
help='Disable type inference (and --locale, --date-format, --datetime-format) when parsing CSV input.')

def main(self):
# We need to do this dance here, because we aren't writing through agate.
Expand Down
2 changes: 1 addition & 1 deletion csvkit/utilities/csvstack.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

class CSVStack(CSVKitUtility):
description = 'Stack up the rows from multiple CSV files, optionally adding a grouping value.'
override_flags = ['f', 'K', 'L']
override_flags = ['f', 'K', 'L', 'date-format', 'datetime-format']

def add_arguments(self):
self.argparser.add_argument(metavar="FILE", nargs='+', dest='input_paths', default=['-'],
Expand Down
2 changes: 1 addition & 1 deletion csvkit/utilities/csvstat.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@

class CSVStat(CSVKitUtility):
description = 'Print descriptive statistics for each column in a CSV file.'
override_flags = ['l', 'L']
override_flags = ['l', 'L', 'date-format', 'datetime-format']

def add_arguments(self):
self.argparser.add_argument('--csv', dest='csv_output', action='store_true',
Expand Down
2 changes: 1 addition & 1 deletion csvkit/utilities/in2csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def add_arguments(self):
self.argparser.add_argument('-y', '--snifflimit', dest='sniff_limit', type=int,
help='Limit CSV dialect sniffing to the specified number of bytes. Specify "0" to disable sniffing entirely.')
self.argparser.add_argument('-I', '--no-inference', dest='no_inference', action='store_true',
help='Disable type inference when parsing CSV input.')
help='Disable type inference (and --locale, --date-format, --datetime-format) when parsing CSV input.')

def main(self):
# Determine the file type.
Expand Down
2 changes: 1 addition & 1 deletion csvkit/utilities/sql2csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

class SQL2CSV(CSVKitUtility):
description = 'Execute an SQL query on a database and output the result to a CSV file.'
override_flags = 'f,b,d,e,H,K,L,p,q,S,t,u,z,zero'.split(',')
override_flags = 'f,b,d,e,H,K,L,p,q,S,t,u,z,date-format,datetime-format,zero'.split(',')

def add_arguments(self):
self.argparser.add_argument('--db', dest='connection_string', default='sqlite://',
Expand Down
5 changes: 5 additions & 0 deletions docs/common_arguments.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ All tools which accept CSV as input share a set of common command-line arguments
Specify the locale (en_US) of any formatted numbers.
-S, --skipinitialspace
Ignore whitespace immediately following the delimiter.
--date-format DATE_FORMAT
Specify a strptime date format string like "%m/%d/%Y".
--datetime-format DATETIME_FORMAT
Specify a strptime datetime format string like
"%m/%d/%Y %I:%M %p".
-H, --no-header-row Specify that the input CSV file has no header row.
Will create default headers (A,B,C,...).
-L SKIP_LINES, --skip-lines SKIP_LINES
Expand Down
3 changes: 3 additions & 0 deletions tests/test_utilities/test_in2csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ def test_version(self):
def test_locale(self):
self.assertConverted('csv', 'examples/test_locale.csv', 'examples/test_locale_converted.csv', ['--locale', 'de_DE'])

def test_date_format(self):
self.assertConverted('csv', 'examples/test_date_format.csv', 'examples/test_date_format_converted.csv', ['--date-format', '%d/%m/%Y'])

def test_convert_csv(self):
self.assertConverted('csv', 'examples/testfixed_converted.csv', 'examples/testfixed_converted.csv')

Expand Down

0 comments on commit 71fac81

Please sign in to comment.