github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/amztime/parse.go (about) 1 // Copyright (c) 2015-2022 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 // Package amztime implements AWS specific time parsing and deviations 19 package amztime 20 21 import ( 22 "errors" 23 "net/http" 24 "time" 25 ) 26 27 // Supported amz date formats. 28 var amzDateFormats = []string{ 29 // Do not change this order, x-amz-date format is usually in 30 // iso8601Format rest are meant for relaxed handling of other 31 // odd SDKs that might be out there. 32 "20060102T150405Z", 33 time.RFC1123, 34 time.RFC1123Z, 35 // Add new AMZ date formats here. 36 } 37 38 // ErrMalformedDate always returned for dates that cannot be parsed. 39 var ErrMalformedDate = errors.New("malformed date") 40 41 // Parse parses date string via supported amz date formats. 42 func Parse(amzDateStr string) (time.Time, error) { 43 for _, dateFormat := range amzDateFormats { 44 amzDate, err := time.Parse(dateFormat, amzDateStr) 45 if err == nil { 46 return amzDate, nil 47 } 48 } 49 return time.Time{}, ErrMalformedDate 50 } 51 52 var httpTimeFormats = []string{ 53 // Do not change this order, http time format dates 54 // are usually in http.TimeFormat however there are 55 // situations where for example aws-sdk-java doesn't 56 // send the correct format. 57 http.TimeFormat, 58 "Mon, 2 Jan 2006 15:04:05 GMT", 59 } 60 61 // ParseHeader parses http.TimeFormat with an acceptable 62 // extension for http.TimeFormat - return time might be zero 63 // if the timeStr is invalid. 64 func ParseHeader(timeStr string) (time.Time, error) { 65 for _, dateFormat := range httpTimeFormats { 66 t, err := time.Parse(dateFormat, timeStr) 67 if err == nil { 68 return t, nil 69 } 70 } 71 return time.Time{}, ErrMalformedDate 72 } 73 74 // ParseReplicationTS parse http.TimeFormat first 75 // will try time.RFC3339Nano when parse http.TimeFormat failed 76 func ParseReplicationTS(str string) (time.Time, error) { 77 tm, err := time.Parse(http.TimeFormat, str) 78 if tm.IsZero() || err != nil { 79 tm, err = time.Parse(time.RFC3339Nano, str) 80 } 81 return tm, err 82 }