playground now language golang datetime go datetime-comparison

datetime - now - Comparación de fecha/hora en golang



golang weekday (5)

En el caso de que al finalizar su intervalo, la fecha no incluya horas como "desde 2017-01-01 hasta todo el día de 2017-01-16", es mejor ajustar el intervalo a 23 horas, 59 minutos y 59 segundos, como:

end = end.Add(time.Duration(23*time.Hour) + time.Duration(59*time.Minute) + time.Duration(59*time.Second)) if now.After(start) && now.Before(end) { ... }

¿Hay alguna opción para comparar fechas en Golang? Tengo que ordenar los datos según la fecha y la hora, de forma independiente. Así que podría permitir que un objeto ocurra dentro de un rango de fechas, siempre y cuando ocurra dentro de un rango de veces. En este modelo, no podía simplemente seleccionar la fecha más antigua, la hora más reciente / fecha más reciente, la hora más reciente y los segundos de Unix () compararlos. Realmente agradecería cualquier sugerencia.

Finalmente, escribí un módulo de comparación de secuencias de tiempo para verificar si un tiempo está dentro de un rango. Sin embargo, esto no está yendo bien; Tengo algunos problemas enormes. Lo publicaré aquí solo por diversión, pero espero que haya una mejor manera de comparar el tiempo.

package main import ( "strconv" "strings" ) func tryIndex(arr []string, index int, def string) string { if index <= len(arr)-1 { return arr[index] } return def } /* * Takes two strings of format "hh:mm:ss" and compares them. * Takes a function to compare individual sections (split by ":"). * Note: strings can actually be formatted like "h", "hh", "hh:m", * "hh:mm", etc. Any missing parts will be added lazily. */ func timeCompare(a, b string, compare func(int, int) (bool, bool)) bool { aArr := strings.Split(a, ":") bArr := strings.Split(b, ":") // Catches margins. if (b == a) { return true } for i := range aArr { aI, _ := strconv.Atoi(tryIndex(aArr, i, "00")) bI, _ := strconv.Atoi(tryIndex(bArr, i, "00")) res, flag := compare(aI, bI) if res { return true } else if flag { // Needed to catch case where a > b and a is the lower limit return false } } return false } func timeGreaterEqual(a, b int) (bool, bool) {return a > b, a < b} func timeLesserEqual(a, b int) (bool, bool) {return a < b, a > b} /* * Returns true for two strings formmated "hh:mm:ss". * Note: strings can actually be formatted like "h", "hh", "hh:m", * "hh:mm", etc. Any missing parts will be added lazily. */ func withinTime(timeRange, time string) bool { rArr := strings.Split(timeRange, "-") if timeCompare(rArr[0], rArr[1], timeLesserEqual) { afterStart := timeCompare(rArr[0], time, timeLesserEqual) beforeEnd := timeCompare(rArr[1], time, timeGreaterEqual) return afterStart && beforeEnd } // Catch things like `timeRange := "22:00:00-04:59:59"` which will happen // with UTC conversions from local time. // THIS IS THE BROKEN PART I BELIEVE afterStart := timeCompare(rArr[0], time, timeLesserEqual) beforeEnd := timeCompare(rArr[1], time, timeGreaterEqual) return afterStart || beforeEnd }

Entonces, TLDR, escribí una función withinTimeRange (rango, tiempo) pero no funciona del todo correctamente. (De hecho, la mayoría solo es el segundo caso, donde un rango de tiempo que se cruza durante días se rompe. La parte original funcionó, me acabo de dar cuenta de que tendría que dar cuenta de eso al hacer conversiones de UTC a locales).

Si hay una forma mejor (preferiblemente integrada), ¡me encantaría saberlo!

NOTA: Solo como ejemplo, resolví este problema en Javascript con esta función:

function withinTime(start, end, time) { var s = Date.parse("01/01/2011 "+start); var e = Date.parse("01/0"+(end=="24:00:00"?"2":"1")+"/2011 "+(end=="24:00:00"?"00:00:00":end)); var t = Date.parse("01/01/2011 "+time); return s <= t && e >= t; }

Sin embargo, realmente quiero hacer este filtro en el lado del servidor.


Lo siguiente resolvió mi problema de convertir cadena en fecha

paquete principal

import ( "fmt" "time" ) func main() { value := "Thu, 05/19/11, 10:47PM" // Writing down the way the standard time would look like formatted our way layout := "Mon, 01/02/06, 03:04PM" t, _ := time.Parse(layout, value) fmt.Println(t) } // => "Thu May 19 22:47:00 +0000 2011"

Gracias a Paul Adam Smith


Los protocolos recientes prefieren el uso de RFC3339 por la time .

En general, se debe usar RFC1123Z en lugar de RFC1123 para los servidores que insisten en ese formato, y RFC3339 se debe preferir para los protocolos nuevos. RFC822, RFC822Z, RFC1123 y RFC1123Z son útiles para el formateo; cuando se usa con el tiempo.Por lo general, no aceptan todos los formatos de tiempo permitidos por las RFC.

cutOffTime, _ := time.Parse(time.RFC3339, "2017-08-30T13:35:00Z") // POSTDATE is a date time field in DB (datastore) query := datastore.NewQuery("db").Filter("POSTDATE >=", cutOffTime).


Para la comparación entre dos veces use time.Sub()

// utc life loc, _ := time.LoadLocation("UTC") // setup a start and end time createdAt := time.Now().In(loc).Add(1 * time.Hour) expiresAt := time.Now().In(loc).Add(4 * time.Hour) // get the diff diff := expiresAt.Sub(createdAt) fmt.Printf("Lifespan is %+v", diff)

Los resultados del programa:

Lifespan is 3h0m0s

http://play.golang.org/p/bbxeTtd4L6


Use el paquete de time para trabajar con la información de tiempo en Go.

Play ejemplo:

package main import ( "fmt" "time" ) func inTimeSpan(start, end, check time.Time) bool { return check.After(start) && check.Before(end) } func main() { start, _ := time.Parse(time.RFC822, "01 Jan 15 10:00 UTC") end, _ := time.Parse(time.RFC822, "01 Jan 16 10:00 UTC") in, _ := time.Parse(time.RFC822, "01 Jan 15 20:00 UTC") out, _ := time.Parse(time.RFC822, "01 Jan 17 10:00 UTC") if inTimeSpan(start, end, in) { fmt.Println(in, "is between", start, "and", end, ".") } if !inTimeSpan(start, end, out) { fmt.Println(out, "is not between", start, "and", end, ".") } }