ConditionDateFormatter.java
package com.github.mygreen.cellformatter;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.CopyOnWriteArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.mygreen.cellformatter.callback.Callback;
import com.github.mygreen.cellformatter.lang.ArgUtils;
import com.github.mygreen.cellformatter.lang.ExcelDateUtils;
import com.github.mygreen.cellformatter.term.DateTerm;
import com.github.mygreen.cellformatter.term.Term;
/**
* ユーザ定義型の日時を解釈するフォーマッタ
*
* @version 0.10
* @author T.TSUCHIE
*
*/
public class ConditionDateFormatter extends ConditionFormatter {
private static final Logger logger = LoggerFactory.getLogger(ConditionDateFormatter.class);
/**
* 日時の各項
*/
private List<Term<Calendar>> terms = new CopyOnWriteArrayList<>();
public ConditionDateFormatter(final String pattern) {
super(pattern);
}
@Override
public FormatterType getType() {
return FormatterType.Date;
}
/**
* 値が条件に一致するかどうか。
* <p>Excelの1900年1月1日を基準に、ミリ秒に直して判定する。
* @param cell
* @return
*/
@Override
public boolean isMatch(final CommonCell cell) {
if(!cell.isNumber()) {
return false;
}
final long zeroTime = ExcelDateUtils.getExcelZeroDateTime(cell.isDateStart1904());
final Date date = cell.getDateCellValue();
final long value = date.getTime() - zeroTime;
if(logger.isDebugEnabled()) {
logger.debug("isMatch::date={}, zeroTime={}, diff={}",
ExcelDateUtils.formatDate(date), ExcelDateUtils.formatDate(new Date(zeroTime)), value);
}
return getOperator().isMatch(value);
}
@Override
public CellFormatResult format(final CommonCell cell, final Locale runtimeLocale) {
ArgUtils.notNull(cell, "date");
final Date date = cell.getDateCellValue();
final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT-00:00"));
cal.setTime(date);
// 各項の処理
StringBuilder sb = new StringBuilder();
for(Term<Calendar> term : terms) {
final String formatValue;
if(term instanceof DateTerm) {
formatValue = ((DateTerm) term).format(cal, getLocale(), runtimeLocale, cell.isDateStart1904());
} else {
formatValue = term.format(cal, getLocale(), runtimeLocale);
}
sb.append(applyFormatCallback(cal, formatValue, runtimeLocale, term));
}
String value = sb.toString();
final CellFormatResult result = new CellFormatResult();
result.setValue(date);
result.setText(value);
result.setTextColor(getColor());
result.setSectionPattern(getPattern());
result.setCellType(FormatCellType.Date);
return result;
}
@SuppressWarnings({"rawtypes", "unchecked"})
private String applyFormatCallback(final Calendar cal, final String str, final Locale runtimeLocale, Term<Calendar> term) {
String value = str;
for(Callback callback : getCallbacks()) {
final Locale locale;
if(getLocale() != null) {
locale = getLocale().getLocale();
} else {
locale = runtimeLocale;
}
if(!callback.isApplicable(locale)) {
continue;
}
value = callback.call(cal, value, locale, term);
}
return value;
}
/**
* フォーマットの項を追加する。
* @param term
*/
public void addTerm(final Term<Calendar> term) {
this.terms.add(term);
}
/**
* フォーマットの複数の項を追加する。
* @param terms
*/
public void addAllTerms(final List<Term<Calendar>> terms) {
this.terms.addAll(terms);
}
/**
* フォーマットの項を全て取得する。
* @return
*/
public List<Term<Calendar>> getTerms() {
return terms;
}
}