@@ -56,6 +56,8 @@ type columnDetail struct {
5656 leftJustify bool
5757 zeroesAfterDecimal bool
5858 col sql.ColumnType
59+ precision int
60+ scale int
5961}
6062
6163// The default formatter based on the native sqlcmd style
@@ -304,6 +306,11 @@ func calcColumnDetails(cols []*sql.ColumnType, fixed int64, variable int64) ([]c
304306 columnDetails [i ].col = * c
305307 columnDetails [i ].leftJustify = true
306308 columnDetails [i ].zeroesAfterDecimal = false
309+ p , s , ok := c .DecimalSize ()
310+ if ok {
311+ columnDetails [i ].precision = int (p )
312+ columnDetails [i ].scale = int (s )
313+ }
307314 if length == 0 {
308315 columnDetails [i ].displayWidth = defaultMaxDisplayWidth
309316 } else {
@@ -359,6 +366,9 @@ func calcColumnDetails(cols []*sql.ColumnType, fixed int64, variable int64) ([]c
359366 columnDetails [i ].leftJustify = false
360367 columnDetails [i ].displayWidth = max64 (38 , nameLen )
361368 columnDetails [i ].zeroesAfterDecimal = true
369+ case "TIME" :
370+ columnDetails [i ].leftJustify = false
371+ columnDetails [i ].displayWidth = max64 (16 , nameLen )
362372 case "DATETIMEOFFSET" :
363373 columnDetails [i ].leftJustify = false
364374 columnDetails [i ].displayWidth = max64 (45 , nameLen )
@@ -451,7 +461,26 @@ func (f *sqlCmdFormatterType) scanRow(rows *sql.Rows) ([]string, error) {
451461 row [n ] = x
452462 case time.Time :
453463 // Go lacks any way to get the user's preferred time format or even the system default
454- row [n ] = x .String ()
464+ switch f .columnDetails [n ].col .DatabaseTypeName () {
465+ case "DATE" :
466+ row [n ] = x .Format ("2006-01-02" )
467+ case "DATETIME" :
468+ row [n ] = x .Format (dateTimeFormatString (3 , false ))
469+ case "DATETIME2" :
470+ row [n ] = x .Format (dateTimeFormatString (f .columnDetails [n ].scale , false ))
471+ case "SMALLDATETIME" :
472+ row [n ] = x .Format (dateTimeFormatString (0 , false ))
473+ case "DATETIMEOFFSET" :
474+ row [n ] = x .Format (dateTimeFormatString (f .columnDetails [n ].scale , true ))
475+ case "TIME" :
476+ format := "15:04:05"
477+ if f .columnDetails [n ].scale > 0 {
478+ format = fmt .Sprintf ("%s.%0*d" , format , f .columnDetails [n ].scale , 0 )
479+ }
480+ row [n ] = x .Format (format )
481+ default :
482+ row [n ] = x .Format (time .RFC3339 )
483+ }
455484 case fmt.Stringer :
456485 row [n ] = x .String ()
457486 // not sure why go-mssql reports bit as bool
@@ -472,6 +501,17 @@ func (f *sqlCmdFormatterType) scanRow(rows *sql.Rows) ([]string, error) {
472501 return row , nil
473502}
474503
504+ func dateTimeFormatString (scale int , addOffset bool ) string {
505+ format := `2006-01-02 15:04:05`
506+ if scale > 0 {
507+ format = fmt .Sprintf ("%s.%0*d" , format , scale , 0 )
508+ }
509+ if addOffset {
510+ format += " -07:00"
511+ }
512+ return format
513+ }
514+
475515// Prints the final version of a cell based on formatting variables and command line parameters
476516func (f * sqlCmdFormatterType ) printColumnValue (val string , col int ) {
477517 c := f .columnDetails [col ]
0 commit comments