5237


YouTube Data API から取得した､データを Gson
を使ってパースしようとしているのですが､対応するクラスについて､一つ疑問があります｡[リファレンス](https://developers.google.com/youtube/v3/docs/search?hl=ja#resource)を拝見すると
`publishedAt` の型は､ `datetime` となっていますが､次の例のように､ Gson では `Date`
型で当てはめてもいいのでしょうか､

**コード:**

[code]

    public class Snippet {
        public Date publishedAt;
        public String title;
        public String description;
        public Thumbnails thumbnails;
    }
    
[/code]

これを実行したところ､独自に作成した `CustomAdapter` で以下の `NullPointerException` が出てしまいました｡

**エラー:**

[code]

    java.lang.NullPointerException: Attempt to invoke virtual method 'long java.util.Date.getTime()' on a null object reference
    
[/code]

**CustomAdapter:**

[code]

    public class CustomAdapter extends ArrayAdapter<Items> {
    private LayoutInflater layoutInflater;
    private ImageLoader mImageLoader;
    private RequestQueue mQueue;
    
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
    
    public CustomAdapter(Context context, int textViewResourceId, List<Items> objects, RequestQueue queue){
        super(context, textViewResourceId, objects);
        layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mImageLoader = new ImageLoader(queue, new LruCacheClass());
    }
    
    static class ViewHolder{
        ImageView image;
        TextView title;
        TextView maker;
        TextView numView;
    }
    
    @Override
    public View getView(int position, View convertView, ViewGroup parent){
        ViewHolder holder;
        Items item = getItem(position);
        String url = item.snippet.thumbnails.high.url;
    
        if(convertView==null){
            convertView = layoutInflater.inflate(R.layout.list_search, parent, false);
    
            holder = new ViewHolder();
            holder.image = (ImageView)convertView.findViewById(R.id.iv_thumbnail);
            holder.title = (TextView)convertView.findViewById(R.id.tv_movie_title);
            holder.maker = (TextView)convertView.findViewById(R.id.tv_maker);
            holder.numView = (TextView)convertView.findViewById(R.id.tv_day_num_view);
            convertView.setTag(holder);
        }else{
            holder = (ViewHolder)convertView.getTag();
        }
    
        ImageLoader.ImageListener listener = ImageLoader.getImageListener(holder.image,
                android.R.drawable.spinner_background,
                android.R.drawable.ic_dialog_alert);
    
        mImageLoader.get(url, listener);
    
        holder.title.setText(item.snippet.title);
        holder.maker.setText(item.channelTitle);
        //この行でNullPointerExceptionがでてしまう｡
        holder.numView.setText(sdf.format(item.snippet.publishedAt.getTime()));
    
        return convertView;
    }
    }
    
[/code]

また､ `publishedAt`
でタイムゾーンに依存させたいので､[こちら](http://www30304u.sakura.ne.jp/blog/?p=2577)のサイトを参考にして
Gson を編集しています｡

**BuildGson:**

[code]

    import com.google.gson.FieldNamingPolicy;
    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    import com.google.gson.JsonDeserializationContext;
    import com.google.gson.JsonDeserializer;
    import com.google.gson.JsonElement;
    import com.google.gson.JsonParseException;
    
    import java.lang.reflect.Type;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.TimeZone;
    
    /**
     * Created by zousan on 2015/01/25.
     */
    public class BuildGson {
    public static Gson buildGsonForPublishedAt() {
        GsonBuilder gb = new GsonBuilder();
    
        gb.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
            @Override
            public Date deserialize(JsonElement dateElement, Type arg1, JsonDeserializationContext arg2)
                    throws JsonParseException {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.s'Z'");
                sdf.setTimeZone(TimeZone.getDefault());
    
                String date = dateElement.getAsString();
                try {
                    return sdf.parse(date);
                } catch (ParseException e) {
                    //System.err(String.format("Gsonのパースに失敗しました: %s", date));
                    return null;
                }
            }
        });
    
        gb.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
        return gb.create();
    }
    }
    
[/code]

改善点等ありましたら教えていただけると助かります｡


CC BY-SA 3.0
2015-01-25T02:50:44.707
5230
2015-01-25T05:42:14.550
2015-01-25T03:06:43.590
4978
7232
question
android json youtube-data-api
YouTube Data API のJSON データの datetime 値を Gson で扱うには


> SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.s'Z'");

ミリ秒は`S`なので`"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"`じゃないですか？

あと[Java
SE7だと`X`でISO8601タイムゾーン](http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html)を表すようです。[Androidのリファレンスには無い](http://developer.android.com/reference/java/text/SimpleDateFormat.html)ので未対応だと思いますが。


CC BY-SA 3.0
2015-01-25T03:23:36.830
5232
2015-01-25T03:33:42.120
2015-01-25T03:33:42.120
5750
5750
5230
answer


gsonオブジェクトを生成するときに、`datetime`の型を指定していないため、そもそもデシリアライズ対象として登録出来ていないんじゃないでしょうか。

細かいことはわかりませんが、  
BuildGsonにてgsonオブジェクトをnewするときに  
[`Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-
dd'T'HH:mm:ss.SSS'Z'").create();`](https://stackoverflow.com/questions/7910734/gsonbuilder-
setdateformat-for-2011-10-26t202959-0700)みたいなことをしてくださいとのことらしいです。

その上で、@pgrhoさんのおっしゃっているようにformatの型は`"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"`が一番いいみたいです。

[jsonファイルのサンプル](https://developers.google.com/youtube/v3/getting-
started?hl=ja)をフォーマットしてみた検証ログを置いておきます。

E/TAG﹕ "publishedAt": "2012-06-20T22:45:24.000Z",は次の感じになる？  
E/TAG﹕ yyyy-MM-dd'T'HH:mm:ss.s'Z'  
E/TAG﹕ Wed Jun 20 22:45:00 GMT+09:00 2012  
E/TAG﹕ yyyy-MM-dd'T'HH:mm:ss.SSS'Z'  
E/TAG﹕ Wed Jun 20 22:45:24 GMT+09:00 2012  
E/TAG﹕ yyyy-MM-dd'T'HH:mm:ssX  
E/TAG﹕ 落ちます  
E/TAG﹕ format結果  
E/TAG﹕ 2012/06/20  
E/TAG﹕ 2012/06/20  
E/TAG﹕ 落ちます


CC BY-SA 3.0
2015-01-25T05:42:14.550
5237
2015-01-25T05:42:14.550
2017-05-23T12:38:56.467
-1
2904
5230
answer