2017年6月30日金曜日

コスパ最高のワイン「アルパカ」

(2017/06/30)
前回はコスパの良い白ワインとしてフロンテラのシャルドネを紹介しました。
が、今回はさらにコスパが良い、というかコスパはおそらく
最強のワイン「アルパカ(Alpaca)」を紹介します。

今回も同じくチリワインで白、シャルドネです。
やはりチリのシャルドネはハズレが少ないんです。

トロピカルフルーツやピーチを想わせる豊かな果実味とコクのある味わいが特徴の、なめらかな飲み口の辛口白ワインです。

アサヒワインコムより

アルパカはなんといっても価格が魅力です。
スーパーだと500円を超えることはいままでなかったです。

(証拠写真)

味はフロンテラに比べると渋みが少なくスッキリしています。
飲みやすさで言えば辛口の中では最強ではないでしょうか。
高級感はないですが普段気軽に飲めるおいしい白ワインと言えると思います。

また、アルパカもスクリューキャップなのでオープナーがなくても
開けられますし余っても保存しやすいですね。

地中海料理と相性バッチリです!









2017年6月29日木曜日

コスパのいい白ワイン「フロンテラ」

(2017/06/29)
最近糖質制限ダイエットとかロカボダイエットとか流行っていますよね。
かくいう私もやっているのですが、ダイエットはやる気あっても
なかなかお酒をやめるのは難しいですよね。

そこでダイエット中でも飲んで大丈夫とされるお酒を挙げていきます。
基本的には蒸留酒ですが一部そうでないものも。
・ウイスキー
・泡盛
・ワイン(辛口)
・糖質0のビール系飲料、サワーなど

この中だとウイスキー(ハイボール)がいいと言う方も多いでしょうけど
ワインがいいかな、と思う人も多いかと思います。

そこでメインのお酒が白ワインの私がオススメのワインを紹介します。
今回紹介したいのは「フロンテラ(FRONTERA) シャルドネ」というチリワインです。


こちらのワインの実売価格は498円~698円というあたりが多いです。

熟したグレープフルーツ、アプリコット、トロピカルフルーツ、パイナップル、ナッツ、白桃、クルミ、ミネラル香と若干のスモーク香など、複雑で芳醇なアロマ。リッチな果実味とクリーンな透明感が同居する辛口ワインです。
KIRINの公式ホームページより

味はかなりサッパリとした辛口。渋みはそれなりにあります。
このワインのいいところは。。
・価格が手頃
・コンビニやスーパーで売っていることが多い
・辛口かつ飲みやすいシャルドネは料理をあまり選ばない
・スクリューキャップでオープナーが不要

こんなところですかね。
もう少し価格の安いおすすめの白ワインもありますが
味や香りはこちらの方が私は好きです。(私は濃いほうが好き)
ちなみにシャルドネというのはぶどうの種類の名前です。
もっと辛口が好き!という人は「ソーヴィニヨン・ブラン」もオススメです。

また白ワインは飲みきれなかった場合に残しておいて
料理に使うことができます。
そんなときにスクリューキャップだと保存しやすいですよね。

ちなみに私の経験上、糖質制限中にアルコールを取りすぎると
肝臓の処理がそちらに取られて低血糖症になりやすいので
ダイエット中にオススメといっても結局はほどほどがいいと思います。







2017年6月28日水曜日

Android開発でConstraintLayoutでアプリが落ちる現象

(2017/06/28)
ひさびさにAndroid開発をしようと思ってEmptyActivityで
空のアプリを作って以下のような簡単なListViewを表示しようとしたら
コンパイルエラーもないのにエミュレータ側でアプリが立ち上がらずに
落ちてしまいます。

class MainActivity : AppCompatActivity() {



    override fun onCreate(savedInstanceState: Bundle?) {

        super.onCreate(savedInstanceState)

        setContentView(R.layout.activity_main)

        // ListView

        val lv = findViewById(R.id.list_view) as ListView

        val list_items = listOf("1", "2", "3")

        // アダプタをセット

        val adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list_items)

        lv.adapter = adapter





    }

}


ちなみに環境は以下の通りです。
・Windows10
・AndroidStudio2.3.3
・Kotlin1.1.3


調べてみたらどうやらAndroidStudio2.2くらいからデフォルトで
選ばれるようになった「ConstraintLayout」が原因とわかりました。

以前のように「RelativeLayout」で書き直したら以下のように
問題なく動きました。


ConstraintLayoutはマテリアルデザインしやすかったりXMLのネストを
浅く書けたりするみたいなんですけど今のところちょっと不具合がまだ
多そうに感じます。
勉強するのも良さそうなのですがもうちょっと安定してからですかね。
私はとりあえずはRelativeLayoutで進めようかなと思っています。








「午後の紅茶 おいしい無糖」を紅茶好きのSEが飲んでみました。

(2017/06/28)
唐突ですが私は紅茶が好きです。
仕事中や食後もコーヒーではなく紅茶をいつも飲んでいます。

コーヒーはココぞというときにはたまに飲むのですが
どうも強すぎる味や香りが「大好き」にはなれないんです。

なので目も覚めつつ香りが程よくて飲みやすい紅茶はベストフレンドです。
中でもダージリンが好きなのですがKIRINからいい感じの商品が出ましたね。

午後の紅茶 おいしい無糖。
今までも無糖の紅茶はありましたがこの商品は少し違います。
ちゃんと「ダージリン」らしいです。
手摘みダージリン茶葉使用と記載があります。

早速FamilyMartで購入して飲んでみました。

さすがに香り、味ともにきちんと淹れたものやお店のものにはかないませんが
ちゃんとダージリンしてます!
値段も普通で150円程度でこれはコスパいいですね。

このレベルのものがコンビニや自販機で買えるというのは良い時代になりましたね。
私は甘いものが苦手なのでこういう無糖系があると本当助かります。

2017年6月現在、ペットボトルの紅茶の中では一番美味しいです。
自信を持ってオススメできます!


本当はFamilyMartでその場で淹れる紅茶があるみたいなのでそれを買いに行ったのですが
会社の最寄りのFamilyMartにはそれがないそうで買えなかったので
代わりにこちらを購入したんですよね。

次回はそちらのほうを飲んでみたいと思います。


2017年6月27日火曜日

TJライナーのメリット・デメリット

(2017/06/27)
他でもちょくちょく書いていますが私は埼玉県の坂戸市に住んでいます。
となると使用できる駅は東武東上線の坂戸駅一択です。
そして幸運なことにこの駅はTJライナーが停まる駅です。
そんなわけで私はTJライナーをかなりヘビーに使っております。

TJライナーについて軽く紹介します。

■TJライナーとは
TJライナー(ティージェイライナー)は、東武鉄道東上本線で運転されている座席定員制(池袋乗車時のみ)の優等列車である。JRなどで運行されているホームライナーに似た形で運行されている。
2008年(平成20年)6月14日に運転を開始し、東上本線の有料列車としては特急「フライング東上」号以来約50年ぶりとなる。ただし「TJライナー」は「フライング東上」と異なり、この名称を愛称としてだけではなく、愛称を兼ねた正式な列車種別名としている。
シンボルカラー(ロゴマーク)は青を基調とする。停車駅案内・駅時刻表においての色は橙を使用。
2010年1月には、日本鉄道運転協会創立51周年記念式典における東記念賞を受賞した[
Wikipediaより

■使用することになった経緯
私の会社は働き方をある程度自由に選べるので、TJライナーで通える時間帯で
仕事をすることができます。
お金よりもQOLを大事にする私としてはTJライナーを使わない選択肢はありませんでした。


■メリット
・必ず座れる
必ず座れるのは相当大きいです。この時間を作業などにあてることができるようになりました。

・座席が広く進行方向に向かって座れる
普通の車両が隣との距離はあまりないですがTJライナーはノートPCで作業できる程度の幅がありますし、新幹線に近いです。

・空調が通常の車両よりも良い
東武東上線はエアコンがひどいです。夏は暑いし冬は寒い。基本的に混み具合からすると不快指数は高いのですがTJライナーの空調はかなりいいです。暑い、寒いとは感じづらいです

・朝は特にすいているので二人がけの席でもだいたい一人で座れる
朝はまだ利用者が少ないのでひとりで2席独占状態が多いです。

・池袋~坂戸間が38分!
1時間を覚悟するこの距離がこの時間で済んでしまうのはすごいです。

・全車両で無料でTOBU WIfiが使用できるのでスタバ状態
ちょっと前のエントリーで書きましたが現在PCは証明書エラーでつなぐことができません。スマホに関しては問題なく無料でネットが使えます。


・スマホで予約できる
いちいち券売機でチケットを買う必要がありません。スマホでピピッとやって駅でQRコードを表示させて読んでもらえばOKです。クレジットカードは東武カードでなくて大丈夫です。(東武の定期券はあいかわらず東武カード必須)


■デメリット
・夜は310円、朝は410円かかる
このインセンティブに関して私はお金がかかるのは逆にメリットですが、費用がかかるというのはデメリットとは言えると思います。

・特に夜は二人席で隣で酒盛りが始まると匂いがきつい
わりとありがちなのですが、お仕事終えて疲れたサラリーマンが新幹線のごとくお酒を飲み始める事が多いです。が、新幹線ほど広くもないし換気もされないので匂いはかなりきつくなります。禁酒車両で+100円とかあったらそっち買います。。。

・朝は途中下車ができないのでお腹が痛いときには地獄を見る
お腹の調子が悪い日、二日酔いの日に死ぬ思いをしたことが何度かあります。。。
降りれないならば電車内にトイレを用意してください。お願いします。

・3大キャリアじゃないとスマホ利用できない。(3大キャリアのキャリアメール必須。。)
UQでも駄目です。3大キャリアのみ。システムは最低レベルです。
サービス開始当初は何故かSoftBankのiPhoneしか使用できず、auのiPhoneは弾かれるというお粗末さでした。


・座席は普通の車両と比べると良いが新幹線よりは狭く、それなりの体型の男性二人だと若干きつい
私は通常サイズの男ですが、同じサイズの男性が隣に座ると若干窮屈です。

・基本的にはスマホではなくチケットが前提のシステム
スマホでQRコードを表示させてそれを読み取ってもらうシステムですが、朝はハンディ端末で読むためにあまり問題ないですが池袋駅はチケットを読み取る前提で固定の装置で下から読み取るためスマホを逆向きにしなければならず読み取り失敗が多いです。


・朝はギスギスしている
メリットでも触れた点の裏返しなのですが、朝は一人で二人席を独占できることが多いため、逆にみんな隣に座られたくないというオーラがすごいです。隣の席にバッグを置いたりしてブロックするようなルール違反もかなり見られます。









Javaで文字列関連の自作ユーティリティ

(2017/06/27)
ApacheCommonsとGsonが必要なところがあります。

public class StringUtil {


    /**

    * パラメータを3桁カンマ区切り数字として返す。

    * @param number        処理対象文字列

    * @return                      フォーマット後文字列

    */

    public static String formatComma(String number) {

            if (!NumberUtils.isCreatable(number)) {

                    return number;

            }

            NumberFormat nfNum = NumberFormat.getNumberInstance();

            return nfNum.format(Double.parseDouble(number));

    }



    /**

    * パラメータの文字列を、パラメータの最大文字数で切って返す。

    *

    * nullの場合ブランクを返す。

    * 文字数以内の場合文字列をそのまま返す。

    * 指定文字数を超える場合は文字数で切った文字列を返す。

    *

    * @param target 処理対象文字列

    * @param length 文字数

    * @return 処理後文字列

    */

    public static String split(String target, int length) {

            String res = null;



            if (StringUtils.isEmpty(target)) {

                    res = "";

            } else if (target.length() > length) {

                    res = target.substring(0, length);

            } else {

                    res = target;

            }



            return res;

    }



    /**

    * 引数の文字列をSHA-256で暗号化して、16進数エンコードする。

    * ※base64でもエンコード出来るが、その場合、文字数が64文字以下になる。

    * @param pass

    * @return

    */

    public static String encode(String pass) {

            MessageDigest md = null;

            try {

                    md = MessageDigest.getInstance("SHA-256");

            } catch (NoSuchAlgorithmException e) {// 発生しない

                    e.printStackTrace();

            }

            md.update(pass.getBytes());

            byte[] digest = md.digest();



            // 16 進数文字列として出力

            StringBuilder sb = new StringBuilder();

            for(byte b : digest) {

                    String hex = String.format("%02x", b); // 16 進数 2 桁として表示 (1byte は 00 ~ ff)

                    sb.append(hex);

            }



            String result = sb.toString();



            if (result.length() > 64) {

                    result = result.substring(0, 64);

            }



            return result;

    }



    /**

    * ランダムな32文字の文字列を生成する。

    * CSRF攻撃対策用のトークンとして使用する。

    * @return

    */

    public static String getRandomToken() {

            SecureRandom random = new SecureRandom();

            byte bytes[] = new byte[32];

            random.nextBytes(bytes);



            // 16 進数文字列として出力

            StringBuilder sb = new StringBuilder();

            for(byte b : bytes) {

                    String hex = String.format("%02x", b); // 16 進数 2 桁として表示 (1byte は 00 ~ ff)

                    sb.append(hex);

            }



            String result = sb.toString();



            if (result.length() > 32) {

                    result = result.substring(0, 32);

            }

            return result;

    }



    /**

    * ランダムな文字列を生成する。

    * 文字列に記号を含めるため、base64でエンコードする。

    * パスワードを生成するために使用する。

    * @param num   文字数

    * @return      生成したパスワード

    */

    public static String getRandomPass(int num) {

            SecureRandom random = new SecureRandom();

            byte bytes[] = new byte[32];

            random.nextBytes(bytes);



            String encoded = Base64.getEncoder().encodeToString(bytes);



            String result =  "";

            if (num <= 32) {

                    result = encoded.substring(0, num);

            } else {

                    result = encoded.substring(0, 32);

            }

            return result;

    }



    /**

    * 数値を指定の桁で0埋めする

    * @param num   処理対象数値

    * @param digit 桁数

    * @return              0埋め後文字列

    */

    public static String padZero(int num, int digit) {

            return String.format("%0" + digit +"d", num);

    }



    /**

    * 指定の桁までスペース埋めする

    * @param str   処理対象文字列

    * @param digit 桁数

    * @return              スペース埋め後文字列

    */

    public static String padSpace(String str, int digit) {

            return String.format("%" + digit +"s", str);

    }



    /**

    * 数字の頭の0を除去する

    * @param str   処理対象文字列

    * @return              0除去後文字列

    */

    public static String ltrimZero(String str) {

            return str.replaceFirst("^0+", "");

    }



    /**

    * 文字列の頭のスペースを除去する

    * @param str   処理対象文字列

    * @return              スペース除去後文字列

    */

    public static String ltrim(String str) {

            return str.replaceFirst("^ +", "");

    }



    /**

    * 文字列の後ろのスペースを除去する

    * @param str   処理対象文字列

    * @return              スペース除去後文字列

    */

    public static String rtrim(String str) {

            return str.replaceFirst(" +$", "");

    }



    /**

    * JSON文字列からMapを生成

    * @param json  JSON文字列

    * @return              Map

    */

    public static Map<String, String> createMapFromJson(String json) {

            Gson gson = new Gson();

            Type listType = new TypeToken<HashMap<String, String>>() { }. getType();

    HashMap<String, String> map = gson.fromJson(json, listType);

    return map;

    }



    /**

    * MapからJSON文字列を生成

    * @param map   Map

    * @return              JSON文字列

    */

    public static String createJsonFromMap(Map<String, String> map) {

            Gson gson = new Gson();

            return gson.toJson(map);

    }



    /**

    * パラメータ1がnullの場合はパラメータ2を返す(SQLのNVLと同じ)

    * @param val1  検査対象文字列

    * @param val2  パラメータ1がnullの時に返す文字列

    * @return              判定後パラメータ1OR2

    */

    public static String nvl(String val1, String val2) {

            if (val1 == null) {

                    return val2;

            } else {

                    return val1;

            }

    }

}

2017年6月23日金曜日

Javaで日付関連の自作ユーティリティ

(2017/06/23)


public class DateUtil {


    /**

    * システム日付を返す

    * @return システム日付

    */

    public static java.util.Date getToday() {

        return new java.util.Date(System.currentTimeMillis());

    }

 

    /**

    * システム日付を返す(SQL)

    * @return システム日付

    */

    public static java.sql.Date getTodaySql() {

        return new java.sql.Date(System.currentTimeMillis());

    }

 

    /**

    * パラメータのDateに日数を加算

    * @param date      対象日付

    * @param add_days      加算日数

    * @return              計算後の日付

    */

    public static java.util.Date addDay(java.util.Date date, int add_days) {

        Calendar cal = Calendar.getInstance();

        cal.setTime(date);

        cal.add(Calendar.DATE, add_days);

 

        return new java.util.Date(cal.getTimeInMillis());

    }

 

    /**

    * パラメータのDateに日数を加算(SQL)

    * @param date      対象日付

    * @param add_days      加算日数

    * @return              計算後の日付

    */

    public static java.sql.Date addDaySql(java.sql.Date date, int add_days) {

        Calendar cal = Calendar.getInstance();

        cal.setTime(date);

        cal.add(Calendar.DATE, add_days);

 

        return new java.sql.Date(cal.getTimeInMillis());

    }

 

    /**

    * パラメータのDateに月を加算

    * @param date          対象日付

    * @param add_months    加算月数

    * @return                  計算後の日付

    */

    public static java.util.Date addMonth(java.util.Date date, int add_months) {

        Calendar cal = Calendar.getInstance();

        cal.setTime(date);

        cal.add(Calendar.MONTH, add_months);

 

        return new java.util.Date(cal.getTimeInMillis());

    }

 

    /**

    * パラメータのDateに月を加算(SQL)

    * @param date          対象日付

    * @param add_months    加算月数

    * @return                  計算後の日付

    */

    public static java.sql.Date addMonthSql(java.sql.Date date, int add_months) {

        Calendar cal = Calendar.getInstance();

        cal.setTime(date);

        cal.add(Calendar.MONTH, add_months);

 

        return new java.sql.Date(cal.getTimeInMillis());

    }

 

    /**

    * パラメータのDateに年を加算

    * @param date          対象日付

    * @param add_months    加算年数

    * @return                  計算後の日付

    */

    public static java.util.Date addYear(java.util.Date date, int add_years) {

        Calendar cal = Calendar.getInstance();

        cal.setTime(date);

        cal.add(Calendar.YEAR, add_years);

 

        return new java.util.Date(cal.getTimeInMillis());

    }

 

    /**

    * パラメータのDateに年を加算(SQL)

    * @param date          対象日付

    * @param add_months    加算年数

    * @return                  計算後の日付

    */

    public static java.sql.Date addYearSql(java.sql.Date date, int add_years) {

        Calendar cal = Calendar.getInstance();

        cal.setTime(date);

        cal.add(Calendar.YEAR, add_years);

 

        return new java.sql.Date(cal.getTimeInMillis());

    }

 

    /**

    * パラメータのDateをYYYY/MM/DDのフォーマットにして返す

    * @param date 対象日付

    * @return 変換後の日付文字列

    */

    public static String formateYyyyMmDd(java.util.Date date) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");

        return sdf.format(date);

    }

 

    /**

    * パラメータのDateをYYYY/MM/DDのフォーマットにして返す(SQL)

    * @param date 対象日付

    * @return 変換後の日付文字列

    */

    public static String formateYyyyMmDdSql(java.sql.Date date) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");

        return sdf.format(date);

    }

 

    /**

    * パラメータのDateをYYYY/MMのフォーマットにして返す

    * @param date 対象日付

    * @return 変換後の日付文字列

    */

    public static String formateYyyyMm(java.util.Date date) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM");

        return sdf.format(date);

    }

 

    /**

    * パラメータのDateをYYYY/MMのフォーマットにして返す(SQL)

    * @param date 対象日付

    * @return 変換後の日付文字列

    */

    public static String formateYyyyMmSql(java.sql.Date date) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM");

        return sdf.format(date);

    }

 

    /**

    * システム日時をYYYYMMDDHHMMのフォーマットにして返す

    * @return 変換後の日時文字列

    */

    public static String getTodayYyyyMmDdHhMm() {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm");

 

        java.sql.Timestamp ts = new java.sql.Timestamp(System.currentTimeMillis());

 

        return sdf.format(ts);

    }

 

    /**

    * システム日付をyyyy-MM-dd HH:mm:ssのフォーマットにして返す

    * @return 変換後の日付文字列

    */

    public static String getTodayYyyyMmDdHhMmSs() {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

 

        java.sql.Timestamp ts = new java.sql.Timestamp(System.currentTimeMillis());

 

        return sdf.format(ts);

    }

 

    /**

    * システム日付をYYYYMMDDのフォーマットにして返す

    * @return 変換後の日付文字列

    */

    public static String getTodayYyyyMmDd() {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

 

        java.sql.Timestamp ts = new java.sql.Timestamp(System.currentTimeMillis());

 

        return sdf.format(ts);

    }

 

    /**

    * システム日付をYYYY/MM/DDのフォーマットにして返す

    * @return 変換後の日付文字列

    */

    public static String getTodayYyyyMmDdWithSlash() {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");

 

        java.sql.Timestamp ts = new java.sql.Timestamp(System.currentTimeMillis());

 

        return sdf.format(ts);

    }

 

 

    /**

    * YYYY-MM-DD(もしくはYYYY/MM/DD)形式の文字列をDateにして返す(java.util.Date 版)

    * @param str_date

    * @return

    */

    public static java.util.Date convertStringToDate(String str_date) {

        // YYYY/MM/DD形式の場合はフォーマットを変更してから処理

        if (str_date.indexOf("/") > -1) {

            str_date = str_date.replaceAll("/", "-");

        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

 

        java.util.Date result = null;

        try {

            result = sdf.parse(str_date);

        } catch (ParseException e) {

            e.printStackTrace();

        }

        return result;

    }

 

    /**

    * YYYY-MM-DD(もしくはYYYY/MM/DD)形式の文字列をDateにして返す(SQL)

    * @param str_date

    * @return

    */

    public static java.sql.Date convertStringToDateSql(String str_date) {

        // YYYY/MM/DD形式の場合はフォーマットを変更してから処理

        if (str_date.indexOf("/") > -1) {

            str_date = str_date.replaceAll("/", "-");

        }

 

        return java.sql.Date.valueOf(str_date);

    }

 

}