java基础-1

前言

没有什么前言不前言的,就只是想记录一下去年写过的Java代码,有些逻辑还是很佩服自己的(乱七八糟的逻辑居然能跑通),可能过段时间有更好的解决方案,记录一下。虽然目前我主做前端项目。

时间处理util是在写价格日历的时候用到的,本来想把价格日历的整个逻辑整理一下的,看着🤢,还是算了吧。

首先声明部分不是我写的,有些是百度的,有些是框架里的,年代久远也不想分太清了。

金额浮点数处理不只java中会有这个问题,python中也有,javascript就更不用说了,所以部分东西我认为是可以通用的。

时间处理util

获取一段时间内星期处理
package xx.xxx.xxx.util; // 包名

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class WeekDayUtil {
//	public static void main(String[] args) {
//		String[] data = getDates("2018-12-01", "2018-12-31", "12");
//		System.out.println(data);
//	}

	/**
	 * 获取某一时间段特定星期几的日期
	 * 
	 * @param dateFrom 开始时间
	 * @param dateEnd 结束时间
	 * @param weekDays 星期
	 * @return 返回时间数组
	 */
	public static String[] getDates(String dateFrom, String dateEnd, String weekDays) {
		long time = 1l;
		long perDayMilSec = 24 * 60 * 60 * 1000;
		List<String> dateList = new ArrayList<String>();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		// 需要查询的星期系数
		String strWeekNumber = weekDays; //weekForNum(weekDays);
		try {
			dateFrom = sdf.format(sdf.parse(dateFrom).getTime() - perDayMilSec);
			while (true) {
				time = sdf.parse(dateFrom).getTime();
				time = time + perDayMilSec;
				Date date = new Date(time);
				dateFrom = sdf.format(date);
				if (dateFrom.compareTo(dateEnd) <= 0) {
					// 查询的某一时间的星期系数
					Integer weekDay = dayForWeek(date);
					// 判断当期日期的星期系数是否是需要查询的
					if (strWeekNumber.indexOf(weekDay.toString()) != -1) {
						dateList.add(dateFrom);
					}
				} else {
					break;
				}
			}
		} catch (ParseException e1) {
			e1.printStackTrace();
		}
		String[] dateArray = new String[dateList.size()];
		dateList.toArray(dateArray);
		return dateArray;
	}

	// 等到当期时间的周系数。星期日:1,星期一:2,星期二:3,星期三:4,星期四:5,星期五:6,星期六:7
	public static Integer dayForWeek(Date date) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		return calendar.get(Calendar.DAY_OF_WEEK);
	}

	/**
	 * 得到对应星期的系数 星期日:1,星期一:2,星期二:3,星期三:4,星期四:5,星期五:6,星期六:7
	 * 
	 * @param weekDays 星期格式 星期一|星期二
	 */
	public static String weekForNum(String weekDays) {
		// 返回结果为组合的星期系数
		String weekNumber = "";
		// 解析传入的星期
		if (weekDays.indexOf("|") != -1) {// 多个星期数
			String[] strWeeks = weekDays.split("\\|");
			for (int i = 0; i < strWeeks.length; i++) {
				weekNumber = weekNumber + "" + getWeekNum(strWeeks[i]).toString();
			}
		} else {// 一个星期数
			weekNumber = getWeekNum(weekDays).toString();
		}
		return weekNumber;
	}
	
    // 注意:前端的星期与java获取的星期不一致
	// 将星期转换为对应的系数 星期日:1,星期一:2,星期二:3,星期三:4,星期四:5,星期五:6,星期六:7
	public static Integer getWeekNum(String strWeek) {
		Integer number = 1;// 默认为星期日
		if ("星期日".equals(strWeek)) {
			number = 1;
		} else if ("星期一".equals(strWeek)) {
			number = 2;
		} else if ("星期二".equals(strWeek)) {
			number = 3;
		} else if ("星期三".equals(strWeek)) {
			number = 4;
		} else if ("星期四".equals(strWeek)) {
			number = 5;
		} else if ("星期五".equals(strWeek)) {
			number = 6;
		} else if ("星期六".equals(strWeek)) {
			number = 7;
		} else {
			number = 1;
		}
		return number;
	}

}
获取一段时间内的日期
package xx.xxx.xxx.util;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 获取一段时间内的日期
 */
public class FindDatesUtil {

	public static void main(String[] args) throws Exception {

		Calendar cal = Calendar.getInstance();
		String start = "2012-02-01";
		String end = "2012-03-02";
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date dBegin = sdf.parse(start);
		Date dEnd = sdf.parse(end);
		List<Date> lDate = findDatesByDate(dBegin, dEnd);
		for (Date date : lDate) {
			System.out.println(sdf.format(date));
		}
		System.out.println(getMaxDayByYearMonth(2019, 1));
	}

	/**
	 * 获取一段时间内的日期,返回string
	 * @param Date dBegin
	 * @param Date dEnd
	 * @return List<String>
	 */
	public static List<String> findDates(Date dBegin, Date dEnd) {
		List lDate = new ArrayList();
		SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
		lDate.add(sd.format(dBegin));
		Calendar calBegin = Calendar.getInstance();
		// 使用给定的 Date 设置此 Calendar 的时间
		calBegin.setTime(dBegin);
		Calendar calEnd = Calendar.getInstance();
		// 使用给定的 Date 设置此 Calendar 的时间
		calEnd.setTime(dEnd);
		// 测试此日期是否在指定日期之后
		while (dEnd.after(calBegin.getTime())) {
			// 根据日历的规则,为给定的日历字段添加或减去指定的时间量
			calBegin.add(Calendar.DAY_OF_MONTH, 1);
			lDate.add(sd.format(calBegin.getTime()));
		}
		return lDate;
	}
	
	/**
	 *  获取一段时间内的日期,返回date
	 * @param Date dBegin
	 * @param Date dEnd
	 * @return List<Date>
	 */
	public static List<Date> findDatesByDate(Date dBegin, Date dEnd) {
		List lDate = new ArrayList();
		lDate.add(dBegin);
		Calendar calBegin = Calendar.getInstance();
		// 使用给定的 Date 设置此 Calendar 的时间
		calBegin.setTime(dBegin);
		Calendar calEnd = Calendar.getInstance();
		// 使用给定的 Date 设置此 Calendar 的时间
		calEnd.setTime(dEnd);
		// 测试此日期是否在指定日期之后
		while (dEnd.after(calBegin.getTime())) {
			// 根据日历的规则,为给定的日历字段添加或减去指定的时间量
			calBegin.add(Calendar.DAY_OF_MONTH, 1);
			lDate.add(calBegin.getTime());
		}
		return lDate;
	}
	
	/**
	 * 获得某个月最后一天
	 *
	 * @param year 年份
	 * @param month 月份 (1-12)
	 * @return 某个月最后一天日期
	 */
	public static String getLastDayByYearMonth(int year, int month) {
	  SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");  
	  Calendar calendar = Calendar.getInstance();
	  calendar.set(Calendar.YEAR, year);
	  calendar.set(Calendar.MONTH, month);
	  calendar.set(Calendar.DAY_OF_MONTH, 0);
	  //return calendar.getActualMaximum(Calendar.DATE);
	  String lastday = format.format(calendar.getTime());
	  return lastday;
	}
	
	/**
	 * 获得某个月第一天
	 *
	 * @param year 年份
	 * @param month 月份 (1-12)
	 * @return 某个月最后一天日期
	 */
	public static String getFirstDayByYearMonth(int year, int month) {
	  SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");  
	  Calendar calendar = Calendar.getInstance();
	  calendar.set(Calendar.YEAR, year);
	  calendar.set(Calendar.MONTH, month - 1);
	  calendar.set(Calendar.DAY_OF_MONTH, 1);
	  //return calendar.getActualMaximum(Calendar.DATE);
	  String firstday = format.format(calendar.getTime());
	  return firstday;
	}
	
	/**
	 * 获得某个月最大天数
	 *
	 * @param year 年份
	 * @param month 月份 (1-12)
	 * @return 某个月最后一天日期
	 */
	public static int getMaxDayByYearMonth(int year, int month) {
	  Calendar calendar = Calendar.getInstance();
	  calendar.set(Calendar.YEAR, year);
	  calendar.set(Calendar.MONTH, month);
	  return calendar.getActualMaximum(Calendar.DATE);
	}
	
	/**
	 * 想要获取的日期与传入日期的差值 比如想要获取传入日期前四天的日期 day=-4即可
     * @param date
     * @param day 
     * @return
     */
    public static Date getDateByDiff(Date date, int day){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, day);
        return calendar.getTime();
    }
    

    /**
     * 判断时间是否在时间段内,返回boolean,区间为[beginTime,endTime)
     * @param nowTime
     * @param beginTime
     * @param endTime
     * @return
     */
    public static boolean isInPeriod(Date nowTime, Date beginTime, Date endTime) {
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);
        Calendar begin = Calendar.getInstance();
        begin.setTime(beginTime);
        Calendar end = Calendar.getInstance();
        end.setTime(endTime);
        if (date.after(begin) && date.before(end)) {
            return true;
        } else if (nowTime.compareTo(beginTime) == 0 || nowTime.compareTo(endTime) == 0) {
            return true;
        } else {
            return false;
        }
    }

}
时间格式转换
package xx.xxx.xxx.util;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DataFormatUtil {
	
	public static void main(String[] args) throws Exception {
		System.out.println(LongToStr(1545350400));
	}
	
	/**
	 * 时间戳转换为字符串
	 * @param time
	 * @return string
	 */
	public static String dateToStr(Timestamp time) {
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String str = df.format(time);
		return str;
	}
	
	/**
	 * 整型转为字符串时间格式
	 * @param seconds
	 * @return
	 */
	public static String IntToStr(int seconds) {
		Calendar c=Calendar.getInstance();
		long millions=new Long(seconds).longValue()*1000;
		c.setTimeInMillis(millions);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateString = sdf.format(c.getTime());
		return dateString;
	}
	
	/**
	 * 整型转为字符串时间格式
	 * @param seconds
	 * @return
	 */
	public static String LongToStr(long seconds) {
		Calendar c=Calendar.getInstance();
		long millions=new Long(seconds).longValue()*1000;
		c.setTimeInMillis(millions);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateString = sdf.format(c.getTime());
		return dateString;
	}
	
	/**
	 * 字符串转Date时间格式
	 * @param strDate
	 * @return
	 */
	public static Date strToDate(String strDate) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date date;
		try {
			date = sdf.parse(strDate);
		} catch (Exception e) {
			date = null;
		}
		return date;
	}
}

金额处理util

package xx.xxx.xxx.util;

import java.math.BigDecimal;

/**
 * 由于Java的简单类型不能够精确的对浮点数进行运算, 这个工具类提供精确的浮点数运算,包括加减乘除和四舍五入。
 */
public final class CurrencyUtil {

    // 默认除法运算精度
    private static final int DEF_DIV_SCALE = 2;

    // 这个类不能实例化
    private CurrencyUtil() {
    }

    /**
     * 提供精确的加法运算。
     * @param v1 被加数
     * @param v2 加数
     * @return 两个参数的和
     */
    public static Double add(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 提供精确的减法运算。
     * @param v1 被减数
     * @param v2 减数
     * @return 两个参数的差
     */
    public static double sub(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 提供精确的乘法运算。
     * @param v1 被乘数
     * @param v2 乘数
     * @return 两个参数的积
     */
    public static Double mul(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 提供精确的乘法运算。
     * @param v1 被乘数
     * @param v2 乘数
     * @return 两个参数的积
     */
    public static Double mul(double v1, double v2, Long days) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        BigDecimal b3 = new BigDecimal(Long.toString(days));
        BigDecimal onePrice = b1.multiply(b2).setScale(2, BigDecimal.ROUND_HALF_UP);
        BigDecimal twoPrice = onePrice.multiply(b3).setScale(2, BigDecimal.ROUND_HALF_UP);
        return twoPrice.doubleValue();
    }

    /**
     * 提供(相对)精确的除法运算,当发生除不尽的情况时, 精确到小数点以后10位,以后的数字四舍五入。
     * @param v1 被除数
     * @param v2 除数
     * @return 两个参数的商
     */
    public static double div(double v1, double v2) {
        return div(v1, v2, DEF_DIV_SCALE);
    }

    /**
     * 提供(相对)精确的除法运算。 当发生除不尽的情况时,由scale参数指定精度,以后的数字四舍五入。
     * @param v1 被除数
     * @param v2 除数
     * @param scale 表示表示需要精确到小数点以后几位。
     * @return 两个参数的商
     */
    public static double div(double v1, double v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 提供精确的小数位四舍五入处理。
     * @param v 需要四舍五入的数字
     * @param scale 小数点后保留几位
     * @return 四舍五入后的结果
     */
    public static double round(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(Double.toString(v));
        BigDecimal one = new BigDecimal("1");
        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    public static void main(String[] args) {
        Double d1 = 1.01;
        Double d2 = 0.42;
        // //System.out.println(d1-d2);
        // //System.out.println(Arith.sub(d1, d2));
        // //System.out.println(Arith.sub1(d1, d2));
        // long a = System.currentTimeMillis();
        // for(int i=0;i<10000;i++){
        // double r = Arith.sub1(d1, d2);
        // }
        // //System.out.println(System.currentTimeMillis() - a);
        // //System.out.println(0.05+0.01);
        // //System.out.println(1.0-0.42);
        // //System.out.println(4.015*100);
        // //System.out.println(123.3/100);
        System.out.println(CurrencyUtil.mul(4.01511, 100));

        // System.out.println( CurrencyUtil.sub(2D, 10D) );
    }
}