| 386 | } |
| 387 | |
| 388 | func formatBinaryDateTime(src []byte, length uint8) (driver.Value, error) { |
| 389 | // length expects the deterministic length of the zero value, |
| 390 | // negative time and 100+ hours are automatically added if needed |
| 391 | if len(src) == 0 { |
| 392 | return zeroDateTime[:length], nil |
| 393 | } |
| 394 | var dst []byte // return value |
| 395 | var p1, p2, p3 byte // current digit pair |
| 396 | |
| 397 | switch length { |
| 398 | case 10, 19, 21, 22, 23, 24, 25, 26: |
| 399 | default: |
| 400 | t := "DATE" |
| 401 | if length > 10 { |
| 402 | t += "TIME" |
| 403 | } |
| 404 | return nil, fmt.Errorf("illegal %s length %d", t, length) |
| 405 | } |
| 406 | switch len(src) { |
| 407 | case 4, 7, 11: |
| 408 | default: |
| 409 | t := "DATE" |
| 410 | if length > 10 { |
| 411 | t += "TIME" |
| 412 | } |
| 413 | return nil, fmt.Errorf("illegal %s packet length %d", t, len(src)) |
| 414 | } |
| 415 | dst = make([]byte, 0, length) |
| 416 | // start with the date |
| 417 | year := binary.LittleEndian.Uint16(src[:2]) |
| 418 | pt := year / 100 |
| 419 | p1 = byte(year - 100*uint16(pt)) |
| 420 | p2, p3 = src[2], src[3] |
| 421 | dst = append(dst, |
| 422 | digits10[pt], digits01[pt], |
| 423 | digits10[p1], digits01[p1], '-', |
| 424 | digits10[p2], digits01[p2], '-', |
| 425 | digits10[p3], digits01[p3], |
| 426 | ) |
| 427 | if length == 10 { |
| 428 | return dst, nil |
| 429 | } |
| 430 | if len(src) == 4 { |
| 431 | return append(dst, zeroDateTime[10:length]...), nil |
| 432 | } |
| 433 | dst = append(dst, ' ') |
| 434 | p1 = src[4] // hour |
| 435 | src = src[5:] |
| 436 | |
| 437 | // p1 is 2-digit hour, src is after hour |
| 438 | p2, p3 = src[0], src[1] |
| 439 | dst = append(dst, |
| 440 | digits10[p1], digits01[p1], ':', |
| 441 | digits10[p2], digits01[p2], ':', |
| 442 | digits10[p3], digits01[p3], |
| 443 | ) |
| 444 | return appendMicrosecs(dst, src[2:], int(length)-20), nil |
| 445 | } |