...
1
2
3 package backuptar
4
5 import (
6 "archive/tar"
7 "fmt"
8 "strconv"
9 "strings"
10 "time"
11 )
12
13
14
15
16
17
18
19
20 func parsePAXTime(s string) (time.Time, error) {
21 const maxNanoSecondDigits = 9
22
23
24 ss, sn := s, ""
25 if pos := strings.IndexByte(s, '.'); pos >= 0 {
26 ss, sn = s[:pos], s[pos+1:]
27 }
28
29
30 secs, err := strconv.ParseInt(ss, 10, 64)
31 if err != nil {
32 return time.Time{}, tar.ErrHeader
33 }
34 if len(sn) == 0 {
35 return time.Unix(secs, 0), nil
36 }
37
38
39 if strings.Trim(sn, "0123456789") != "" {
40 return time.Time{}, tar.ErrHeader
41 }
42 if len(sn) < maxNanoSecondDigits {
43 sn += strings.Repeat("0", maxNanoSecondDigits-len(sn))
44 } else {
45 sn = sn[:maxNanoSecondDigits]
46 }
47 nsecs, _ := strconv.ParseInt(sn, 10, 64)
48 if len(ss) > 0 && ss[0] == '-' {
49 return time.Unix(secs, -1*nsecs), nil
50 }
51 return time.Unix(secs, nsecs), nil
52 }
53
54
55
56 func formatPAXTime(ts time.Time) (s string) {
57 secs, nsecs := ts.Unix(), ts.Nanosecond()
58 if nsecs == 0 {
59 return strconv.FormatInt(secs, 10)
60 }
61
62
63 sign := ""
64 if secs < 0 {
65 sign = "-"
66 secs = -(secs + 1)
67 nsecs = -(nsecs - 1e9)
68 }
69 return strings.TrimRight(fmt.Sprintf("%s%d.%09d", sign, secs, nsecs), "0")
70 }
71
View as plain text