001/* 002 * Copyright (c) 2009 The openGion Project. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 013 * either express or implied. See the License for the specific language 014 * governing permissions and limitations under the License. 015 */ 016package org.opengion.fukurou.util; 017 018import java.io.FileInputStream; 019import java.io.FileOutputStream; 020 021// import java.util.Date; 022// import java.util.Locale; 023// import java.text.DateFormat; 024// import java.text.SimpleDateFormat; 025 026/** 027 * DateSet.java は、入力ファイルの日付,時刻キーワードを実行時の日時で変換して,出力します。 028 * 029 * 変換には,$(yyyy)の形式で指定し,カッコの文字列は,java.text.SimpleDateFormat で使用する, 030 * 時刻フォーマット構文を用います。 031 * また、引数に keys,vals を渡すことで、$(KEY1) 文字列を VAL1 文字列と置き換えます。 032 * 033 * サンプルファイル 034 * $(yyyy/MM/dd) 年/月/日を表します。 035 * $(yy) 年だけを2桁で表します。 036 * $(MM) 月を2桁 (02,03など)で表します。 037 * $(dd) 日を2桁 (02,03など)で表します。 038 * $(HH:mm:ss) 時:分:秒を表します。 039 * $(MMMMMMMM) 月をフルスペルで表します。 040 * $(MMM) 月を3桁固定(Mar,Aplなど)で表します。 041 * $(EEEEEEEE) 曜日をフルスペルで表します。 042 * $(EEE) 曜日を3桁固定(Sun,Monなど)で表します。 043 * 044 * 時刻フォーマット構文 045 * 046 * 記号 意味 表示 例 047 * ------ ------- ------------ ------- 048 * G 年号 (テキスト) AD 049 * y 年 (数値) 1996 050 * M 月 (テキスト & 数値) July & 07 051 * d 日 (数値) 10 052 * h 午前/午後の時 (1~12) (数値) 12 053 * H 一日における時 (0~23) (数値) 0 054 * m 分 (数値) 30 055 * s 秒 (数値) 55 056 * S ミリ秒 (数値) 978 057 * E 曜日 (テキスト) 火曜日 058 * D 年における日 (数値) 189 059 * F 月における曜日 (数値) 2 (7月の第2水曜日) 060 * w 年における週 (数値) 27 061 * W 月における週 (数値) 2 062 * a 午前/午後 (テキスト) PM 063 * k 一日における時 (1~24) (数値) 24 064 * K 午前/午後の時 (0~11) (数値) 0 065 * z 時間帯 (テキスト) PDT 066 * ' テキスト用エスケープ 067 * '' 単一引用符 ' 068 * 069 * パターン文字のカウントによって、そのフォーマットが決まります。 070 * (テキスト): 4以上: フル形式を使用します。4以下: 短いまたは省力された形式があれば、それを使用します。 071 * 072 * (数値): 最小桁数。これより短い数値は、この桁数までゼロが追加されます。年には特別な処理があります。 073 * つまり、'y'のカウントが2なら、年は2桁に短縮されます。 074 * 075 * (テキスト & 数値): 3以上ならテキストを、それ以外なら数値を使用します。 076 * 077 * パターンの文字が['a'..'z']と['A'..'Z']の範囲になければ、その文字は引用テキストとして扱われます。 078 * たとえば、':'、'.'、' '、'#'、'@'などの文字は、単一引用符に囲まれていなくても、 079 * 結果の時刻テキストに使用されます。 080 * 081 * 無効なパターン文字がパターンに入っていると、フォーマットや解析で例外がスローされます。 082 * 083 * USロケールを使った例: 084 * 085 * フォーマットパターン 結果 086 * -------------------- ---- 087 * "yyyy.MM.dd G 'at' hh:mm:ss z" ⇒ 1996.07.10 AD at 15:08:56 PDT 088 * "EEE, MMM d, ''yy" ⇒ Wed, July 10, '96 089 * "h:mm a" ⇒ 12:08 PM 090 * "hh 'o''''clock' a, zzzz" ⇒ 12 o'clock PM, Pacific Daylight Time 091 * "K:mm a, z" ⇒ 0:00 PM, PST 092 * "yyyyy.MMMMM.dd GGG hh:mm aaa" ⇒ 1996.July.10 AD 12:08 PM 093 * 094 * @version 0.9.0 1999/03/09 095 * @author Kazuhiko Hasegawa 096 * @since JDK1.1, 097 */ 098public class DateSet { 099 private String[] keys = null; 100 private String[] vals = null; 101 102 /** 103 * フォーマット解析時に置き換える キーと値の配列を設定します。 104 * 105 * $(KEY1) 文字列を VAL1 文字列と置き換える処理を行います。これにより日付以外の 106 * 文字列を置き換える処理を実行できます。 107 * 108 * @param inkeys 置き換え元キー配列 109 * @param invals 置き換え元値配列 110 */ 111 public void setKeysVals( final String[] inkeys, final String[] invals ) { 112 if( inkeys != null && invals != null && inkeys.length == invals.length ) { 113 int size = inkeys.length ; 114 keys = new String[size]; 115 vals = new String[size]; 116 System.arraycopy( inkeys,0,keys,0,size ); 117 System.arraycopy( invals,0,vals,0,size ); 118 } 119 } 120 121 /** 122 * 現在日付、時刻をフォーマット指定個所に埋め込みます。 123 * フォーマットの指定方法は、java.text.SimpleDateFormat の指定方法と同一です。 124 * 125 * @param inByte 変換元バイト配列 126 * 127 * @return 変換後のバイト配列 128 */ 129 public byte[] change( final byte[] inByte ) { 130 byte[] outByte = new byte[ inByte.length+100 ]; 131 int add = 0; 132 for( int i=0; i<inByte.length; i++) { 133 if( inByte[i] == '$' && i<inByte.length-1 && inByte[i+1] == '(' ) { 134 int j = 0; 135 while( inByte[i+j+2] != ')') { j++; } 136// String str = changeForm( new String( inByte,i+2,j ) ); 137// byte[] byteDate = str.getBytes() ; 138 String str = changeForm( new String( inByte,i+2,j,StringUtil.DEFAULT_CHARSET ) ); // 5.5.2.6 (2012/05/25) findbugs対応 139 byte[] byteDate = str.getBytes( StringUtil.DEFAULT_CHARSET ) ; // 5.5.2.6 (2012/05/25) findbugs対応 140 for( int k = 0; k<byteDate.length; k++) { 141 outByte[add] = byteDate[k]; 142 add++; 143 } 144 i += j+2; 145 } 146 else { 147 outByte[add] = inByte[i]; 148 add++; 149 } 150 } 151 byte[] rtnByte = new byte[ add ]; 152 System.arraycopy( outByte,0,rtnByte,0,add ); 153 return rtnByte; 154 } 155 156 /** 157 * keys,vals の変換、および、現在日付、時刻のフォーマット変換を行います。 158 * 159 * 先に、keys,vals の変換を行います。form が、keys にマッチすれば、vals を 160 * 返します。最後までマッチしなければ、時刻のフォーマット変換を行います。 161 * フォーマットの指定方法は、java.text.SimpleDateFormat の指定方法と同一です。 162 * 163 * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します。 164 * 165 * @param form フォーム文字列 ( 例 "yyyy/MM/dd HH:mm:ss" ) 166 * 167 * @return フォーマット変換結果 168 */ 169 public String changeForm( final String form ) { 170 if( keys != null ) { 171 for( int i=0; i<keys.length; i++ ) { 172 if( form.equals( keys[i] ) ) { 173 return vals[i]; 174 } 175 } 176 } 177 178// DateFormat formatter = new SimpleDateFormat( form, Locale.JAPAN ); 179// return formatter.format(new Date()); 180 181 return HybsDateUtil.getDate( form ); 182 } 183 184 /** 185 * keys,vals の変換、および、現在日付、時刻のフォーマット変換を行います。 186 * 187 * 先に、keys,vals の変換を行います。form が、keys にマッチすれば、vals を 188 * 返します。最後までマッチしなければ、時刻のフォーマット変換を行います。 189 * フォーマットの指定方法は、java.text.SimpleDateFormat の指定方法と同一です。 190 * 191 * @param form フォーム文字列 ( 例 "yyyy/MM/dd HH:mm:ss" ) 192 * 193 * @return フォーマット変換結果 194 */ 195 public String changeString( final String form ) { 196 StringBuilder buf = new StringBuilder( 200 ); 197 int bkst = 0; 198 int st = form.indexOf( "$(" ); 199 while( st >= 0 ) { 200 buf.append( form.substring( bkst,st ) ); 201 int ed = form.indexOf( ")",st+2 ); 202 buf.append( changeForm( form.substring( st+2,ed ) ) ); 203 bkst = ed + 1; 204 st = form.indexOf( "$(",bkst ); 205 } 206 buf.append( form.substring( bkst ) ); 207 208 return buf.toString(); 209 } 210 211 /** 212 * 現在日付、時刻をフォーマットを指定して、所得します。 213 * フォーマットの指定方法は、java.text.SimpleDateFormat の指定方法と同一です。 214 * 215 * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するため、削除。 216 * 217 * @param form フォーム文字列 ( 例 "yyyy/MM/dd HH:mm:ss" ) 218 * 219 * @return 現在日付、時刻 220 */ 221// public static String getDate( final String form ) { 222// DateFormat formatter = new SimpleDateFormat( form, Locale.JAPAN ); 223// return formatter.format(new Date()); 224// } 225 226 /** 227 * 入力ファイルの時刻フォーマットを変換して出力ファイルに書き込みます。 228 * 229 * 引数に <key1> <val1> のペア情報を渡すことが可能です。 230 * 先に、keys,vals の変換を行います。form が、keys にマッチすれば、vals を 231 * 返します。最後までマッチしなければ、時刻のフォーマット変換を行います。 232 * フォーマットの指定方法は、java.text.SimpleDateFormat の指定方法と同一です。 233 * フォーム文字列例 ( "yyyy/MM/dd HH:mm:ss" ) 234 * 235 * @param args 引数配列( 入力ファイル 出力ファイル キー1 値1 ・・・ 236 * @throws Throwable なんらかのエラーが発生した場合。 237 */ 238 public static void main( final String[] args ) throws Throwable { 239 if( args.length > 2 && ( args.length % 2 != 0 ) ) { 240// LogWriter.log("Usage: java DateSet <inputFile> <outputFile> [<key1> <val1> ・・・]" ); 241 System.err.println( "Usage: java DateSet <inputFile> <outputFile> [<key1> <val1> ・・・]" ); 242 return ; 243 } 244 245 String[] keys = new String[ (args.length-2)/2 ]; 246 String[] vals = new String[ (args.length-2)/2 ]; 247 for( int i=1; i<=keys.length; i++ ) { 248 keys[i-1] = args[i*2]; 249 vals[i-1] = args[i*2+1]; 250 } 251 252 FileInputStream filein = new FileInputStream( args[0] ); 253 byte[] byteIn = new byte[ filein.available() ]; 254 int len = filein.read( byteIn ); 255 if( len != byteIn.length ) { 256 String errMsg = "読み取りファイルのデータが切り捨てられました。" + 257 "File=" + args[0] + " Length=" + len + " Input=" + byteIn.length ; 258// LogWriter.log( errMsg ); 259 System.err.println( errMsg ); 260 } 261 filein.close(); 262 263 DateSet dateSet = new DateSet(); 264 dateSet.setKeysVals( keys,vals ); 265 byte[] byteout = dateSet.change( byteIn ); 266 267 FileOutputStream fileout = new FileOutputStream( args[1] ); 268 fileout.write( byteout ); 269 fileout.close(); 270 } 271}