做开发和时间打交道是必不可少的,前后端到数据库的时间交互都需要时间做转换,当然这只是其中几种比较简单的场景,近期工作和时间打交道较多,今天抽时间做个简单的梳理。
1.string和date
时间的格式化和解析是最基础的也是最简易的时间转换。
1.1格式化
Date d = new Date();
DateFormat sdf = new SimpleDateFormat( "Y年M月d日H:m:s ");
String str = sdf.format(d );
1.2解析
String str = " 2018 - 12-1 15:56:20 ";
DateFormat sdf = new SimpleDateFormat( “Y-M-d H:m:s” );
Date d = sdf.parse( str );
2.获取当前时间的前一段时间 日 周 年等
1.getInstance()是重载的,默认根据当前机器区分时区和地区。我们用公历即可。
Calender c = Calender.getInstance();本质返回的是子类对象 Calender是抽象类
2.getTime返回Date对象,获取距1970毫秒。
Calendar c = new GregorianCalendar();
Calendar c2 = new GregorianCalendar();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date parseStart = sdf.parse(startDate);
Date parseEnd = sdf.parse(endDate);
c.setTime(parseStart);
c2.setTime(parseEnd);
c.add(Calendar.YEAR, -1);
c2.add(Calendar.YEAR, -1);
Date timeStart = c.getTime();
Date timeEnd = c2.getTime();
String formatStart = sdf.format(timeStart);
String formatEnd = sdf.format(timeEnd);
list = orderCountUpdatetimeExpenseDayBiz.dataByMonths(formatStart, formatEnd, parkIds, 2);
tbZxthsCountDays = orderCountUpdatetimeExpenseDayBiz.dataByMonths(formatStart, formatEnd, parkIds, 1);
3.计算一段时间内的天数
public static int differentDays(Date date1, Date date2) {
Calendar cal1 = Calendar.getInstance();
cal1.setTime(date1);
Calendar cal2 = Calendar.getInstance();
cal2.setTime(date2);
int day1 = cal1.get(Calendar.DAY_OF_YEAR);
int day2 = cal2.get(Calendar.DAY_OF_YEAR);
int year1 = cal1.get(Calendar.YEAR);
int year2 = cal2.get(Calendar.YEAR);
if (year1 != year2) //同一年
{
int timeDistance = 0;
for (int i = year1; i < year2; i++) {
if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) //闰年
{
timeDistance += 366;
} else //不是闰年
{
timeDistance += 365;
}
}
return timeDistance + (day2 - day1);
} else //不同年
{
System.out.println("判断day2 - day1 : " + (day2 - day1));
return day2 - day1;
}
}
4.时间根据使用情况排序 倒序
public static List<String> listOrder(List<String> list) {
List<String> list1 = new ArrayList<>();
if (list.size() > 1) {
for (int i = list.size() - 1; i >= 0; i--) {
list1.add(list.get(i));
}
} else {
list1 = list;
}
return list1;
}
5.时间可以定义比较器排序
Collections.sort(afterList, new Comparator<OrderCountUpdatetimeExpenseDay>() {
@Override
public int compare(OrderCountUpdatetimeExpenseDay o1, OrderCountUpdatetimeExpenseDay o2) {
//升序
return o2.getUpdatetime().compareTo(o1.getUpdatetime());
}
});
6.获取昨天时间
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, -1);
SimpleDateFormat dfx = new SimpleDateFormat("yyyy-MM-dd");
String yesterday = dfx.format(calendar.getTime());
Date startYesterday = DateUtils.stringConvertDate(yesterday + " 00:00:00", 3);
Date endYesterday = DateUtils.stringConvertDate(yesterday + " 23:59:59", 3);
7.今天时间
Calendar calendarToday = Calendar.getInstance();
SimpleDateFormat dfxToday = new SimpleDateFormat("yyyy-MM-dd");
String today = dfxToday.format(calendarToday.getTime());
Date startToday = DateUtils.stringConvertDate(today + " 00:00:00", 3);
8.截止现在时间
Date time = new Date();
String format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(time);
DateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date endToday = format1.parse(format);
9.工具类
public static Date stringConvertDate(String time, int temp) {
if (time == null || "".equals(time)) {
return new Date();
}
SimpleDateFormat sdf = null;
if (temp == 0) {
sdf = new SimpleDateFormat("yyyy-MM-dd");
} else if (temp == 1) {
sdf = new SimpleDateFormat("yyyy-MM-dd HH");
} else if (temp == 2) {
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
} else if (temp == 3) {
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
} else if (temp == 4) {
sdf = new SimpleDateFormat("yyyy-MM");
} else if (temp == 5) {
sdf = new SimpleDateFormat("yyyy");
} else if(temp == 11){
sdf = new SimpleDateFormat("yyyyMMdd");
}else {
sdf = new SimpleDateFormat("yyyy-MM-dd");
}
try {
return sdf.parse(time);
} catch (ParseException e) {
return new Date();
}
}
最近做一个项目,在一定时间内的周数据,如果时间跨年,会出现这样一个问题,一周7天,假如去年占3天,今年占4天,去年的最后一周为这周,今年的第一周也是这一周,这样一来就产生了重复的周数据,而我要计算每一周和上期同比(本月本周和上月本周的数据对比),这样两个集合的长度便不统一,导致数据偏差,通过断点我发现,跨年的周存在此问题。解决也很简单,把时间集合数据去重复即可。
1.获得一定时间内的时间集合 参数为数据集合和新建值返回字符串时间格式的时间集合
List<String> dateWeek = new ArrayList<>();
List<String> strings = newExtractWeek(thsCountDays, dateWeek);
2.去重复
Set set = new HashSet();
List newList = new ArrayList();
for (Iterator iter = strings.iterator(); iter.hasNext(); ) {
Object element = iter.next();
if (set.add(element))
newList.add(element);
}
strings.clear();
strings.addAll(newList);
10.获取指定周的日期 参数为传来的数据,数据中包含时间字段。
private List<String> newExtractWeek(List<OrderCountUpdatetimeExpenseDay> days, List<String> dates) {
if (days != null && days.size() > 0) {
for (OrderCountUpdatetimeExpenseDay thsCountDay : days) {
createtime = thsCountDay.getCreatetimes();
String replace = createtime.replace("-", "");
int year = Integer.parseInt(replace.substring(0, 4));
int week = Integer.parseInt(replace.substring(4));
String startDay = DateUtils.getStartDayOfWeekNo(year, week);
String endDay = DateUtils.getEndDayOfWeekNo(year, week);
dates.add(startDay + "~" + endDay);
}
}
return dates;
}
/**
* 获取指定年指定周的开始日期
* @param year
* @param weekNo
* @return
*/
public static String getStartDayOfWeekNo(int year,int weekNo){
Calendar cal = getCalendarFormYear(year);
cal.set(Calendar.WEEK_OF_YEAR, weekNo);
int month = cal.get(Calendar.MONTH) + 1;
int day = cal.get(Calendar.DAY_OF_MONTH);
String monthStr = null;
String dayStr = null;
StringBuilder monthBuilder = new StringBuilder();
StringBuilder dayBuilder = new StringBuilder();
if(month < 10){
monthStr = monthBuilder.append("0").append(month).toString();
} else {
monthStr = monthBuilder.append(month).toString();
}
if(day < 10) {
dayStr = dayBuilder.append("0").append(day).toString();
} else {
dayStr = dayBuilder.append(day).toString();
}
return cal.get(Calendar.YEAR) + "" + monthStr + "" + dayStr;
}
/**
* 获取指定年指定周的结束日期
* @param year
* @param weekNo
* @return
*/
public static String getEndDayOfWeekNo(int year,int weekNo){
Calendar cal = getCalendarFormYear(year);
cal.set(Calendar.WEEK_OF_YEAR, weekNo);
cal.add(Calendar.DAY_OF_WEEK, 6);
int month = cal.get(Calendar.MONTH) + 1;
int day = cal.get(Calendar.DAY_OF_MONTH);
String monthStr = null;
String dayStr = null;
StringBuilder monthBuilder = new StringBuilder();
StringBuilder dayBuilder = new StringBuilder();
if(month < 10){
monthStr = monthBuilder.append("0").append(month).toString();
} else {
monthStr = monthBuilder.append(month).toString();
}
if(day < 10) {
dayStr = dayBuilder.append("0").append(day).toString();
} else {
dayStr = dayBuilder.append(day).toString();
}
return cal.get(Calendar.YEAR) + "" + monthStr + "" + dayStr;
}
**
* 日期转星期
*
* @param datetime
* @return
*/ public static String dateToWeek(String datetime) {
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");
String[] weekDays = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
Calendar cal = Calendar.getInstance();
// 获得一个日历
Date datet = null;
try {
datet = f.parse(datetime);
cal.setTime(datet);
} catch (ParseException e) {
e.printStackTrace();
}
int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
// 指示一个星期中的某天。
if(w < 0){
w = 0;}
return weekDays[w];
}
日同比的计算相对简单一些,首先获取本周的数据
1.thsCountDays = orderCountUpdatetimeExpenseDayBiz.dataStatisticsForDay(startDate, endDate, parkIds);
map存储,键为时间,值为该对象
Map<String, OrderCountUpdatetimeExpenseDay> mapDay = new HashMap();
for (int i = 0; i < thsCountDays.size(); i++) {
mapDay.put(thsCountDays.get(i).getCreatetimes(), thsCountDays.get(i));
}
2.获得对应日期的上一周集合数据
tbThsCountDays = orderCountUpdatetimeExpenseDayBiz.dataStatisticsForDay(formatStart, formatEnd, parkIds);
Map<String, OrderCountUpdatetimeExpenseDay> tbMapDay = new HashMap();
for (int i = 0; i < tbThsCountDays.size(); i++) {
tbMapDay.put(tbThsCountDays.get(i).getCreatetimes(), tbThsCountDays.get(i));
}
3.获得本周的值存到新集合
List<String> mapKeyList = new ArrayList<>(mapDay.keySet());
List<OrderCountUpdatetimeExpenseDay> mapValueList = new ArrayList<>(mapDay.values());
4.上周同上
List<String> tbMapKeyList = new ArrayList<>(tbMapDay.keySet());
List<OrderCountUpdatetimeExpenseDay> tbMapValueList = new ArrayList<>(tbMapDay.values());
5.日同比存在问题是 并不是每一天都一定有数据,可能本周是135有数据,上周2467有数据,这么一来,对应的值全乱套了,所以采用map,保存key为对应的数据时间,判断本周某天的时间和上一周的时间对比两个集合的key即可。
List<Date> dateList = new ArrayList<>();
//如过这周某一天对应上周有对应的key 查询数据是string这里要转换一下
for (int i = 0; i < mapKeyList.size(); i++) {
dateList.add(sdf.parse(mapKeyList.get(i)));
}
现在日期是无序的,日期排序
Collections.sort(dateList, new Comparator<Date>() {
@Override
public int compare(Date o1, Date o2) {
//升序
return o2.compareTo(o1);
}
});
6.计算同比
double tb = 0.0;
for (int i = 0; i < dateList.size(); i++) {
boolean flag = false;
c.setTime(dateList.get(i));//获取上周日期
c.add(Calendar.SECOND, -7 * 24 * 3600);
Date upServenTime = c.getTime();
String compareTime = sdf.format(upServenTime);
if (tbMapKeyList != null && tbMapKeyList.size() > 0) {
for (int j = 0; j < tbMapKeyList.size(); j++) {
if (compareTime.equals(tbMapKeyList.get(j))) {//如果两周时间对应上
if(tbMapValueList.get(j).getExpenseSum()!=0.0){
tb = (double)Math.round((((mapValueList.get(i).getExpenseSum()) - (tbMapValueList.get(j).getExpenseSum()) )/ (tbMapValueList.get(j).getExpenseSum())*1000000)/100)/100;
// tbDay = (double) Math.round((tbDay * 1000000) / 100) / 100;
flag = true;
}else {
tb = 666;
flag = true;
}
}
if (!flag) {
tb = 666;
}
}
} else {
tb = 666;
}
tbValue.add(tb);
}