Golang将2个JSON项解码为1个结构体。

huangapple go评论90阅读模式
英文:

Golang decode 2 JSON items into 1 struct

问题

我正在尝试将两个JSON项解码到同一个结构体中,因为第二个JSON项完善了第一个JSON项,但它不起作用(什么都不做),你有什么想法吗?

func getUserClip(this *LibraryController, id string) (*Clip){
	//Test Api
	//Send Request to azure search
	Data := Clip{}
	if req := GetClipById("b373400a-bd7e-452a-af68-36992b0323a5"); req == nil {
		return nil
	} else {
		str, err := req.String()
		if err != nil {
			beego.Debug("Error Json req.String: ", err)
		}
		//Uncode Json to string
		if err := json.Unmarshal([]byte(str), &Data); err != nil {
			beego.Debug("Error json", err)
		}
		for i := range Data.Value {
			if req = GetCliRedis(Data.Value[i].Id); err != nil {
				return nil
			} else {
				str, err := req.String()
				beego.Debug("JSON REDIS DEBUG: ", str)
				if err != nil {
					beego.Debug("Error Json req.String: ", err)
				}
				if err := json.Unmarshal([]byte(str), &Data); err != nil {
					beego.Debug("Error json", err)
				}
			}
			i++
		}
	}
	return &Data
}

type Clip struct {
	Value 	[]InfoClip `json:"value"`
}

type InfoClip struct {
	Id					string 		`json:"id"`
	CreatedAt			time.Time 	`json:"createdAt"`
	StartTimeCode  		int 	 	`json:"startTimeCode"`
	EndTimeCode    		int 	 	`json:"endTimeCode"`
	Metas           	metas  		`json:"metas"`
	Tags				[]string 	`json:"tags"`
	Categories			[]string 	`json:"categories"`
	UserId				string 		`json:"userId"`
	SourceId			string 		`json:"sourceId"`
	ProviderName      	string 		`json:"providerName"`
	ProviderReference 	string 		`json:"providerReference"`
	PublicationStatus 	string 		`json:"publicationStatus"`
	Name              	string 		`json:"name"`
	FacebookPage      	string 		`json:"facebookPage"`
	TwitterHandle     	string 		`json:"twitterHandle"`
	PermaLinkUrl      	string 		`json:"permalinkUrl"`
	Logo              	string 		`json:"logo"`
	Link              	string 		`json:"link"`
	Views 				int 		`json:"views"`
}

type metas struct {
	Title      			string 		`json:"title"`
	Tags       			[]string 	`json:"tags"`
	Categories 			[]string 	`json:"categories"`
	PermaLink  			string    	`json:"permalink"`
}

我收到的JSON是:

{  
   "clipId":"9b2ea9bb-e54b-4291-ba16-9211fa3c755f",
   "streamUrl":"https://<edited out>/asset-32e43a5d-1500-80c3-cc6b-f1e4fe2b5c44/6c53fbf5-dbe9-4617-9692-78e8d76a7b6e_H264_500kbps_AAC_und_ch2_128kbps.mp4?sv=2012-02-12&sr=c&si=17ed71e8-5176-4432-8092-ee64928a55f6&sig=KHyToRlqvwQxWZXVvRYOkBOBOF0SuBLVmKiGp4joBpw%3D&st=2015-05-18T13%3A32%3A41Z&se=2057-05-07T13%3A32%3A41Z",
   "startTimecode":"6",
   "endTimecode":"16",
   "createdAt":"2015-05-19 13:31:32",
   "metas":"{\"title\":\"Zapping : Obama, Marine Le Pen et Michael Jackson\",\"tags\":[\"actualite\"],\"categories\":[\"actualite\"],\"permalink\":\"http://videos.lexpress.fr/actualite/zapping-obama-marine-le-pen-et-michael-jackson_910357.html\"}",
   "sourceId":"6c53fbf5-dbe9-4617-9692-78e8d76a7b6e",
   "providerName":"dailymotion",
   "providerReference":"x1xmnxq",
   "publicationStatus":"1",
   "userId":"b373400a-bd7e-452a-af68-36992b0323a5",
   "name":"LEXPRESS.fr",
   "facebookPage":"https://www.facebook.com/LExpress",
   "twitterHandle":"https://twitter.com/lexpress",
   "permalinkBaseURL":"https://tym.net/fr/{CLIP_ID}",
   "logo":"lexpress-120px.png",
   "link":"http://videos.lexpress.fr/"
}

Redis完善了Azure搜索缺失的信息:

这是结构体:

type Clip struct {
	Value 	[]SearchClip `json:"value"`
}

type SearchClip struct {
	Id         			string `json:"id"`
	CreatedAt  			string `json:"createdAt"`
	Tags       			[]string `json:"tags"`
	Categories 			[]string `json:"categories"`
	UserId     			string `json:"userId"`
	SourceId   			string `json:"sourceId"`
	Views      			int `json:"views"`
}

这是基本信息,Redis完善了它。

如果没有其他更好的解决方案,我不想将两个结构体合并为第三个结构体。

英文:

i'm trying to decode 2 JSON items into the same struct, because the second JSON complet the first one, but it doesn't work (do nothing) have you got some ideas ?

func getUserClip(this *LibraryController, id string) (*Clip){
//Test Api
//Send Request to azure search
Data := Clip{}
if req := GetClipById(&quot;b373400a-bd7e-452a-af68-36992b0323a5&quot;); req == nil {
return nil
} else {
str, err := req.String()
if err != nil {
beego.Debug(&quot;Error Json req.String: &quot;, err)
}
//Uncode Json to string
if err := json.Unmarshal([]byte(str), &amp;Data); err != nil {
beego.Debug(&quot;Error json&quot;, err)
}
for i := range Data.Value {
if req = GetCliRedis(Data.Value[i].Id); err != nil {
return nil
} else {
str, err := req.String()
beego.Debug(&quot;JSON REDIS DEBUG: &quot;, str)
if err != nil {
beego.Debug(&quot;Error Json req.String: &quot;, err)
}
if err := json.Unmarshal([]byte(str), &amp;Data); err != nil {
beego.Debug(&quot;Error json&quot;, err)
}
}
i++
}
}
return &amp;Data
}

and the struct

type Clip struct {
Value 	[]InfoClip `json:value`
}
type InfoClip struct {
Id					string 		`json:id`
CreatedAt			time.Time 	`json:createdAt`
StartTimeCode  		int 	 	`json:startTimeCode`
EndTimeCode    		int 	 	`json:endTimeCode`
Metas           	metas  		`json:metas`
Tags				[]string 	`json:tags`
Categories			[]string 	`json:categories`
UserId				string 		`json:userId`
SourceId			string 		`json:sourceId`
ProviderName      	string 		`json:providerName`
ProviderReference 	string 		`json:providerReference`
PublicationStatus 	string 		`json:publicationStatus`
Name              	string 		`json:name`
FacebookPage      	string 		`json:facebookPage`
TwitterHandle     	string 		`json:twitterHandle`
PermaLinkUrl      	string 		`json:permalinkUrl`
Logo              	string 		`json:logo`
Link              	string 		`json:link`
Views 				int 		`json:views`
}
type metas struct {
Title      			string 		`json:title`
Tags       			[]string 	`json:tags`
Categories 			[]string 	`json:categories`
PermaLink  			string    	`json:permalink`
}

The JSON I receive is:

{  
&quot;clipId&quot;:&quot;9b2ea9bb-e54b-4291-ba16-9211fa3c755f&quot;,
&quot;streamUrl&quot;:&quot;https://&lt;edited out&gt;/asset-32e43a5d-1500-80c3-cc6b-f1e4fe2b5c44\/6c53fbf5-dbe9-4617-9692-78e8d76a7b6e_H264_500kbps_AAC_und_ch2_128kbps.mp4?sv=2012-02-12&amp;sr=c&amp;si=17ed71e8-5176-4432-8092-ee64928a55f6&amp;sig=KHyToRlqvwQxWZXVvRYOkBOBOF0SuBLVmKiGp4joBpw%3D&amp;st=2015-05-18T13%3A32%3A41Z&amp;se=2057-05-07T13%3A32%3A41Z&quot;,
&quot;startTimecode&quot;:&quot;6&quot;,
&quot;endTimecode&quot;:&quot;16&quot;,
&quot;createdAt&quot;:&quot;2015-05-19 13:31:32&quot;,
&quot;metas&quot;:&quot;{\&quot;title\&quot;:\&quot;Zapping : Obama, Marine Le Pen et Michael Jackson\&quot;,\&quot;tags\&quot;:[\&quot;actualite\&quot;],\&quot;categories\&quot;:[\&quot;actualite\&quot;],\&quot;permalink\&quot;:\&quot;http:\/\/videos.lexpress.fr\/actualite\/zapping-obama-marine-le-pen-et-michael-jackson_910357.html\&quot;}&quot;,
&quot;sourceId&quot;:&quot;6c53fbf5-dbe9-4617-9692-78e8d76a7b6e&quot;,
&quot;providerName&quot;:&quot;dailymotion&quot;,
&quot;providerReference&quot;:&quot;x1xmnxq&quot;,
&quot;publicationStatus&quot;:&quot;1&quot;,
&quot;userId&quot;:&quot;b373400a-bd7e-452a-af68-36992b0323a5&quot;,
&quot;name&quot;:&quot;LEXPRESS.fr&quot;,
&quot;facebookPage&quot;:&quot;https:\/\/www.facebook.com\/LExpress&quot;,
&quot;twitterHandle&quot;:&quot;https:\/\/twitter.com\/lexpress&quot;,
&quot;permalinkBaseURL&quot;:&quot;https:\/\/tym.net\/fr\/{CLIP_ID}&quot;,
&quot;logo&quot;:&quot;lexpress-120px.png&quot;,
&quot;link&quot;:&quot;http:\/\/videos.lexpress.fr\/&quot;
}

The Redis complet the azure search missing information :

here the struct :

type Clip struct {
Value 	[]SearchClip `json:value`
}
type SearchClip struct {
Id         			string `json:id`
CreatedAt  			string`json:createdAt`
Tags       			[]string `json:tags`
Categories 			[]string `json:categories`
UserId     			string `json:userId`
SourceId   			string `json:sourceId`
Views      			int `json:views`
}

this is the basic information and redis complet this

I don't want to merge 2 struct into a third one i think it's not the better process, i will do it if it's the last solution.

答案1

得分: 3

由于缺乏活动,我只会将嵌入选项作为解决方案发布出来。这可能是实现你想要的功能的最简单方法。

type ClipInfoAndMeta struct {
      Metas
      InfoClip
}

请注意,我将metas的名称大写了,不确定是否必要,但我认为这样做会更好。这里使用的语言特性称为“嵌入”,它的工作方式与组合非常相似,只是嵌入类型的字段/方法在包含类型的范围内更像是“提升”了。也就是说,对于ClipInfoAndMeta的实例,您可以直接访问在InfoClip上定义的任何公开字段。

你设置的一个奇怪之处是两种类型之间的字段名称会发生冲突。不确定这会产生什么结果。在说了这么多之后,看到你尝试从中解组的JSON字符串将会很有帮助。因为我在写这篇文章的时候意识到metas只是InfoClip的一个子集。这让我对你实际想要做什么感到困惑。我的意思是,如果返回的数据都在一个对象中,那么意味着InfoClip足以存储所有数据。如果是这种情况,你就没有理由使用另一个对象...如果你想要减少传递给应用程序显示层的字段,你应该在InfoClip类型上定义一个方法,比如func (i *InfoClip) GetMetas() Metas { return &Metas{ ... } },然后你可以在任何地方处理一个类型,并在需要时将Metas传递给显示层。

英文:

For lack of activity I'm just gonna post the embedding option as a solution. It's probably the simplest way to do what you want.

type ClipInfoAndMeta struct {
Metas
InfoClip
}

Note I upper cased the name on metas not sure it's necessary but I believe it will be. The language feature being used here is called 'embedding' and it works a lot like composition except that the fields/methods for embedded types are more or less 'hoisted' to the containing types scope. IE with an instance of ClipInfoAndMeta you can directly access any exported field that is defined on InfoClip.

One oddity of your set up is that you'll have collisions on field names between the two types. Not sure how that would play out. With all this being said, it would be helpful to see the json string you're trying to Unmarshal from. As I've been writing this I realized that metas is just a subset of InfoClip. Which has confused me about what you are actually trying to do? I mean, if the data coming back is all in one object, it would mean InfoClip is sufficient for storing all of it. If that is the case you have no reason for the other object... And if you want to trim down the fields which get passed to the display layer of your app you should just define a method on the InfoClip type like func (i *InfoClip) GetMetas() Metas { return &amp;Metas{ ... } } then you can just deal with the one type everywhere and hand off the Metas to the display layer when it's needed.

答案2

得分: 2

经过多次尝试和错误,我向您呈现了这个完全功能的解决方案:

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"time"
)

type Clip struct {
	Value []InfoClip `json:value`
}

type customTime struct {
	time.Time
}

const ctLayout = "2006-01-02 15:04:05"

func (ct *customTime) UnmarshalJSON(b []byte) (err error) {
	if b[0] == '"' && b[len(b)-1] == '"' {
		b = b[1 : len(b)-1]
	}
	ct.Time, err = time.Parse(ctLayout, string(b))
	return
}

type InfoClip struct {
	Id                string     `json:"clipId"`
	CreatedAt         customTime `json:"createdAt"`
	StartTimeCode     string     `json:"startTimeCode"` //if you want ints here, you'll have to decode manually, or fix the json beforehand
	EndTimeCode       string     `json:"endTimeCode"`   //same for this one
	Metas             metas      `json:"-"`
	MetasString       string     `json:"metas"`
	Tags              []string   `json:"tags"`
	Categories        []string   `json:"categories"`
	UserId            string     `json:"userId"`
	SourceId          string     `json:"sourceId"`
	ProviderName      string     `json:"providerName"`
	ProviderReference string     `json:"providerReference"`
	PublicationStatus string     `json:"publicationStatus"`
	Name              string     `json:"name"`
	FacebookPage      string     `json:"facebookPage"`
	TwitterHandle     string     `json:"twitterHandle"`
	PermaLinkUrl      string     `json:"permalinkBaseURL"`
	Logo              string     `json:"logo"`
	Link              string     `json:"link"`
	Views             int        `json:"views"`
}

type metas struct {
	Title      string   `json:"title"`
	Tags       []string `json:"tags"`
	Categories []string `json:"categories"`
	PermaLink  string   `json:"permalink"`
}

var jsonString = `{
   "clipId":"9b2ea9bb-e54b-4291-ba16-9211fa3c755f",
   "streamUrl":"https://<edited out>/asset-32e43a5d-1500-80c3-cc6b-f1e4fe2b5c44/6c53fbf5-dbe9-4617-9692-78e8d76a7b6e_H264_500kbps_AAC_und_ch2_128kbps.mp4?sv=2012-02-12&sr=c&si=17ed71e8-5176-4432-8092-ee64928a55f6&sig=KHyToRlqvwQxWZXVvRYOkBOBOF0SuBLVmKiGp4joBpw%3D&st=2015-05-18T13%3A32%3A41Z&se=2057-05-07T13%3A32%3A41Z",
   "startTimecode":"6",
   "endTimecode":"16",
   "createdAt":"2015-05-19 13:31:32",
   "metas":"{\"title\":\"Zapping : Obama, Marine Le Pen et Michael Jackson\",\"tags\":[\"actualite\"],\"categories\":[\"actualite\"],\"permalink\":\"http://videos.lexpress.fr/actualite/zapping-obama-marine-le-pen-et-michael-jackson_910357.html\"}",
   "sourceId":"6c53fbf5-dbe9-4617-9692-78e8d76a7b6e",
   "providerName":"dailymotion",
   "providerReference":"x1xmnxq",
   "publicationStatus":"1",
   "userId":"b373400a-bd7e-452a-af68-36992b0323a5",
   "name":"LEXPRESS.fr",
   "facebookPage":"https://www.facebook.com/LExpress",
   "twitterHandle":"https://twitter.com/lexpress",
   "permalinkBaseURL":"https://tym.net/fr/{CLIP_ID}",
   "logo":"lexpress-120px.png",
   "link":"http://videos.lexpress.fr/"
}`

func main() {
	res := parseJson(jsonString)
	fmt.Printf("%+v\n", res)
}

func parseJson(theJson string) InfoClip {
	toParseInto := struct {
		InfoClip
		MetasString string `json:"metas"`
	}{
		InfoClip:    InfoClip{},
		MetasString: "",
	}

	err := json.Unmarshal([]byte(jsonString), &toParseInto)
	if err != nil {
		log.Panic(err)
	}

	err = json.Unmarshal([]byte(toParseInto.MetasString), &toParseInto.InfoClip.Metas)
	if err != nil {
		log.Panic(err)
	}

	return toParseInto.InfoClip
}

parseJson函数中我们在创建一个新的结构体并将其赋值给toParseInto变量。我们设计这个结构体的方式是通过嵌入包含了InfoClip的所有字段,并添加一个字段来临时保存JSON字符串metas

然后我们将JSON解组到该结构体中,修复了下面列出的问题后,它可以正常工作。

之后,我们将内部JSON解组到嵌入的InfoClip中的正确字段。

现在,我们可以轻松地返回嵌入的InfoClip以获取我们真正想要的结果。

以下是我在您原始解决方案中发现的所有问题:

  1. 您的JSON中的时间格式不是JSON中要使用的标准时间格式。虽然它在某个RFC中定义,但无论如何:由于这个原因,我们必须使用自己的类型customTime来解析它。它的使用方式与普通的time.Time相同,因为它是嵌入其中的。
  2. 所有的json标签都是错误的。它们都缺少引号,有些甚至根本不正确。
  3. startTimeCodeendTimeCode在JSON中是字符串,而不是整数。

您可以改进的部分:

  • 错误处理:不要只是在parseJson函数中引发panic,而是以某种方式返回错误。
  • 如果您希望startTimecodeendTimecode作为整数可用,可以手动解析它们。您可以使用类似于我用于解析内部JSON的“hack”。

最后,请注意,这与您的问题无关,而是与您的问题相关:如果您在原始问题中提供了您的代码和JSON,您可能会在不到一个小时的时间内得到答案。不要把这弄得比必要的更难。

编辑:我忘记提供我的参考来源,我使用了这个问题来解析您的时间格式。

英文:

After a lot of trial and error, I present to you this fully functional solution:

package main
import (
&quot;encoding/json&quot;
&quot;fmt&quot;
&quot;log&quot;
&quot;time&quot;
)
type Clip struct {
Value []InfoClip `json:value`
}
type customTime struct {
time.Time
}
const ctLayout = &quot;2006-01-02 15:04:05&quot;
func (ct *customTime) UnmarshalJSON(b []byte) (err error) {
if b[0] == &#39;&quot;&#39; &amp;&amp; b[len(b)-1] == &#39;&quot;&#39; {
b = b[1 : len(b)-1]
}
ct.Time, err = time.Parse(ctLayout, string(b))
return
}
type InfoClip struct {
Id                string     `json:&quot;clipId&quot;`
CreatedAt         customTime `json:&quot;createdAt&quot;`
StartTimeCode     string     `json:&quot;startTimeCode&quot;` //if you want ints here, you&#39;ll have to decode manually, or fix the json beforehand
EndTimeCode       string     `json:&quot;endTimeCode&quot;`   //same for this one
Metas             metas      `json:&quot;-&quot;`
MetasString       string     `json:&quot;metas&quot;`
Tags              []string   `json:&quot;tags&quot;`
Categories        []string   `json:&quot;categories&quot;`
UserId            string     `json:&quot;userId&quot;`
SourceId          string     `json:&quot;sourceId&quot;`
ProviderName      string     `json:&quot;providerName&quot;`
ProviderReference string     `json:&quot;providerReference&quot;`
PublicationStatus string     `json:&quot;publicationStatus&quot;`
Name              string     `json:&quot;name&quot;`
FacebookPage      string     `json:&quot;facebookPage&quot;`
TwitterHandle     string     `json:&quot;twitterHandle&quot;`
PermaLinkUrl      string     `json:&quot;permalinkBaseURL&quot;`
Logo              string     `json:&quot;logo&quot;`
Link              string     `json:&quot;link&quot;`
Views             int        `json:&quot;views&quot;`
}
type metas struct {
Title      string   `json:&quot;title&quot;`
Tags       []string `json:&quot;tags&quot;`
Categories []string `json:&quot;categories&quot;`
PermaLink  string   `json:&quot;permalink&quot;`
}
var jsonString = `{  
&quot;clipId&quot;:&quot;9b2ea9bb-e54b-4291-ba16-9211fa3c755f&quot;,
&quot;streamUrl&quot;:&quot;https://&lt;edited out&gt;/asset-32e43a5d-1500-80c3-cc6b-f1e4fe2b5c44\/6c53fbf5-dbe9-4617-9692-78e8d76a7b6e_H264_500kbps_AAC_und_ch2_128kbps.mp4?sv=2012-02-12&amp;sr=c&amp;si=17ed71e8-5176-4432-8092-ee64928a55f6&amp;sig=KHyToRlqvwQxWZXVvRYOkBOBOF0SuBLVmKiGp4joBpw%3D&amp;st=2015-05-18T13%3A32%3A41Z&amp;se=2057-05-07T13%3A32%3A41Z&quot;,
&quot;startTimecode&quot;:&quot;6&quot;,
&quot;endTimecode&quot;:&quot;16&quot;,
&quot;createdAt&quot;:&quot;2015-05-19 13:31:32&quot;,
&quot;metas&quot;:&quot;{\&quot;title\&quot;:\&quot;Zapping : Obama, Marine Le Pen et Michael Jackson\&quot;,\&quot;tags\&quot;:[\&quot;actualite\&quot;],\&quot;categories\&quot;:[\&quot;actualite\&quot;],\&quot;permalink\&quot;:\&quot;http:\/\/videos.lexpress.fr\/actualite\/zapping-obama-marine-le-pen-et-michael-jackson_910357.html\&quot;}&quot;,
&quot;sourceId&quot;:&quot;6c53fbf5-dbe9-4617-9692-78e8d76a7b6e&quot;,
&quot;providerName&quot;:&quot;dailymotion&quot;,
&quot;providerReference&quot;:&quot;x1xmnxq&quot;,
&quot;publicationStatus&quot;:&quot;1&quot;,
&quot;userId&quot;:&quot;b373400a-bd7e-452a-af68-36992b0323a5&quot;,
&quot;name&quot;:&quot;LEXPRESS.fr&quot;,
&quot;facebookPage&quot;:&quot;https:\/\/www.facebook.com\/LExpress&quot;,
&quot;twitterHandle&quot;:&quot;https:\/\/twitter.com\/lexpress&quot;,
&quot;permalinkBaseURL&quot;:&quot;https:\/\/tym.net\/fr\/{CLIP_ID}&quot;,
&quot;logo&quot;:&quot;lexpress-120px.png&quot;,
&quot;link&quot;:&quot;http:\/\/videos.lexpress.fr\/&quot;
}`
func main() {
res := parseJson(jsonString)
fmt.Printf(&quot;%+v\n&quot;,res)
}
func parseJson(theJson string) InfoClip {
toParseInto := struct {
InfoClip
MetasString string `json:&quot;metas&quot;`
}{
InfoClip:    InfoClip{},
MetasString: &quot;&quot;}
err := json.Unmarshal([]byte(jsonString), &amp;toParseInto)
if err != nil {
log.Panic(err)
}
err = json.Unmarshal([]byte(toParseInto.MetasString), &amp;toParseInto.InfoClip.Metas)
if err != nil {
log.Panic(err)
}
return toParseInto.InfoClip
}

What are we doing in the parseJson function?

We create a new struct and assign that to the toParseInto variable. We design the struct in a way that it contains all of the fields from InfoClip via embedding, and We add a field to temporarily hold the JSON string metas.

We then unmarshal into that struct, which, after fixing the issues listed below, works fine.

After that, we unmarshal that inner JSON into the correct field in the embedded InfoClip.

We can now easily return that embedded InfoClip to get what we really wanted.

Now, all the issues I have identified in your original solution:

  1. The time format in your JSON is not the standard time format to be used in JSON. That is defined in some RFC, but anyways: because of that, we have to use our own type customTime to parse that. It handles just like a normal time.Time, because that is embedded within.
  2. All your json tags were wrong. All of them had missing quotes, and some were just not even correct.
  3. startTimeCode and endTimeCode are strings in the JSON, not ints

Left to you to improve:

  • Error handling: Don't just panic in the parseJson function, but rather return the error somehow
  • If you want startTimecode and endTimecode to be available as ints, parse them manually. You can employ a "hack" similar to the one I used to parse the inner JSON.

One final note, not related to this answer but rather to your question: If you had provided both your code and the JSON with your original question, you would have had an answer in probably less than an hour. Please, please don't make this harder than it needs to be.

EDIT: I forgot to provide my sources, I used this question to parse your time format.

huangapple
  • 本文由 发表于 2015年10月21日 17:40:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/33255821.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定