2 * Copyright (c) 2009 The openGion Project.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13 * either express or implied. See the License for the specific language
14 * governing permissions and limitations under the License.
16 package org.opengion.fukurou.system; // 6.4.2.0 (2016/01/29) package変更 fukurou.util → fukurou.system
18 import java.io.FileInputStream;
19 import java.io.FileOutputStream;
20 import java.util.Date;
21 import java.util.Locale;
22 // import java.util.Calendar; // 7.0.1.4 (2018/11/26)
23 import java.util.concurrent.ConcurrentMap; // 7.0.1.3 (2018/11/12)
24 import java.util.concurrent.ConcurrentHashMap; // 7.0.1.3 (2018/11/12)
25 import java.text.DateFormat;
26 import java.text.SimpleDateFormat;
28 // import static org.opengion.fukurou.system.HybsConst.BUFFER_MIDDLE; // 6.1.0.0 (2014/12/26) refactoring
31 * DateSet.java は、入力ファイルの日付、時刻キーワードを実行時の日時で変換して出力します。
33 * 変換には、$(yyyy)の形式で指定し、カッコの文字列は java.text.SimpleDateFormat で使用する
35 * また、引数に keys,vals を渡すことで、$(KEY1) 文字列を VAL1 文字列と置き換えます。
38 * $(yyyy/MM/dd) 年/月/日を表します。
40 * $(MM) 月を2桁 (02,03など)で表します。
41 * $(dd) 日を2桁 (02,03など)で表します。
42 * $(HH:mm:ss) 時:分:秒を表します。
43 * $(MMMMMMMM) 月をフルスペルで表します。
44 * $(MMM) 月を3桁固定(Mar,Aplなど)で表します。
45 * $(EEEEEEEE) 曜日をフルスペルで表します。
46 * $(EEE) 曜日を3桁固定(Sun,Monなど)で表します。
48 * // 7.0.1.3 (2018/11/12) 2019/01/01 2030/01/01
49 * $(ATIME) 通算秒数( new Date().getTime()/1000 ) の 10桁文字列 1546268400 1893423600
50 * $(BTIME) 通算分数( new Date().getTime()/60000 ) の 8桁文字列 25771140 31557060
51 * ※ BTIME が桁あふれするのは、2160/02/18 です。
56 * ------ ------- ------------ -------
59 * M 月 (テキスト & 数値) July & 07
61 * h 午前/午後の時 (1~12) (数値) 12
62 * H 一日における時 (0~23) (数値) 0
68 * F 月における曜日 (数値) 2 (7月の第2水曜日)
72 * k 一日における時 (1~24) (数値) 24
73 * K 午前/午後の時 (0~11) (数値) 0
78 * パターン文字のカウントによって、そのフォーマットが決まります。
79 * (テキスト): 4以上: フル形式を使用します。4以下: 短いまたは省力された形式があれば、それを使用します。
81 * (数値): 最小桁数。これより短い数値は、この桁数までゼロが追加されます。年には特別な処理があります。
82 * つまり、'y'のカウントが2なら、年は2桁に短縮されます。
84 * (テキスト & 数値): 3以上ならテキストを、それ以外なら数値を使用します。
86 * パターンの文字が['a'..'z']と['A'..'Z']の範囲になければ、その文字は引用テキストとして扱われます。
87 * たとえば、':'、'.'、' '、'#'、'@'などの文字は、単一引用符に囲まれていなくても、
90 * 無効なパターン文字がパターンに入っていると、フォーマットや解析で例外がスローされます。
95 * -------------------- ----
96 * "yyyy.MM.dd G 'at' hh:mm:ss z" ⇒ 1996.07.10 AD at 15:08:56 PDT
97 * "EEE, MMM d, ''yy" ⇒ Wed, July 10, '96
99 * "hh 'o''''clock' a, zzzz" ⇒ 12 o'clock PM, Pacific Daylight Time
100 * "K:mm a, z" ⇒ 0:00 PM, PST
101 * "yyyyy.MMMMM.dd GGG hh:mm aaa" ⇒ 1996.July.10 AD 12:08 PM
103 * @og.rev 6.4.2.0 (2016/01/29) package変更 fukurou.util → fukurou.system
104 * @og.rev 7.0.1.3 (2018/11/12) keys,valsをMapに変更。BUILD_TYPEのビルド番号を100秒単位に変更。
106 * @version 0.9.0 1999/03/09
107 * @author Kazuhiko Hasegawa
110 public class DateSet {
111 private final ConcurrentMap<String,String> prmMap = new ConcurrentHashMap<>(); // 7.0.1.3 (2018/11/12)
113 // private String[] keys ;
114 // private String[] vals ;
121 * @og.rev 7.0.1.3 (2018/11/12) KeysValsは、Mapに置き換え
122 * @og.rev 7.0.1.4 (2018/11/26) ATIME,BTIME 追加
125 prmMap.put( "ATIME" , Long.toString( new Date().getTime()/1000 ) ); //
126 prmMap.put( "BTIME" , Long.toString( new Date().getTime()/60000 ) ); //
128 // final Calendar now = Calendar.getInstance();
129 // final int tm = ( now.get( Calendar.HOUR_OF_DAY ) * 60 + now.get( Calendar.MINUTE ) ) / 15 ; // 0 ~ 96未満の数値になる
131 // final String CTIME = getDate( "yyDDD" ) + String.format( "%02d" , tm ) ;
132 // prmMap.put( "CTIME" , CTIME );
136 * フォーマット解析時に置き換える キーと値のMapを設定します。
138 * $(KEY1) 文字列を VAL1 文字列と置き換える処理を行います。これにより日付以外の
139 * 文字列を置き換える処理を実行できます。
141 * @og.rev 7.0.1.3 (2018/11/12) KeysValsは、Mapに置き換え
143 * @param pMap 置き換え元のMap
145 public void setParamMap( final ConcurrentMap<String,String> pMap ) {
147 prmMap.putAll( pMap );
152 // * フォーマット解析時に置き換える キーと値の配列を設定します。
154 // * $(KEY1) 文字列を VAL1 文字列と置き換える処理を行います。これにより日付以外の
155 // * 文字列を置き換える処理を実行できます。
157 // * @og.rev 7.0.1.3 (2018/11/12) KeysValsは、Mapに置き換え
159 // * @param inkeys 置き換え元キー配列
160 // * @param invals 置き換え元値配列
162 // public void setKeysVals( final String[] inkeys, final String[] invals ) {
163 // if( inkeys != null && invals != null && inkeys.length == invals.length ) {
164 // final int size = inkeys.length ;
165 // keys = new String[size];
166 // vals = new String[size];
167 // System.arraycopy( inkeys,0,keys,0,size );
168 // System.arraycopy( invals,0,vals,0,size );
173 * 現在日付、時刻をフォーマット指定個所に埋め込みます。
174 * フォーマットの指定方法は、java.text.SimpleDateFormat の指定方法と同一です。
176 * @og.rev 6.3.6.0 (2015/08/16) System.arraycopy が使える箇所は、置き換えます。
177 * @og.rev 6.4.2.0 (2016/01/29) fukurou.util.StringUtil → fukurou.system.HybsConst に変更
179 * @param inByte 変換元バイト配列(可変長引数)
182 public byte[] change( final byte... inByte ) {
183 byte[] outByte = new byte[inByte.length+100];
185 for( int i=0; i<inByte.length; i++ ) {
186 if( inByte[i] == '$' && i<inByte.length-1 && inByte[i+1] == '(' ) {
188 while( inByte[i+j+2] != ')') { j++; }
189 final String str = changeForm( new String( inByte,i+2,j,HybsConst.DEFAULT_CHARSET ) ); // 6.4.2.0 (2016/01/29)
190 final byte[] byteDate = str.getBytes( HybsConst.DEFAULT_CHARSET ) ; // 6.4.2.0 (2016/01/29)
191 // 6.3.6.0 (2015/08/16) System.arraycopy が使える箇所は、置き換えます。
192 System.arraycopy( byteDate,0,outByte,add,byteDate.length ); // 6.3.6.0 (2015/08/16)
193 add += byteDate.length ; // 6.3.6.0 (2015/08/16)
197 outByte[add] = inByte[i];
201 final byte[] rtnByte = new byte[add];
202 System.arraycopy( outByte,0,rtnByte,0,add );
207 * パラメータの変換、および、現在日付、時刻のフォーマット変換を行います。
209 * 先に、パラメータの変換を行います。form が、Mapのkey にマッチすれば、
210 * その値を返します。マッチしなければ、時刻のフォーマット変換を行います。
211 * フォーマットの指定方法は、java.text.SimpleDateFormat の指定方法と同一です。
213 * @og.rev 5.5.7.2 (2012/10/09) HybsDateUtil を利用するように修正します。
214 * @og.rev 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
215 * @og.rev 7.0.1.3 (2018/11/12) KeysValsは、Mapに置き換え
217 * @param form フォーム文字列 ( 例 "yyyy/MM/dd HH:mm:ss" )
221 public String changeForm( final String form ) {
222 // Map#getOrDefault( key,defVal )はdefValも評価が必ず実行されるため、使えない。
223 // return prmMap.getOrDefault( form,DateSet.getDate( form ) ;
225 final String rtn = prmMap.get( form );
227 return rtn == null ? DateSet.getDate( form ) : rtn ;
229 // // 6.3.9.0 (2015/11/06) コンストラクタで初期化されていないフィールドを null チェックなしで利用している(findbugs)
230 // if( keys != null && vals != null ) {
231 // for( int i=0; i<keys.length; i++ ) {
232 // if( form.equals( keys[i] ) ) {
238 // return DateSet.getDate( form );
242 * パラメータの変換、および、現在日付、時刻のフォーマット変換を行います。
244 * 先に、パラメータの変換を行います。form が、Mapのkey にマッチすれば、
245 * その値を返します。マッチしなければ、時刻のフォーマット変換を行います。
246 * フォーマットの指定方法は、java.text.SimpleDateFormat の指定方法と同一です。
248 * @param form フォーム文字列 ( 例 "yyyy/MM/dd HH:mm:ss" )
253 public String changeString( final String form ) {
254 final StringBuilder buf = new StringBuilder( HybsConst.BUFFER_MIDDLE );
256 int st = form.indexOf( "$(" );
258 buf.append( form.substring( bkst,st ) );
259 final int ed = form.indexOf( ')',st+2 ); // 6.0.2.5 (2014/10/31) refactoring
260 buf.append( changeForm( form.substring( st+2,ed ) ) );
262 st = form.indexOf( "$(",bkst );
264 buf.append( form.substring( bkst ) );
266 return buf.toString();
270 * 現在日付、時刻を指定のフォーマットで文字列に変換して返します。
271 * 出力フォーマットは、"yyyy/MM/dd HH:mm:ss" 固定です。
273 * @og.rev 5.5.7.2 (2012/10/09) 新規作成
274 * @og.rev 6.4.2.0 (2016/01/29) fukurou.util.HybsDateUtil → fukurou.system.DateSet に変更
276 * @return 現在日付、時刻 ( 例 2012/09/05 18:10:24 )
279 public static String getDate() {
280 final DateFormat formatter = new SimpleDateFormat( "yyyy/MM/dd HH:mm:ss",Locale.JAPAN );
281 return formatter.format( new Date() );
285 * 現在時刻を指定のフォーマットで文字列に変換して返します。
286 * フォーマットの指定方法は、java.text.SimpleDateFormat の指定方法と同一です。
287 * 変換時のロケーションは、Locale.JAPAN です。
288 * 現在時刻は、new Date() で求めます。
290 * @param form フォーム文字列 ( 例 "yyyy/MM/dd HH:mm:ss.SSS" )
292 * @og.rev 5.5.7.2 (2012/10/09) 新規作成
293 * @og.rev 6.4.2.0 (2016/01/29) fukurou.util.HybsDateUtil → fukurou.system.DateSet に変更
297 * @see java.text.SimpleDateFormat
299 public static String getDate( final String form ) {
300 final DateFormat formatter = new SimpleDateFormat( form,Locale.JAPAN );
301 return formatter.format( new Date() );
305 * 指定時刻を指定のフォーマットで文字列に変換して返します。
306 * フォーマットの指定方法は、java.text.SimpleDateFormat の指定方法と同一です。
307 * 変換時のロケーションは、Locale.JAPAN です。
308 * 指定時刻は、new Date( time ) で求めます。
310 * @param time 指定のカレントタイムのロング値
311 * @param form フォーム文字列 ( 例 "yyyy/MM/dd HH:mm:ss.SSS" )
313 * @og.rev 5.5.7.2 (2012/10/09) 新規作成
314 * @og.rev 6.4.2.0 (2016/01/29) fukurou.util.HybsDateUtil → fukurou.system.DateSet に変更
316 * @return 現在日付、時刻( 例 2001/04/17 15:48:22 )
319 public static String getDate( final long time,final String form ) {
320 final DateFormat formatter = new SimpleDateFormat( form,Locale.JAPAN );
321 return formatter.format( new Date( time ) );
325 * 入力ファイルの時刻フォーマットを変換して出力ファイルに書き込みます。
327 * 引数に <key1> <val1> のペア情報を渡すことが可能です。
328 * 先に、keys,vals の変換を行います。form が、keys にマッチすれば、vals を
329 * 返します。最後までマッチしなければ、時刻のフォーマット変換を行います。
330 * フォーマットの指定方法は、java.text.SimpleDateFormat の指定方法と同一です。
331 * フォーム文字列例 ( "yyyy/MM/dd HH:mm:ss" )
333 * @og.rev 7.0.1.3 (2018/11/12) KeysValsは、Mapに置き換え
335 * @param args 引数配列( 入力ファイル 出力ファイル キー1 値1 ・・・
336 * @throws Throwable なんらかのエラーが発生した場合。
338 public static void main( final String[] args ) throws Throwable {
339 if( args.length > 2 && ( args.length % 2 != 0 ) ) {
340 System.err.println( "Usage: java org.opengion.fukurou.system.DateSet <inputFile> <outputFile> [<key1> <val1> ・・・]" );
344 final ConcurrentMap<String,String> prmMap = new ConcurrentHashMap<>(); // 7.0.1.3 (2018/11/12)
346 for( int i=2; i<args.length; i+=2 ) {
347 prmMap.put( args[i] , args[i+1] );
350 // String[] keys = new String[ (args.length-2)/2 ];
351 // String[] vals = new String[ (args.length-2)/2 ];
352 // for( int i=1; i<=keys.length; i++ ) {
353 // keys[i-1] = args[i*2];
354 // vals[i-1] = args[i*2+1];
357 final FileInputStream filein = new FileInputStream( args[0] );
358 final byte[] byteIn = new byte[ filein.available() ];
359 final int len = filein.read( byteIn );
360 if( len != byteIn.length ) {
361 final String errMsg = "読み取りファイルのデータが切り捨てられました。" +
362 "File=" + args[0] + " Length=" + len + " Input=" + byteIn.length ;
363 System.err.println( errMsg );
367 final DateSet dateSet = new DateSet();
368 // dateSet.setKeysVals( keys,vals );
369 dateSet.setParamMap( prmMap );
370 final byte[] byteout = dateSet.change( byteIn );
372 final FileOutputStream fileout = new FileOutputStream( args[1] );
373 fileout.write( byteout );