How to convert ISO 8601 time in golang? - go

What is the equivalent code in golang for the following shell command ?
date -u +%Y-%m-%dT%T%z

If you're looking for a simple, but not perfect solution consider using time.RFC3339 constant. But also know that there are differences between ISO8601 which are too complex for this answer.
See https://ijmacd.github.io/rfc3339-iso8601/ for differences and also has a handy test file generator to show differences. There is also a good discussion on SO here What's the difference between ISO 8601 and RFC 3339 Date Formats?
package main
import (
"time"
"fmt"
)
func main(){
fmt.Println(time.Now().Format(time.RFC3339))
}
golang Time.Format

package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Now().UTC().Format("2006-01-02T15:04:05-0700"))
}

I had the following spec:
YYYY-MM-DDThh:mm:ss.sssZ
with the final Z being explicitly present in the examples.
Here's how I dealt with it:
first I found the time.RFCxxx that was the closest to my target
I copied its value
I fiddled with it until I found the expected result
which is
2006-01-02T15:04:05.999Z

ISO8601 allows for variable levels of granularity. You can have just a year, year+month, year+month+day, add a time portion, and optionally have a timezone portion. Go's built-in time parsing, however, requires you to know ahead-of-time which parts will be included.
The github.com/btubbs/datetime library provides a more flexible parser that can handle all the commonly used ISO8601 formats. See https://github.com/btubbs/datetime
Disclosure: I wrote that library.

Replacing the sign in the format with a Z triggers the ISO 8601 behavior. Which is exactly time.RFC3339. If you are wanting the string output to end in 'Z' what you need to do is convert to the UTC zone.
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Now().UTC().Format("2006-01-02T15:04:05Z07:00"))
}
// this is the same format used by RFC3339. just a note on why.

Related

Get sizeof internal go struct

I've been playing with uprobes. In order to probe a specific object in runtime, I need to know the size of internal go struct. In my case, the poll.FD. I could count each nested struct manually, but this could increase the complexity if we are working with a lot nested struct.
My first attempt was to use dlv expression , len <variable>. Didn't work Command failed: command not available
My second attempt was to create a program to extract this information:
package main
import (
"fmt"
"internal/poll"
"unsafe"
)
func main() {
fmt.Println("size of internal/poll FD struct:", unsafe.Sizeof(poll.FD{}))
}
When I compile the code above, the following message is shown:
main.go:7:2: use of internal package internal/poll not allowed
Am I missing something? Is there a better way get that information?
You can try do it by Testing in same package, in order to pass this limitation.
unsafe.Sizeof(reflect.ValueOf(<nested struct>)) is this what you're looking for to get the size of nested struct?
PS:This may not be answer but I can't comment.

How to format todays date in go as dd-mm-yyyy? [duplicate]

This question already has answers here:
How to convert date to different formats?
(2 answers)
Closed 5 years ago.
I am trying to format todays date in golang and seem to be struggling with something i deem to be quite simple.
I am trying to get todays date in the format of dd-mm-yyy
any ideas?
thanks
It works this way in Go Playground: https://play.golang.org/p/kBjTxZS9Y7
Here is the code:
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Now().Format("02-01-2006"))
}

How do I get colors to work with golang tabwriter?

I am using the tabwriter and I cannot get it to work with colors. I am using the "github.com/fatih/color" package.
Basically the problem is that I need to call tabwriter's w.Flush() in order to get the colors to render... I cannot switch colors if I have not called a flush.
Calling Flush in turn screws with the tabwriter formatting.
Any ideas on how to combine the two?
package main
import "fmt"
import "text/tabwriter"
import "os"
import "github.com/fatih/color"
func main() {
w := new(tabwriter.Writer)
w.Init(os.Stderr, 0, 8, 0, '\t', 0)
color.Set(color.FgGreen)
fmt.Fprintln(w, "ID\tNAME\tSIZE\tFIELD1\tSTATUS\tSTATE")
// ------> Calling w.Flush() here cases problems.
color.Set(color.FgYellow)
fmt.Fprintln(w, "8617833164795356724\tfoo1\t1.1 Gb\t3\tsome_status\tsome_state")
fmt.Fprintln(w)
w.Flush()
}
Despite what the accepted answer says, it is possible, you just have to be very careful about field length.
Wrap each "field" (i.e. a specific row and column) with a color+reset code. If all codes are of the same string length, tabwriter will give you a good result.
I have a crude demonstration here: https://play.golang.org/p/r6GNeV1gbH
I didn't do so in my demo, but you should also add the background codes as well (you can simply add them together as in RedText + YellowBackground), providing a default background. In this way, everything will be of equal length and you'll have background support as well.
Please note that I am a beginner Go programmer. I don't claim that my code is any good.
Short answer
You can't.
Naive answer
Use the color.Color.SprintFunc() method to get a function and wrap your strigns using this function.
Real answer
That won't work either, because the color is set using a special character sequence that isn't recognized by the tabwriter, so this row will be shorter by the length of twice the marker (one to set the color and one to get back to the standard color).
Solution
Write an alternative tabwriter (the algoerithm isn't even complex) that recognized the color character sequence and ignore it.

Date Format shows wrong date

I'm trying to format a date like this: [daynumber] [monthname] [fullyear]
package main
import (
"fmt"
"time"
)
func main() {
t := time.Now()
fmt.Println(t.Format("1 January 2014"))
}
However this prints out "11 November 10110" instead of the correct date "29 November 2014".
What is the correct way to use Time.Format?
Try:
fmt.Println(t.Format("2 January 2006"))
From Time.Format()
Format returns a textual representation of the time value formatted according to layout, which defines the format by showing how the reference time,
Mon Jan 2 15:04:05 -0700 MST 2006
The article "Parsing and formatting date/time in Go " adds:
The use of a mnemonic over obscure formatting codes I think reflects the pragmatism of Go’s developers and their focus on creating a language that makes its users more productive
Ironically, I have trouble remembering the exact values and order of that format template.
(Especially the day and month that I keep mixing up, being used to the dd-mm convention, as opposed to mm-dd).

Unix timestamp format conversion

A unix_timestamp of 1405936049 corresponds to: 2014-07-21 09:47:29. My goal is to derive the latter form from the timestamp.
After reading the format documentation, I came up with the following:
fmt.Println(time.Unix(1405936049, 0).Format("2006-01-02 15:04:05"))
which yields: 2014-07-21 02:47:29, which makes sense, since time.Unix(1405936049, 0) gives: 2014-07-21 02:47:29 -0700 PDT (to be clear, I want: 2014-07-21 09:47:29, the hour is incorrect).
I'm sure if I knew the correct terminology, I'd be able to find a solution in the documentation, but at this point, I'm uncertain how to tell the parser to account for -0700 or perhaps an alternative solution would be to use something besides time.Unix(), so that the resulting time would have already accounted for the hour difference? Any help would be appreciated.
You want the UTC time, not your local PDT time. For example,
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(time.Unix(1405936049, 0).UTC().Format("2006-01-02 15:04:05"))
}
Output:
2014-07-21 09:47:29
You have to use Location for this:
loc, _ := time.LoadLocation("Europe/Paris")
fmt.Println(time.Unix(1405936049, 0).In(loc).Format("2006-01-02 15:04:05"))
I think the location you want is "UTC", but I let you check (otherwise, here is a list of all available locations). The reason why in playground the format is already 09:47:29 is that playground does not include locations and uses UTC by default.

Resources