v icon indicating copy to clipboard operation
v copied to clipboard

json.decode does not parse time into Struct

Open JoyceBabu opened this issue 2 years ago • 4 comments

V version: V 0.3.0 ba1045e OS: macos, macOS, 12.5.1, 21G83

What did you do?

I am trying to decode a JSON string with a datetime field into a struct. As per https://github.com/vlang/v/discussions/11793, JSON.decode should be able to decode datetime string into time.Time, if the field is within a struct.

import json
import time

struct DeploymentInfo {
	version int
	date    time.Time
	name    string
	email   string
}

struct DeploymentInfo2 {
	version int
	date    Date
	name    string
	email   string
}

struct Date {
	time.Time
}

fn main() {
	res := '{ "version": 1, "name": "test", "date": "2001-01-01" }'
	info := json.decode(DeploymentInfo, res) ?
	println(info)
	info2 := json.decode(DeploymentInfo2, res) ?
	println(info)
}

What did you expect to see?

2001-01-01 to be parsed into time.Time.

DeploymentInfo{
    version: 1
    date: 2001-01-01 00:00:00
    name: 'test'
    email: ''
}
DeploymentInfo2{
    version: 1
    date: Date{
        Time: 0000-00-00 00:00:00
    }
    name: 'test'
    email: ''
}

or

DeploymentInfo{
    version: 1
    date: 1970-01-01 00:00:00
    name: 'test'
    email: ''
}
DeploymentInfo2{
    version: 1
    date: Date{
        Time: 2001-01-01 00:00:00
    }
    name: 'test'
    email: ''
}

What did you see instead?

DeploymentInfo{
    version: 1
    date: 1970-01-01 00:00:00
    name: 'test'
    email: ''
}
DeploymentInfo2{
    version: 1
    date: Date{
        Time: 0000-00-00 00:00:00
    }
    name: 'test'
    email: ''
}

JoyceBabu avatar Aug 30 '22 11:08 JoyceBabu

https://github.com/vlang/v/issues/15592#issuecomment-1230285571

You can try json2, or you can decode to string first, and then convert to time.Time

shove70 avatar Aug 31 '22 00:08 shove70

Usage error.

import json
import time

struct DeploymentInfo {
	version int
	date    time.Time
	name    string
	email   string
}

struct DeploymentInfo2 {
	version int
	date    Date
	name    string
	email   string
}

struct Date {
	time.Time
}

fn main() {
	res1 := '{ "version": 1, "name": "test", "date": 1661942525 }'
	info := json.decode(DeploymentInfo, res1) ?
	println(info)

	res2 := '{ "version": 1, "name": "test", "date": {"Time": 1661942525} }'
	info2 := json.decode(DeploymentInfo2, res2) ?
	println(info2)
}

PS D:\Test\v\tt1> v run .
DeploymentInfo{
    version: 1
    date: 2022-08-31 10:42:05
    name: 'test'
    email: ''
}
DeploymentInfo2{
    version: 1
    date: Date{
        Time: 2022-08-31 10:42:05
    }
    name: 'test'
    email: ''
}

yuyi98 avatar Aug 31 '22 02:08 yuyi98

res1 := '{ "version": 1, "name": "test", "date": 1661942525 }'

Upstream data providers usually do not use 'int' to represent time or date, such as RPC and REST API, so it needs to be improved here

shove70 avatar Aug 31 '22 05:08 shove70

#15592 (comment)

You can try json2, or you can decode to string first, and then convert to time.Time

Thank you for the suggestion. json2 worked for me.

JoyceBabu avatar Aug 31 '22 16:08 JoyceBabu

module main

import x.json2 as json
import time

struct DeploymentInfo {
	version int
	date    time.Time
	name    string
	email   string
}

struct DeploymentInfo2 {
	version int
	date    Date
	name    string
	email   string
}

struct Date {
	time.Time
}

fn main() {
	res := '{ "version": 1, "name": "test", "date": "2001-01-01" }'
	info := json.decode[DeploymentInfo](res) !
	println(info)
	info2 := json.decode[DeploymentInfo2]( res) !
	println(info)
}
V panic: result not set (array index out of range)
v hash: 1ba1f99
/tmp/v_1000/v_bug.14596429838912933521.tmp.c:8099: at _v_panic: Backtrace
/tmp/v_1000/v_bug.14596429838912933521.tmp.c:8069: by panic_result_not_set
/tmp/v_1000/v_bug.14596429838912933521.tmp.c:17997: by main__main
/tmp/v_1000/v_bug.14596429838912933521.tmp.c:18446: by main

enghitalo avatar Dec 09 '22 21:12 enghitalo