diff --git a/date_utils/date_utils.go b/date_utils/date_utils.go index c88b39a22077602ead42c62458808428a45db174..5f0ad1b4d4ac543812913a8499a64fb3031eb40d 100644 --- a/date_utils/date_utils.go +++ b/date_utils/date_utils.go @@ -2,6 +2,7 @@ package date_utils import ( "fmt" + "github.com/jinzhu/now" "reflect" "strconv" "strings" @@ -107,6 +108,33 @@ func CurrentDate() time.Time { return currentDate } +func TodayStart() string { + currentTime := CurrentDate() + return DateDBFormattedString(now.With(currentTime).BeginningOfDay()) +} + +func TodayEnd() string { + currentTime := CurrentDate() + return DateDBFormattedString(now.With(currentTime).EndOfDay()) +} + +func StartOfDay(date time.Time) time.Time { + day := now.With(date.In(CurrentLocation())).BeginningOfDay() + return day +} + +func EndOfDay(date time.Time) time.Time { + // Subtract one second from the start of the next day so that we have 23:59:59 instead of 23:59:58.999999 + day := now.With(date.AddDate(0, 0, 1).In(CurrentLocation())).BeginningOfDay().Add(-time.Second) + return day +} + +// BeginningOfNextDay is useful for specifying intervals where the beginning of the next day is excluded e.g. date < beginningOfNextDay +func BeginningOfNextDay(date time.Time) time.Time { + day := now.With(date.AddDate(0, 0, 1).In(CurrentLocation())).BeginningOfDay() + return day +} + func DateEqual(date1, date2 time.Time) bool { y1, m1, d1 := date1.Date() y2, m2, d2 := date2.Date() @@ -132,6 +160,26 @@ func TimeBefore(a string, b string) bool { return hoursA < hoursB } +// DatePtrToString converts a time.Time pointer to a string in the format "2006-01-02 15:04:05". +func DatePtrToString(date *time.Time) string { + if date == nil { + return "" + } + return date.In(CurrentLocation()).Format(DateLayoutYearMonthDayTime()) +} + +// DatePtrToTimeString converts a time.Time pointer to a string in the format "15:04". If the pointer is nil, it returns "--:--". +func DatePtrToTimeString(date *time.Time) string { + if date != nil { + // Convert to local time + DateLocal(date) + // Return formatted as time only + return date.Format("15:04") + } + + return "--:--" +} + // ConvertToNoDateTimeString - Converts a PSQL Time type to Go Time type func ConvertToNoDateTimeString(timeString *string) (*string, error) { parsedTime, err := time.Parse("15:04:05", *timeString) diff --git a/handler_utils/request.go b/handler_utils/request.go index ef101c40b64023109ad7da2603f4dad2509117b4..ec8ce8ef29fa807c7111d925f62220953686b068 100644 --- a/handler_utils/request.go +++ b/handler_utils/request.go @@ -3,7 +3,9 @@ package handler_utils import ( "bytes" "context" + "crypto/sha1" "crypto/sha256" + "encoding/base64" "encoding/hex" "io" "net/http" @@ -111,3 +113,12 @@ func FindHeaderValue(headers map[string]string, key string) string { } return "" } + +// HashRequestBody does a simple SHA1 hash of the provided body string. This is useful for checking for duplicates, but +// should not be used for any security purposes. +func HashRequestBody(body string) string { + algorithm := sha1.New() + algorithm.Write([]byte(body)) + sha := base64.URLEncoding.EncodeToString(algorithm.Sum(nil)) + return sha +} diff --git a/string_utils/string_utils.go b/string_utils/string_utils.go index 07dd05f75a460e4fc857c1ec80f50ca3cd0de2c3..7e776f6786d0580d3f0dbfbf89f2ab942d689fd3 100644 --- a/string_utils/string_utils.go +++ b/string_utils/string_utils.go @@ -7,6 +7,7 @@ import ( "github.com/jaytaylor/html2text" "github.com/samber/lo" "gitlab.bob.co.za/bob-public-utils/bobgroup-go-utils/number_utils" + "math" "regexp" "strconv" "strings" @@ -233,7 +234,7 @@ func Int64SliceToStringSlice(numbers []int64) []string { } func Float64ToString(number float64, precision int) string { - return strconv.FormatFloat(number, 'f', precision, 64) + return strconv.FormatFloat(number_utils.RoundFloat(number), 'f', precision, 64) } func Float64ToStringWithPrec(number float64, prec int) string { @@ -383,3 +384,54 @@ func HTMLStringToTextBytes(html string) ([]byte, error) { } return []byte(text), nil } + +func BoolToYesNo(val bool) string { + if val { + return "Yes" + } + return "No" +} + +func FormatCurrency(amount float64, currencySymbol string, formatZero bool) string { + if amount == 0 && !formatZero { + return "-" + } + + isNegative := amount < 0 + amount = math.Abs(amount) + + amountString := addSeparator(amount, " ") + + currencySymbol = strings.TrimSpace(currencySymbol) + if len(currencySymbol) > 0 { + currencySymbol += " " + } + + format := currencySymbol + "%s" + if isNegative { + format = " - " + format + } + return strings.TrimSpace(fmt.Sprintf(format, amountString)) +} + +func reverseString(s string) string { + stringRunes := []rune(s) + for i, j := 0, len(stringRunes)-1; i < j; i, j = i+1, j-1 { + stringRunes[i], stringRunes[j] = stringRunes[j], stringRunes[i] + } + + return string(stringRunes) +} + +func addSeparator(f float64, seperator string) string { + str := reverseString(fmt.Sprintf("%.2f", f)) + re := regexp.MustCompile(`([\d]){3}`) + str = strings.TrimSpace(re.ReplaceAllString(str, fmt.Sprintf(`$0%s`, seperator))) + + return reverseString(str) +} + +func IsAllDigits(str string) bool { + _, err := number_utils.StringToInt(str) + return err == nil +}