How to get string or int64 from object time in golang? - go

I get from input source timestamp and then I make time '00:00:00' for this timestamp. Now I need to get timestamp from object time
timestamp_int:= 1532009163
time := time.Date(
time.Unix(int64(timestamp_int), 0).UTC().Year(),
time.Unix(int64(timestamp_int), 0).UTC().Month(),
time.Unix(int64(timestamp_int), 0).UTC().Day(), 0, 0, 0, 0,
time.Unix(int64(timestamp_int), 0).UTC().Location())
new_time := time.Format("timestamp") //here i need to get new timestamp

You can get the timestamp in seconds by using the Unix method.
timestamp := 1532009163
t := time.Unix(int64(timestamp), 0)
newTimestamp := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, time.UTC).Unix()
fmt.Println(newTimestamp)
// 1531958400

Related

GoLang time zone conversion

I am looking to display a time in a specific format for a particular country. My current code:
now := time.Now()
ogTime := time.Date(2022, 8, 1, 0, 0, 0, 0, now.Location())
loc, _ := time.LoadLocation("Asia/Singapore")
convertedTime := ogTime.In(loc)
fmt.Println(convertedTime)
This prints out 2022-08-01 08:00:00 +0800 +08
Is there a way to display 2022-07-31T16:00:00Z? Is it possible to remove the time offset and instead just have a Z? I have tried ogTime.Format(RFC3339) as well as something like ogTime.Format("2006-01-02 T15:04:05Z"), but neither work.
fmt.Println is using the Stringer()-implementation of time.Time to print the value as a string, which determines the formatting for you.
To set the format yourself, use time.Time.Format();
now := time.Now()
fmt.Println(now.Format(`2006-01-02T15:04:05Z07:00`))
A "Z" in the output without an offset means the time is in UTC. If you do not want to print the timezone, omit it from the format;
fmt.Println(convertedTime.Format("2006-01-02T15:04:05"))
2022-08-01T08:00:00
If you want to print in UTC convert the timezone before printing; fmt.Println(convertedTime.UTC().Format("2006-01-02T15:04:05Z07:00"))
2022-08-01T00:00:00Z
Printing a "Z" while the time is not in UTC would require you to concatenate it yourself, but would be silly;
fmt.Println(convertedTime.Format("2006-01-02T15:04:05") + "Z")
2022-08-01T08:00:00Z
If you want to provide local time and print it in UTC, provide your timezone when parsing the date
loc, _ := time.LoadLocation("Asia/Singapore")
ogTime := time.Date(2022, 8, 1, 0, 0, 0, 0, loc)
fmt.Println(ogTime.UTC().Format("2006-01-02T15:04:05Z07:00"))
2022-07-31T16:00:00Z

Golang Time parsing providing the format is returning wrong results

I've got a t time.Time which I'm converting to an specific timezone and from which I need to extract both date and time (separately) as strings as follows:
Data should look like: 2006-09-23
Time should look like: 05:06:23
I'm doing the following:
Setting t to the needed timezone:
var err error
loc, err := time.LoadLocation("America/Los_Angeles")
if err != nil {
return err
} else {
t = t.In(loc)
}
Setting up the format and converting it to string so I can extract its values:
format := "2006-01-02 15:03:04"
timestamp := t.Format(format)
timestampSlice := strings.Fields(timestamp)
fmt.Println(timestampSlice[0])
fmt.Println(timestampSlice[1])
But I'm getting unexpected results for time (date works fine):
When passing
time.Date(2021, time.Month(2), 21, 1, 10, 30, 0, time.UTC)
I'd expect
2021-02-20 and 17:10:30
but I'm getting:
17:05:10 for the time
When passing
time.Date(2022, time.Month(8), 26, 22, 7, 30, 0, time.FixedZone("Asia/Shanghai", 0)),
I'd expect
2022-08-26 and 06:07:30
but I'm getting:
15:03:07
what am I doing wrong? does the values passed in the format have any effect in the parsing? I thought the format was only to signal the way the result should look
From the docs:
// Jan 2 15:04:05 2006 MST
// 1 2 3 4 5 6 -7
So the format 2006-01-02 15:03:04 would be parsed as years-months-days hours-hours-minutes. Note that 15 refers to the hours (00-23), that 03 refers to the hours (1-12), and 04 refers to the minutes.
So the correct format would be
format := "2006-01-02 15:04:05"
You can learn more about formatting time here: https://pkg.go.dev/time#example-Time.Format

check if timestamp between 2 dates

I have dates stored as timestamps in mongo, for example, 1564444800000000000. I want to check if a timestamp is between 2 dates - July 1, 2021 and July, 2021. I converted these 2 dates to timestamps using https://www.epochconverter.com/. I first fetched all records and while looping through the records, I did a check like so
cDate := 1564444800000000000
if cDate > 1625167488000 && cDate < 1627759488000 {
log.Fatal("found one!")
}
But this not seem to work as I get no matches. Is there a better way of doing this?
I mean just looking at the numbers:
cDate := 1564444800000000000
1625167488000
1627759488000
I don't see how one with six more digits than the one's it's supposed to be between would ever be between them. And even if we divided CDate by 1000000 it would be
cDate := 1564444800000
1625167488000
1627759488000
and it's still less than both of those, so it still wouldn't be between them. But that being said, you most likely do just need to divide cDate by 1000000 and your example is just not a good one (since 1564444800000 is July 29 2019)
I suggest to transform in a date then check with the before and after API, as example:
package main
import (
"fmt"
"time"
)
func main() {
cDate := int64(1564444800000000000)
firstJuly := time.Date(2019, 7, 1, 0, 0, 0, 0, time.UTC)
thrirtyOneJuly := time.Date(2019, 7, 31, 0, 0, 0, 0, time.UTC)
date := time.Unix(0, cDate)
// fmt.Println(date) //will print 2019-07-30 00:00:00 +0000 UTC
fmt.Println("Is July?", date.After(firstJuly) && date.Before(thrirtyOneJuly))
}
will print
Is July? true
See on playground

Type mismatch with projection on a []byte property

I have a struct as follows
type MyEntity struct {
PF []byte `json:"-" datastore:"_pf"`
}
Querying without a Projection works fine. However, when I query with projection on "_pf" field, I get "type mismatch: string versus []uint8" error. I implemented the PropertyLoadSaver and examined the prop.Value for "_pf" property and found that some rows return []byte type and some return string. So, why is projected query failing with this error while non-projected queries are fine? At the moment I am resolving this by implementing PropertyLoadSaver interface and explicitly checking types and converting string type to []byte type to solve this problem.
Here is the complete test case. This is reproduced on cloud datastore emulator. Use appropriate value for datastoreProject variable below. Rest all should directly work. You can see the behavior by inserting both entities or one of the types of the entities. The error that is displayed is
panic: datastore: cannot load field "_pf" into a "tests.MyEntity": type mismatch: string versus []uint8 [recovered]
panic: datastore: cannot load field "_pf" into a "tests.MyEntity": type mismatch: string versus []uint8
Following is the code.
type MyEntity struct {
PF []byte `json:"-" datastore:"_pf"`
}
func TestPackedField(t *testing.T) {
e1 := &MyEntity{PF: []byte{83, 0, 0, 0, 93, 150, 154, 206, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 3}} // returns []byte on projection
e2 := &MyEntity{PF: []byte{83, 0, 0, 0, 93, 120, 79, 87, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 3}} // returns string on projection
ctx := context.Background()
conn, err := datastore.NewClient(ctx, datastoreProject)
if err != nil {
panic(err)
}
bkey := datastore.NameKey("Bytes", "bytearray", nil)
if true {
conn.Put(ctx, bkey, e1)
}
skey := datastore.NameKey("Bytes", "string", nil)
if true {
conn.Put(ctx, skey, e2)
}
q1 := datastore.NewQuery("Bytes").Order("-_pf").Limit(2)
var elfull []*MyEntity
if _, err := conn.GetAll(ctx, q1, &elfull); err != nil {
panic(err)
}
q2 := datastore.NewQuery("Bytes").Project("_pf").Order("-_pf").Limit(2)
var elprojected []*MyEntity
if _, err := conn.GetAll(ctx, q2, &elprojected); err != nil {
conn.Delete(ctx, bkey)
conn.Delete(ctx, skey)
panic(err)
}
}
In order to understand why this works fine on normal queries and not on projection queries you might want firstly to read about what is the actual difference between those two. As it is mentioned in this post:
Whereas "regular" (which I'm taking to mean SELECT * ...) queries against Cloud Datastore typically use indexes that only contain a sorted subset of the properties of the queried entities, plus pointers to the full entities, projection queries run against indexes that contain all the fields requested by the query. So it appears the significant latency gain comes from the elimination of the need to fetch the queried entities once the set of entities matching the query has been discerned via the index.
So, basically, when you do your projection query, your queried entities are not fetched.
As I was reading through this official documentation, I found some really interesting phrases related to your question :
A field of slice type corresponds to a Datastore array property, except for []byte, which corresponds to a Datastore blob. If a non-array value is loaded into a slice field, the result will be a slice with one element, containing the value.
Key Field
If the struct contains a *datastore.Key field tagged with the name "key", its value will be ignored on Put. When reading the Entity back into the Go struct, the field will be populated with the *datastore.Key value used to query for the Entity.
What I understood from here is that maybe in your case, the fields are populated with the key value for that query ( string ).
Another interesting thing that I have discoverd is that according to the properties and values type documentation the type []byte is not indexed. And as it is told here, unindexed properties cannot be projected. So projected queries should not work for this particular use case at all.

How can I query all values except the value created today?

q := datastore.NewQuery("Encounter").Filter("PatientID =", patientID).Order("CreatedDate").Order("-CreatedBy")
How can I query all the values except the values created today?
Add a filter by CreatedDate.
t := time.Now()
zone, _ := time.LoadLocation("Europe/Amsterdam")
day := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, zone)
q := datastore.NewQuery("Encounter").Filter("PatientID =", patientID).Filter("CreatedDate <", day).Order("CreatedDate").Order("-CreatedBy")
This only returns items older than today. If you need both older and newer than today, since there is no inequality in filters, you can fetch older and newer than today, then iterate through them and append the results.

Resources