 9bdcbe0447
			
		
	
	9bdcbe0447
	
	
	
		
			
			Major integrations and fixes: - Added BACKBEAT SDK integration for P2P operation timing - Implemented beat-aware status tracking for distributed operations - Added Docker secrets support for secure license management - Resolved KACHING license validation via HTTPS/TLS - Updated docker-compose configuration for clean stack deployment - Disabled rollback policies to prevent deployment failures - Added license credential storage (CHORUS-DEV-MULTI-001) Technical improvements: - BACKBEAT P2P operation tracking with phase management - Enhanced configuration system with file-based secrets - Improved error handling for license validation - Clean separation of KACHING and CHORUS deployment stacks 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			153 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			153 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package sprig
 | |
| 
 | |
| import (
 | |
| 	"strconv"
 | |
| 	"time"
 | |
| )
 | |
| 
 | |
| // Given a format and a date, format the date string.
 | |
| //
 | |
| // Date can be a `time.Time` or an `int, int32, int64`.
 | |
| // In the later case, it is treated as seconds since UNIX
 | |
| // epoch.
 | |
| func date(fmt string, date interface{}) string {
 | |
| 	return dateInZone(fmt, date, "Local")
 | |
| }
 | |
| 
 | |
| func htmlDate(date interface{}) string {
 | |
| 	return dateInZone("2006-01-02", date, "Local")
 | |
| }
 | |
| 
 | |
| func htmlDateInZone(date interface{}, zone string) string {
 | |
| 	return dateInZone("2006-01-02", date, zone)
 | |
| }
 | |
| 
 | |
| func dateInZone(fmt string, date interface{}, zone string) string {
 | |
| 	var t time.Time
 | |
| 	switch date := date.(type) {
 | |
| 	default:
 | |
| 		t = time.Now()
 | |
| 	case time.Time:
 | |
| 		t = date
 | |
| 	case *time.Time:
 | |
| 		t = *date
 | |
| 	case int64:
 | |
| 		t = time.Unix(date, 0)
 | |
| 	case int:
 | |
| 		t = time.Unix(int64(date), 0)
 | |
| 	case int32:
 | |
| 		t = time.Unix(int64(date), 0)
 | |
| 	}
 | |
| 
 | |
| 	loc, err := time.LoadLocation(zone)
 | |
| 	if err != nil {
 | |
| 		loc, _ = time.LoadLocation("UTC")
 | |
| 	}
 | |
| 
 | |
| 	return t.In(loc).Format(fmt)
 | |
| }
 | |
| 
 | |
| func dateModify(fmt string, date time.Time) time.Time {
 | |
| 	d, err := time.ParseDuration(fmt)
 | |
| 	if err != nil {
 | |
| 		return date
 | |
| 	}
 | |
| 	return date.Add(d)
 | |
| }
 | |
| 
 | |
| func mustDateModify(fmt string, date time.Time) (time.Time, error) {
 | |
| 	d, err := time.ParseDuration(fmt)
 | |
| 	if err != nil {
 | |
| 		return time.Time{}, err
 | |
| 	}
 | |
| 	return date.Add(d), nil
 | |
| }
 | |
| 
 | |
| func dateAgo(date interface{}) string {
 | |
| 	var t time.Time
 | |
| 
 | |
| 	switch date := date.(type) {
 | |
| 	default:
 | |
| 		t = time.Now()
 | |
| 	case time.Time:
 | |
| 		t = date
 | |
| 	case int64:
 | |
| 		t = time.Unix(date, 0)
 | |
| 	case int:
 | |
| 		t = time.Unix(int64(date), 0)
 | |
| 	}
 | |
| 	// Drop resolution to seconds
 | |
| 	duration := time.Since(t).Round(time.Second)
 | |
| 	return duration.String()
 | |
| }
 | |
| 
 | |
| func duration(sec interface{}) string {
 | |
| 	var n int64
 | |
| 	switch value := sec.(type) {
 | |
| 	default:
 | |
| 		n = 0
 | |
| 	case string:
 | |
| 		n, _ = strconv.ParseInt(value, 10, 64)
 | |
| 	case int64:
 | |
| 		n = value
 | |
| 	}
 | |
| 	return (time.Duration(n) * time.Second).String()
 | |
| }
 | |
| 
 | |
| func durationRound(duration interface{}) string {
 | |
| 	var d time.Duration
 | |
| 	switch duration := duration.(type) {
 | |
| 	default:
 | |
| 		d = 0
 | |
| 	case string:
 | |
| 		d, _ = time.ParseDuration(duration)
 | |
| 	case int64:
 | |
| 		d = time.Duration(duration)
 | |
| 	case time.Time:
 | |
| 		d = time.Since(duration)
 | |
| 	}
 | |
| 
 | |
| 	u := uint64(d)
 | |
| 	neg := d < 0
 | |
| 	if neg {
 | |
| 		u = -u
 | |
| 	}
 | |
| 
 | |
| 	var (
 | |
| 		year   = uint64(time.Hour) * 24 * 365
 | |
| 		month  = uint64(time.Hour) * 24 * 30
 | |
| 		day    = uint64(time.Hour) * 24
 | |
| 		hour   = uint64(time.Hour)
 | |
| 		minute = uint64(time.Minute)
 | |
| 		second = uint64(time.Second)
 | |
| 	)
 | |
| 	switch {
 | |
| 	case u > year:
 | |
| 		return strconv.FormatUint(u/year, 10) + "y"
 | |
| 	case u > month:
 | |
| 		return strconv.FormatUint(u/month, 10) + "mo"
 | |
| 	case u > day:
 | |
| 		return strconv.FormatUint(u/day, 10) + "d"
 | |
| 	case u > hour:
 | |
| 		return strconv.FormatUint(u/hour, 10) + "h"
 | |
| 	case u > minute:
 | |
| 		return strconv.FormatUint(u/minute, 10) + "m"
 | |
| 	case u > second:
 | |
| 		return strconv.FormatUint(u/second, 10) + "s"
 | |
| 	}
 | |
| 	return "0s"
 | |
| }
 | |
| 
 | |
| func toDate(fmt, str string) time.Time {
 | |
| 	t, _ := time.ParseInLocation(fmt, str, time.Local)
 | |
| 	return t
 | |
| }
 | |
| 
 | |
| func mustToDate(fmt, str string) (time.Time, error) {
 | |
| 	return time.ParseInLocation(fmt, str, time.Local)
 | |
| }
 | |
| 
 | |
| func unixEpoch(date time.Time) string {
 | |
| 	return strconv.FormatInt(date.Unix(), 10)
 | |
| }
 |