Skip to content

time.Now().String() should work #32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
hajimehoshi opened this issue May 13, 2014 · 8 comments
Closed

time.Now().String() should work #32

hajimehoshi opened this issue May 13, 2014 · 8 comments

Comments

@hajimehoshi
Copy link
Member

Trying to convert a time.Time object to a string might not work. It is because this seems to need the access to a file where zones are defined if the Time includes a locale. As far as I know, a Time object with UTC (like a Time created by time.Parse()) doesn't cause problems. For example, on my locale machine:

package main

import (
        "time"
)

func main() {
        print(time.Now().String())
}

can be compiled, but the JavaScript file results in:

Uncaught Error: syscalls not available test.js:1145
go$panic test.js:1145
go$packages.syscall.syscall syscall_unix.go:33
go$packages.syscall.go$pkg.Syscall syscall_unix.go:41
go$packages.syscall.go$pkg.Open zsyscall_darwin_amd64.go:833
go$packages.time.readFile sys_unix.go:23
go$packages.time.loadZoneFile zoneinfo_read.go:206
go$packages.time.initLocal zoneinfo_unix.go:59
go$packages.sync.Once.Ptr.Do once.go:40
go$packages.time.Location.Ptr.get zoneinfo.go:69
go$packages.time.Time.Ptr.locabs time.go:272
go$packages.time.Time.Ptr.Format format.go:415
go$packages.time.Time.Ptr.String format.go:400
go$packages.main.go$pkg.main test.go:9
(anonymous function) test.go:9
(anonymous function)

I wonder if I could use Time object without accessing any files. As JavaScript's Time knows the local locale, time.Now().String() should be able to work.

@neelance
Copy link
Member

Is this a good solution to your problem?

@hajimehoshi
Copy link
Member Author

Yeah, it worked. Thanks!

@dolanor
Copy link

dolanor commented Aug 4, 2019

Hi,
I need to display a time.Duration and on my gopherjs install, a:

d, _ := time.ParseDuration("1m30s")
fmt.Println("%T, %v", d, d)
// prints: "int64, 90000000000"

And then, any attempt to call d.String() will be faced with: String is not a function

I tried on the gopherjs playground, and of course it doesn't have the same behavior. I have GopherJS 1.12-2. I don't know if it's linked to this issue or it's something else, and maybe I should open a new issue.

@theclapp
Copy link

theclapp commented Aug 4, 2019

GopherJS tip (3e4dfb7) with Go 1.12.7 on my mac works for me:

package main

import (
	"fmt"
	"runtime"
	"time"
)

func main() {
	d, _ := time.ParseDuration("1m30s")
	fmt.Printf("%T, %v\n", d, d)
	fmt.Printf("%s\n", d)
	fmt.Printf("%s\n", d.String())
	fmt.Printf("%s\n", runtime.Version())
}

prints

% gopherjs run issue_32.go
time.Duration, 1m30s
1m30s
1m30s
go1.12.7
% gopherjs version
GopherJS 1.12-2

Maybe an upgrade would fix things?

@dolanor
Copy link

dolanor commented Aug 4, 2019

Actually, to repeat my use case in a more similar way, I received a time.Duration in a struct unmarshaled from gob bytes. Trying to call this time.Duration's String() function failed with the String is not a function.

I found a workaround, which consists of:

durationWronglyConsideredAsInt64, _ := GetTimerDuration()
goodDuration := time.Duration(int64(durationWronglyConsideredAsInt64))

And then it's rightfully considered as time.Duration, and I can call .String() on it

(And I tried with just this, and it failed:

goodDuration := time.Duration(durationWronglyConsideredAsInt64)

)

@theclapp
Copy link

theclapp commented Aug 4, 2019

What's the actual type returned by GetTimerDuration()? I mean, time.Duration is just an int64, so it's not like there's a complex struct that needs to be initialized (at least from the Go point of view; I think int64s are emulated in GopherJS as two int32's). If GetTimerDuration isn't returning a time.Duration, that seems like the problem right there.

If it is returning a time.Duration, well, I don't know what to tell you. That's weird.

Could you post a full main() function or link to the GopherJS playground that reproduces the problem?

@dolanor
Copy link

dolanor commented Aug 4, 2019

Here is the gopherjs playground:
https://gopherjs.github.io/playground/#/ONanWJXXtL

And the equivalent go playground:
https://play.golang.org/p/91dh16Ry_BK

@theclapp
Copy link

theclapp commented Aug 5, 2019

Y'all this is weird. From @dolanor's first gopherjs playground link:

type Message struct {
	Duration time.Duration
}

m := Message{Duration: time.Minute}

var buf bytes.Buffer
err := gob.NewEncoder(&buf).Encode(m)
if err != nil {
	panic(err)
}

m2 := Message{}
err = gob.NewDecoder(&buf).Decode(&m2)
if err != nil {
	panic(err)
}
fmt.Printf("m2 => type: %T, value: %v, decimal: %d\n", m2.Duration, m2.Duration, m2.Duration)
// prints m2 => type: int64 [should be time.Duration], value: 60000000000 [should be 1m0s], decimal: 60000000000 [this is fine]

So somehow the gob decoder is not setting the type of m2.Duration correctly.

Somebody that knows more gopherjs internals than I do is going to have to weigh on this. Sorry @dolanor. Might want to open a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants