/**
 * Copyright (c) 2003-2004 System Integrator Corporation.
 *                 All Rights Reserved.
 */
package jp.co.sint.tools;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;

import jp.co.sint.basic.SINameValue;
import jp.co.sint.config.SIConfig;

import org.apache.log4j.Category;

/**
 * @version $Id: SIDateTime.java,v 1.0 2003/07/25 jwchen Exp $
 * @author  Jinwang Chen
 * <br>Description: 日付と時刻の関連のutilitiesのクラス
 * <p>History</p>
 * <p>Author&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Reason</p>
 * ============&nbsp;&nbsp;&nbsp;==========&nbsp;&nbsp;===========================<br>
 * J.W.Chen       2003/07/25  Original
 */

public class SIDateTime{
  //ログ用のインスタンスの生成
  private static Category log=Category.getInstance(SIConfig.SILOG4J_WEBSHOP_CATEGORY_NAME);
  //日付
  private GregorianCalendar currDateTime;
  //年
  private int year;
  //月
  private int month;
  //日
  private int day;
  //時間
  private int hour;
  //分
  private int minute;
  //秒
  private int second;

  /**
   * <b>SIDateTime</b>
   * いまの時刻インスタンスの作成
   * @param なし
   * @return なし
   * @throws なし
   */
  public SIDateTime(){
    currDateTime = new GregorianCalendar();
    init();
  }

  /**
   * <b>SIDateTime</b>
   * コンストラクタ
   * 日付というオブジェクトの時刻のインスタンスの生成
   * @param date Dateオブジェクト
   * @return なし
   * @throws なし
   */
  public SIDateTime(Date date){
    currDateTime = new GregorianCalendar();
    currDateTime.setTime(date);
    init();
  }

  /**
   * <b>SIDateTime</b>
   * コンストラクタ
   * タイムスタンプという時刻オブジェクトのインスタンスの生成
   * @param lTs タイムスタンプ
   * @return なし
   * @throws なし
   */
  public SIDateTime(Timestamp lTs){
    currDateTime = new GregorianCalendar();
    currDateTime.setTime(lTs);
    init();
  }
  /**
   * <b>SIDateTime</b>
   * YYYYMMDDhhmmssという形式の時刻オブジェクトのインスタンスの生成
   * @param yyyymmddhhmmss intの時刻
   * @return なし
   * @throws なし
   */
  public SIDateTime(long date){
    Date lDate=new Date(date);
    currDateTime = new GregorianCalendar();
    currDateTime.setTime(lDate);
    init();
  }

  /**
   * <b>SIDateTime</b>
   * YYYY-MM-DD hh:mm:ssという形式の時刻オブジェクトのインスタンスの生成
   * @param date stringの時刻
   * @return なし
   * @throws ParseException
   */
  public SIDateTime(String date)throws ParseException{
    this(date,SIConfig.SIDATE_TIME_FORMAT);
  }

  public SIDateTime(String date,String format)throws ParseException{
    if (SIUtil.isNull(date))currDateTime = new GregorianCalendar();
    else{
      DateFormat sdf=new SimpleDateFormat(format);
      sdf.setLenient(false);
      Date lDate=new Date();
      try{
        lDate=sdf.parse(date);
      }catch(Exception ee){
        if (format.equals(SIConfig.SIDATE_FORMAT)){
          sdf=new SimpleDateFormat(SIConfig.SIDATE_FORMAT0);
          sdf.setLenient(false);
          lDate=sdf.parse(date);
        }else if (format.equals(SIConfig.SIDATE_TIME_FORMAT)){
          sdf=new SimpleDateFormat(SIConfig.SIDATE_TIME_FORMAT0);
          sdf.setLenient(false);
          lDate=sdf.parse(date);
        }else if (format.equals(SIConfig.SIDATE_FORMAT0)){
          sdf=new SimpleDateFormat(SIConfig.SIDATE_FORMAT);
          sdf.setLenient(false);
          lDate=sdf.parse(date);
        }else if (format.equals(SIConfig.SIDATE_TIME_FORMAT0)){
          sdf=new SimpleDateFormat(SIConfig.SIDATE_TIME_FORMAT);
          sdf.setLenient(false);
          lDate=sdf.parse(date);
        }
      }

      currDateTime = new GregorianCalendar();
      currDateTime.setTime(lDate);
    }
    init();
  }

  /**
   * <b>init</b>
   * 年、月、日、時間、分、秒のデータを設定する
   * @param なし
   * @return なし
   * @throws なし
   */
  private void init(){
    year = currDateTime.get(Calendar.YEAR);
    month = currDateTime.get(Calendar.MONTH)+1;
    day = currDateTime.get(Calendar.DAY_OF_MONTH);
    hour = currDateTime.get(Calendar.HOUR_OF_DAY);
    minute = currDateTime.get(Calendar.MINUTE);
    second = currDateTime.get(Calendar.SECOND);
  }

  /**
   * <b>addYear</b>
   * 年の加算
   * @param num 年数
   * @return なし
   * @throws なし
   */
  public void addYear(int num)
  {
    currDateTime.add(Calendar.YEAR, num);
    init();
  }

  /**
   * <b>addMonth</b>
   * 月の加算
   * @param num 月数
   * @return なし
   * @throws なし
   */
  public void addMonth(int num)
  {
    currDateTime.add(Calendar.MONTH, num);
    init();
  }

  /**
   * <b>addDay</b>
   * 日数の加算
   * @param num 日数
   * @return なし
   * @throws なし
   */
  public void addDay(int num)
  {
    currDateTime.add(Calendar.DAY_OF_MONTH, num);
    init();
  }

  /**
   * <b>addHour</b>
   * 時間数の加算
   * @param num 時間数
   * @return なし
   * @throws なし
   */
  public void addHour(int num){
    currDateTime.add(Calendar.HOUR_OF_DAY, num);
    init();
  }

  /**
   * <b>addMinute</b>
   * 分の加算
   * @param num 分
   * @return なし
   * @throws なし
   */
  public void addMinute(int num){
    currDateTime.add(Calendar.MINUTE, num);
    init();
  }

  /**
   * <b>addSecond</b>
   * 秒の加算
   * @param num 秒
   * @return なし
   * @throws なし
   */
  public void addSecond(int num){
    currDateTime.add(Calendar.SECOND, num);
    init();
  }

  public int getDate(){
    return(year*10000 + month * 100 + day);
  }

  public long getDateTime()
  {
    long date = (long)getDate();
    return( date*1000000 + hour*10000 + minute * 100 + second);
  }

  public String getDateString(){
    return(String.valueOf(getDate()));
  }

  public String getDateTimeString(){
    return(String.valueOf(getDateTime()));
  }

  public String getFullDateTime(){
    return getYearStr()+"/"+
           getMonthStr()+"/"+
           getDayStr()+" "+
           getHourStr()+":"+
           getMinuteStr()+":"+
           getSecondStr();
  }
  public String getFullDate(){
    return getYearStr()+"/"+getMonthStr()+"/"+getDayStr();
  }
  public String getFullDate2(){
      return getYearStr()+"-"+getMonthStr()+"-"+getDayStr();
    }

  public int getDateMonth(){
    return(year*100 + month);
  }

  public int getYear(){
    return(year);
  }

  public String getYearStr(){
    return String.valueOf(year);
  }

  public int getMonth(){
    return(month);
  }
  public String getMonthStr(){
    return SIUtil.lFillIn(month,2);
  }

  public int getDay(){
    return(day);
  }
  
  public int getLasyDay(){
      return currDateTime.getActualMaximum(Calendar.DAY_OF_MONTH);
  }
  
  public String getDayStr(){
    return SIUtil.lFillIn(day,2);
  }

  public int getHour(){
    return(hour);
  }

  public String getHourStr(){
    return SIUtil.lFillIn(hour,2);
  }
  /**
   * <b>getSecond</b>
   * このオブジェクトによって、秒数を返します。
   * @param なし
   * @return 経過の秒数
   * @throws なし
   */
  public int getMinute(){
    return(minute);
  }

  public String getMinuteStr(){
    return SIUtil.lFillIn(minute,2);
  }

  /**
   * <b>getSecond</b>
   * このオブジェクトによって、秒数を返します。
   * @param なし
   * @return 経過の秒数
   * @throws なし
   */
  public int getSecond(){
    return(second);
  }

  public String getSecondStr(){
    return SIUtil.lFillIn(second,2);
  }

  /**
   * <b>getTime</b>
   * このオブジェクトによって、経過のミリ秒数を返します。
   * @param なし
   * @return 経過のミリ秒数
   * @throws なし
   */
  public long getTime(){
    return(currDateTime.getTime().getTime());
  }

  /**
   * <b>getDateObject</b>
   * このオブジェクトによって、日付のオブジェクトを返します。
   * @param なし
   * @return 日付のオブジェクト
   * @throws なし
   */
  public Date getDateObject(){
    return(currDateTime.getTime());
  }

  /**
   * <b>lapseMonth</b>
   * dateによる指定した日からこのオブジェクト
   * の日までの経過月を返します。
   * @param date 指定日
   * @return 経過月数
   * @throws なし
   */
  public int lapseMonth(SIDateTime date){
    int s = (year - date.year)*12 + (month - date.month);
    if ((day - date.day)<0){
      //日で一ヶ月経過していない
      s--;
    }
    return(s);
  }

  /**
   * <b>lapseMonth</b>
   * YYYYMMDDによる指定した日からこのオブジェクト
   * の日までの経過月を返します。
   * @param yyyymmdd 指定日
   * @return 経過月数
   * @throws なし
   */
  public int lapseMonth(String yyyymmdd){
    char[] c = yyyymmdd.toCharArray();
    int y = Integer.parseInt(new String(c,0,4));
    int m = Integer.parseInt(new String(c,4,2));
    int d = Integer.parseInt(new String(c,6,2));

    int s = (year - y)*12 + (month - m);
    if ((day - d)<0){
      s--;
    }
    return(s);
  }

  /**
   * <b>isDate</b>
   * 正しい日付をチェックします
   * @param year チェックの年
   * @param month チェックの月
   * @@param day  チェックの日
   * @return true 正しい日付 false 正しくない日付
   * @throws なし
   */
  public static boolean isDate(int year,int month,int day){
    return isDateTime(year,month,day,0,0,0);
  }

  /**
   * <b>isDateTime</b>
   * 正しい日付をチェックします
   * @param year チェックの年
   * @param month チェックの月
   * @@param day  チェックの日
   * @return true 正しい日付 false 正しくない日付
   * @throws なし
   */
  public static boolean isDateTime(int year,int month,int day,int hour,int minute,int second){
    Calendar lDate = Calendar.getInstance();
    lDate.set(year-1900,month-1,day,hour,minute,day);
    if (lDate.get(Calendar.SECOND)==second &&
        lDate.get(Calendar.MINUTE)==minute &&
        lDate.get(Calendar.HOUR_OF_DAY)==hour &&
        lDate.get(Calendar.DAY_OF_MONTH)==day &&
        lDate.get(Calendar.MONTH)+1==month &&
        lDate.get(Calendar.YEAR)+1900==year) {
      return true;
    }
    return false;
  }

  /**
   * <b>getYearColl</b>
   * 画面に表示する全ての年のリスト
   * @param なし
   * @return 可能な年のコネクションのリスト
   * @throws なし
   */
  public static Collection getYearColl(){
    return SIUtil.getColl(SIConfig.SIDATE_MIN_YEAR,SIConfig.SIDATE_MAX_YEAR);
  }

  public static Collection getYear2Coll(){
    SIDateTime lDateTime=new SIDateTime();
    String lMinYear=lDateTime.getYearStr().substring(2);
    String lMaxYear=String.valueOf(SIConfig.SIDATE_MAX_YEAR).substring(2);
    return SIUtil.getColl(Integer.parseInt(lMinYear),Integer.parseInt(lMaxYear));
  }
  
  public static Collection getInventoryYearColl(){
      return SIUtil.getColl(SIConfig.INVENTORY_MIN_YEAR,SIConfig.SIDATE_MAX_YEAR);
  }

  /**
   * <b>getXYearColl</b>
   * いまから何年間まで表示
   * @param xx 年数
   * @return 年リスト
   * @throws なし
   */
  public static Collection getXYearColl(int xx){
    SIDateTime lDateTime=new SIDateTime();
    String lMinYear=lDateTime.getYearStr();
    return SIUtil.getColl(Integer.parseInt(lMinYear),Integer.parseInt(lMinYear)+xx);
  }

  /**
   * <b>getMonthColl</b>
   * 画面に表示する全ての月のリスト
   * @param なし
   * @return 可能な月のコネクションのリスト
   * @throws なし
   */
  public static Collection getMonthColl(){
    return SIUtil.getColl(1,12);
  }

  /**
   * <b>getDayColl</b>
   * 画面に表示する全ての日のリスト
   * @param なし
   * @return 可能な日のコネクションのリスト
   * @throws なし
   */
  public static Collection getDayColl(){
    return SIUtil.getColl(1,31);
  }

  /**
   * <b>getHourColl</b>
   * 画面に時間を表示する時間のデータリスト
   * @param なし
   * @return 可能な時間のコネクションのリスト
   * @throws なし
   */
  public static Collection getHourColl(){
    return SIUtil.getColl(0,23);
  }

  /**
   * <b>getMinuteColl</b>
   * 画面に分を表示する分のデータリスト
   * @param なし
   * @return 可能な分のコネクションのリスト
   * @throws なし
   */
  public static Collection getMinuteColl(){
    return SIUtil.getColl(0,59);
  }

  /**
   * <b>getSecondColl</b>
   * 画面に分を表示する分のデータリスト
   * @param なし
   * @return 可能な分のコネクションのリスト
   * @throws なし
   */
  public static Collection getSecondColl(){
    return SIUtil.getColl(0,59);
  }

  public static String getDate(String lYear,String lMonth,String lDay){
    if (SIUtil.isNull(lYear+lMonth+lDay)) return "";
    else return lYear+"/"+lMonth+"/"+lDay;
  }

  //7.3.0 PI-NES0501 追加 ここから
  /**
   * <b>getMonthToYear</b>
   * 月単位のカウントを年月のフォーマットで返す
   * @param lMonthCount 月カウント
   * @return monthToYear 年月を表す文字列
   * @throws なし
   */
  public static String getMonthToYear(int lMonthCount){
    if (lMonthCount==0) return "";
    else{
      int lYear = 0;
      int lMonth = 0;
      String monthToYear ="";
      
      lYear = lMonthCount / 12;
      lMonth = lMonthCount % 12;
      if (lYear!=0 & lMonth!=0) monthToYear = lYear + "年" + lMonth + "ヶ月";
      else if (lYear!=0 & lMonth==0) monthToYear = lYear + "年";
      else if (lYear==0 & lMonth!=0) monthToYear = lMonth + "ヶ月";
      return monthToYear;
    }
  }

  /**
   * <b>getSeasonColl</b>
   * １ヶ月の上旬、中旬、下旬をコレクションにして返す
   * @param なし
   * @return lResultColl
   * @throws なし
   */
  public static Collection getSeasonColl() {
      Collection lResultColl = new ArrayList();
      lResultColl.add(new SINameValue("", ""));
      lResultColl.add(new SINameValue("上旬", "01"));
      lResultColl.add(new SINameValue("中旬", "10"));
      lResultColl.add(new SINameValue("下旬", "20"));
      return lResultColl;
  }
  //7.3.0 PI-NES0501 追加 ここまで
  
  public String getFullDateNen() {
    return year + "年" + month + "月" + day + "日";
  }
  
}
