日期工具类



import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.apache.commons.lang3.StringUtils; /**
* 日期工具类
*
* @author Evan
*
*/
public class DateUtils { private static final ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>(); private static final Object object = new Object(); /**
* 获取SimpleDateFormat
*
* @param pattern
* 日期格式
* @return SimpleDateFormat对象
* @throws RuntimeException
* 异常:非法日期格式
*/
private static SimpleDateFormat getDateFormat(String pattern)
throws RuntimeException {
SimpleDateFormat dateFormat = threadLocal.get();
if (dateFormat == null) {
synchronized (object) {
if (dateFormat == null) {
dateFormat = new SimpleDateFormat(pattern);
dateFormat.setLenient(false);
threadLocal.set(dateFormat);
}
}
}
dateFormat.applyPattern(pattern);
return dateFormat;
} /**计算日期
* @param date 限制输入格式都是:yyyy-MM-dd HH:mm:ss
* @param interval 间隔毫秒数,可正可负
* @param tarPattern 目标的输出格式,默认是:yyyy-MM-dd HH:mm:ss
* @return
*
* @author luozhixiao
*/
public static String dateSub(String date, Long interval, String tarPattern){
String tarDate = null; if(StringUtils.isNotBlank( tarDate ) && interval != null){
try {
Long dtLong = getDateFormat("yyyy-MM-dd HH:mm:ss").parse( date ).getTime();
Date rs = new Date(dtLong+interval);
tarDate = getDateFormat(tarPattern!=null?tarPattern:"yyyy-MM-dd HH:mm:ss").format( rs );
} catch (ParseException | RuntimeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} return tarDate;
} /**日期格式转化
* @param date 日期
* @param originFormat 日期的原来格式
* @param targetFormat 目标格式
* @return
*
* @author luozhixiao
*/
public static String transDateFormat(String date , String originFormat , String targetFormat){
String tarDateStr = null; if(StringUtils.isNotBlank( date )&&StringUtils.isNotBlank( originFormat )&&StringUtils.isNotBlank( targetFormat )){
try {
SimpleDateFormat dateFm = getDateFormat(originFormat);
Date dd = dateFm.parse( date );
SimpleDateFormat dateFm2 = getDateFormat(targetFormat);
tarDateStr = dateFm2.format( dd );
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} return tarDateStr;
} /**
* 获取日期中的某数值。如获取月份
*
* @param date
* 日期
* @param dateType
* 日期格式
* @return 数值
*/
private static int getInteger(Date date, int dateType) {
int num = 0;
Calendar calendar = Calendar.getInstance();
if (date != null) {
calendar.setTime(date);
num = calendar.get(dateType);
}
return num;
} /**
* 增加日期中某类型的某数值。如增加日期
*
* @param date
* 日期字符串
* @param dateType
* 类型
* @param amount
* 数值
* @return 计算后日期字符串
*/
public static String addInteger(String date, int dateType, int amount) {
String dateString = null;
DateStyle dateStyle = getDateStyle(date);
if (dateStyle != null) {
Date myDate = StringToDate(date, dateStyle);
myDate = addInteger(myDate, dateType, amount);
dateString = DateToString(myDate, dateStyle);
}
return dateString;
} /**
* 增加日期中某类型的某数值。如增加日期
*
* @param date
* 日期
* @param dateType
* 类型
* @param amount
* 数值
* @return 计算后日期
*/
private static Date addInteger(Date date, int dateType, int amount) {
Date myDate = null;
if (date != null) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(dateType, amount);
myDate = calendar.getTime();
}
return myDate;
} /**
* 获取精确的日期
*
* @param timestamps
* 时间long集合
* @return 日期
*/
private static Date getAccurateDate(List<Long> timestamps) {
Date date = null;
long timestamp = 0;
Map<Long, long[]> map = new HashMap<Long, long[]>();
List<Long> absoluteValues = new ArrayList<Long>(); if (timestamps != null && timestamps.size() > 0) {
if (timestamps.size() > 1) {
for (int i = 0; i < timestamps.size(); i++) {
for (int j = i + 1; j < timestamps.size(); j++) {
long absoluteValue = Math.abs(timestamps.get(i)
- timestamps.get(j));
absoluteValues.add(absoluteValue);
long[] timestampTmp = { timestamps.get(i),
timestamps.get(j) };
map.put(absoluteValue, timestampTmp);
}
} // 有可能有相等的情况。如2012-11和2012-11-01。时间戳是相等的。此时minAbsoluteValue为0
// 因此不能将minAbsoluteValue取默认值0
long minAbsoluteValue = -1;
if (!absoluteValues.isEmpty()) {
minAbsoluteValue = absoluteValues.get(0);
for (int i = 1; i < absoluteValues.size(); i++) {
if (minAbsoluteValue > absoluteValues.get(i)) {
minAbsoluteValue = absoluteValues.get(i);
}
}
} if (minAbsoluteValue != -1) {
long[] timestampsLastTmp = map.get(minAbsoluteValue); long dateOne = timestampsLastTmp[0];
long dateTwo = timestampsLastTmp[1];
if (absoluteValues.size() > 1) {
timestamp = Math.abs(dateOne) > Math.abs(dateTwo) ? dateOne
: dateTwo;
}
}
} else {
timestamp = timestamps.get(0);
}
} if (timestamp != 0) {
date = new Date(timestamp);
}
return date;
} /**
* 判断字符串是否为日期字符串
*
* @param date
* 日期字符串
* @return true or false
*/
public static boolean isDate(String date) {
boolean isDate = false;
if (date != null) {
if (getDateStyle(date) != null) {
isDate = true;
}
}
return isDate;
} /**
* 获取日期字符串的日期风格。失敗返回null。
*
* @param date
* 日期字符串
* @return 日期风格
*/
public static DateStyle getDateStyle(String date) {
DateStyle dateStyle = null;
Map<Long, DateStyle> map = new HashMap<Long, DateStyle>();
List<Long> timestamps = new ArrayList<Long>();
for (DateStyle style : DateStyle.values()) {
if (style.isShowOnly()) {
continue;
}
Date dateTmp = null;
if (date != null) {
try {
ParsePosition pos = new ParsePosition(0);
dateTmp = getDateFormat(style.getValue()).parse(date, pos);
if (pos.getIndex() != date.length()) {
dateTmp = null;
}
} catch (Exception e) {
}
}
if (dateTmp != null) {
timestamps.add(dateTmp.getTime());
map.put(dateTmp.getTime(), style);
}
}
Date accurateDate = getAccurateDate(timestamps);
if (accurateDate != null) {
dateStyle = map.get(accurateDate.getTime());
}
return dateStyle;
} /**
* 将日期字符串转化为日期。失败返回null。
*
* @param date
* 日期字符串
* @return 日期
*/
public static Date StringToDate(String date) {
DateStyle dateStyle = getDateStyle(date);
return StringToDate(date, dateStyle);
} /**
* 将日期字符串转化为日期。失败返回null。
*
* @param date
* 日期字符串
* @param pattern
* 日期格式
* @return 日期
*/
public static Date StringToDate(String date, String pattern) {
Date myDate = null;
if (date != null) {
try {
myDate = getDateFormat(pattern).parse(date);
} catch (Exception e) {
}
}
return myDate;
} /**
* 将日期字符串转化为日期。失败返回null。
*
* @param date
* 日期字符串
* @param dateStyle
* 日期风格
* @return 日期
*/
public static Date StringToDate(String date, DateStyle dateStyle) {
Date myDate = null;
if (dateStyle != null) {
myDate = StringToDate(date, dateStyle.getValue());
}
return myDate;
} /**
* 将日期转化为日期字符串。失败返回null。
*
* @param date
* 日期
* @param pattern
* 日期格式
* @return 日期字符串
*/
public static String DateToString(Date date, String pattern) {
String dateString = null;
if (date != null) {
try {
dateString = getDateFormat(pattern).format(date);
} catch (Exception e) {
}
}
return dateString;
} /**
* 将日期转化为日期字符串。失败返回null。
*
* @param date
* 日期
* @param dateStyle
* 日期风格
* @return 日期字符串
*/
public static String DateToString(Date date, DateStyle dateStyle) {
String dateString = null;
if (dateStyle != null) {
dateString = DateToString(date, dateStyle.getValue());
}
return dateString;
} /**
* 将日期字符串转化为另一日期字符串。失败返回null。
*
* @param date
* 旧日期字符串
* @param newPattern
* 新日期格式
* @return 新日期字符串
*/
public static String StringToString(String date, String newPattern) {
DateStyle oldDateStyle = getDateStyle(date);
return StringToString(date, oldDateStyle, newPattern);
} /**
* 将日期字符串转化为另一日期字符串。失败返回null。
*
* @param date
* 旧日期字符串
* @param newDateStyle
* 新日期风格
* @return 新日期字符串
*/
public static String StringToString(String date, DateStyle newDateStyle) {
DateStyle oldDateStyle = getDateStyle(date);
return StringToString(date, oldDateStyle, newDateStyle);
} /**
* 将日期字符串转化为另一日期字符串。失败返回null。
*
* @param date
* 旧日期字符串
* @param olddPattern
* 旧日期格式
* @param newPattern
* 新日期格式
* @return 新日期字符串
*/
public static String StringToString(String date, String olddPattern,
String newPattern) {
return DateToString(StringToDate(date, olddPattern), newPattern);
} /**
* 将日期字符串转化为另一日期字符串。失败返回null。
*
* @param date
* 旧日期字符串
* @param olddDteStyle
* 旧日期风格
* @param newParttern
* 新日期格式
* @return 新日期字符串
*/
public static String StringToString(String date, DateStyle olddDteStyle,
String newParttern) {
String dateString = null;
if (olddDteStyle != null) {
dateString = StringToString(date, olddDteStyle.getValue(),
newParttern);
}
return dateString;
} /**
* 将日期字符串转化为另一日期字符串。失败返回null。
*
* @param date
* 旧日期字符串
* @param olddPattern
* 旧日期格式
* @param newDateStyle
* 新日期风格
* @return 新日期字符串
*/
public static String StringToString(String date, String olddPattern,
DateStyle newDateStyle) {
String dateString = null;
if (newDateStyle != null) {
dateString = StringToString(date, olddPattern,
newDateStyle.getValue());
}
return dateString;
} /**
* 将日期字符串转化为另一日期字符串。失败返回null。
*
* @param date
* 旧日期字符串
* @param olddDteStyle
* 旧日期风格
* @param newDateStyle
* 新日期风格
* @return 新日期字符串
*/
public static String StringToString(String date, DateStyle olddDteStyle,
DateStyle newDateStyle) {
String dateString = null;
if (olddDteStyle != null && newDateStyle != null) {
dateString = StringToString(date, olddDteStyle.getValue(),
newDateStyle.getValue());
}
return dateString;
} /**
* 增加日期的年份。失败返回null。
*
* @param date
* 日期
* @param yearAmount
* 增加数量。可为负数
* @return 增加年份后的日期字符串
*/
public static String addYear(String date, int yearAmount) {
return addInteger(date, Calendar.YEAR, yearAmount);
} /**
* 增加日期的年份。失败返回null。
*
* @param date
* 日期
* @param yearAmount
* 增加数量。可为负数
* @return 增加年份后的日期
*/
public static Date addYear(Date date, int yearAmount) {
return addInteger(date, Calendar.YEAR, yearAmount);
} /**
* 增加日期的月份。失败返回null。
*
* @param date
* 日期
* @param monthAmount
* 增加数量。可为负数
* @return 增加月份后的日期字符串
*/
public static String addMonth(String date, int monthAmount) {
return addInteger(date, Calendar.MONTH, monthAmount);
} /**
* 增加日期的月份。失败返回null。
*
* @param date
* 日期
* @param monthAmount
* 增加数量。可为负数
* @return 增加月份后的日期
*/
public static Date addMonth(Date date, int monthAmount) {
return addInteger(date, Calendar.MONTH, monthAmount);
} /**
* 增加日期的天数。失败返回null。
*
* @param date
* 日期字符串
* @param dayAmount
* 增加数量。可为负数
* @return 增加天数后的日期字符串
*/
public static String addDay(String date, int dayAmount) {
return addInteger(date, Calendar.DATE, dayAmount);
} /**
* 增加日期的天数。失败返回null。
*
* @param date
* 日期
* @param dayAmount
* 增加数量。可为负数
* @return 增加天数后的日期
*/
public static Date addDay(Date date, int dayAmount) {
return addInteger(date, Calendar.DATE, dayAmount);
} /**
* 增加日期的小时。失败返回null。
*
* @param date
* 日期字符串
* @param hourAmount
* 增加数量。可为负数
* @return 增加小时后的日期字符串
*/
public static String addHour(String date, int hourAmount) {
return addInteger(date, Calendar.HOUR_OF_DAY, hourAmount);
} /**
* 增加日期的小时。失败返回null。
*
* @param date
* 日期
* @param hourAmount
* 增加数量。可为负数
* @return 增加小时后的日期
*/
public static Date addHour(Date date, int hourAmount) {
return addInteger(date, Calendar.HOUR_OF_DAY, hourAmount);
} /**
* 增加日期的分钟。失败返回null。
*
* @param date
* 日期字符串
* @param minuteAmount
* 增加数量。可为负数
* @return 增加分钟后的日期字符串
*/
public static String addMinute(String date, int minuteAmount) {
return addInteger(date, Calendar.MINUTE, minuteAmount);
} /**
* 增加日期的分钟。失败返回null。
*
* @param date
* 日期
* @param minuteAmount
* 增加数量。可为负数
* @return 增加分钟后的日期
*/
public static Date addMinute(Date date, int minuteAmount) {
return addInteger(date, Calendar.MINUTE, minuteAmount);
} /**
* 增加日期的秒钟。失败返回null。
*
* @param date
* 日期字符串
* @param secondAmount
* 增加数量。可为负数
* @return 增加秒钟后的日期字符串
*/
public static String addSecond(String date, int secondAmount) {
return addInteger(date, Calendar.SECOND, secondAmount);
} /**
* 增加日期的秒钟。失败返回null。
*
* @param date
* 日期
* @param secondAmount
* 增加数量。可为负数
* @return 增加秒钟后的日期
*/
public static Date addSecond(Date date, int secondAmount) {
return addInteger(date, Calendar.SECOND, secondAmount);
} /**
* 获取日期的年份。失败返回0。
*
* @param date
* 日期字符串
* @return 年份
*/
public static int getYear(String date) {
return getYear(StringToDate(date));
} /**
* 获取日期的年份。失败返回0。
*
* @param date
* 日期
* @return 年份
*/
public static int getYear(Date date) {
return getInteger(date, Calendar.YEAR);
} /**
* 获取日期的月份。失败返回0。
*
* @param date
* 日期字符串
* @return 月份
*/
public static int getMonth(String date) {
return getMonth(StringToDate(date));
} /**
* 获取日期的月份。失败返回0。
*
* @param date
* 日期
* @return 月份
*/
public static int getMonth(Date date) {
return getInteger(date, Calendar.MONTH) + 1;
} /**
* 获取日期的天数。失败返回0。
*
* @param date
* 日期字符串
* @return 天
*/
public static int getDay(String date) {
return getDay(StringToDate(date));
} /**
* 获取日期的天数。失败返回0。
*
* @param date
* 日期
* @return 天
*/
public static int getDay(Date date) {
return getInteger(date, Calendar.DATE);
} /**
* 获取日期的小时。失败返回0。
*
* @param date
* 日期字符串
* @return 小时
*/
public static int getHour(String date) {
return getHour(StringToDate(date));
} /**
* 获取日期的小时。失败返回0。
*
* @param date
* 日期
* @return 小时
*/
public static int getHour(Date date) {
return getInteger(date, Calendar.HOUR_OF_DAY);
} /**
* 获取日期的分钟。失败返回0。
*
* @param date
* 日期字符串
* @return 分钟
*/
public static int getMinute(String date) {
return getMinute(StringToDate(date));
} /**
* 获取日期的分钟。失败返回0。
*
* @param date
* 日期
* @return 分钟
*/
public static int getMinute(Date date) {
return getInteger(date, Calendar.MINUTE);
} /**
* 获取日期的秒钟。失败返回0。
*
* @param date
* 日期字符串
* @return 秒钟
*/
public static int getSecond(String date) {
return getSecond(StringToDate(date));
} /**
* 获取日期的秒钟。失败返回0。
*
* @param date
* 日期
* @return 秒钟
*/
public static int getSecond(Date date) {
return getInteger(date, Calendar.SECOND);
} /**
* 获取日期 。默认yyyy-MM-dd格式。失败返回null。
*
* @param date
* 日期字符串
* @return 日期
*/
public static String getDate(String date) {
return StringToString(date, DateStyle.YYYY_MM_DD);
} /**
* 获取日期。默认yyyy-MM-dd格式。失败返回null。
*
* @param date
* 日期
* @return 日期
*/
public static String getDate(Date date) {
return DateToString(date, DateStyle.YYYY_MM_DD);
} /**
* 获取日期的时间。默认HH:mm:ss格式。失败返回null。
*
* @param date
* 日期字符串
* @return 时间
*/
public static String getTime(String date) {
return StringToString(date, DateStyle.HH_MM_SS);
} /**
* 获取日期的时间。默认HH:mm:ss格式。失败返回null。
*
* @param date
* 日期
* @return 时间
*/
public static String getTime(Date date) {
return DateToString(date, DateStyle.HH_MM_SS);
} /**
* 获取日期的星期。失败返回null。
*
* @param date
* 日期字符串
* @return 星期
*/
public static Week getWeek(String date) {
Week week = null;
DateStyle dateStyle = getDateStyle(date);
if (dateStyle != null) {
Date myDate = StringToDate(date, dateStyle);
week = getWeek(myDate);
}
return week;
} /**
* 获取日期的星期。失败返回null。
*
* @param date
* 日期
* @return 星期
*/
public static Week getWeek(Date date) {
Week week = null;
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int weekNumber = calendar.get(Calendar.DAY_OF_WEEK) - 1;
switch (weekNumber) {
case 0:
week = Week.SUNDAY;
break;
case 1:
week = Week.MONDAY;
break;
case 2:
week = Week.TUESDAY;
break;
case 3:
week = Week.WEDNESDAY;
break;
case 4:
week = Week.THURSDAY;
break;
case 5:
week = Week.FRIDAY;
break;
case 6:
week = Week.SATURDAY;
break;
}
return week;
} /**
* 获取两个日期相差的天数
*
* @param date
* 日期字符串
* @param otherDate
* 另一个日期字符串
* @return 相差天数。如果失败则返回-1
*/
public static int getIntervalDays(String date, String otherDate) {
return getIntervalDays(StringToDate(date), StringToDate(otherDate));
} /**
* @param date
* 日期
* @param otherDate
* 另一个日期
* @return 相差天数。如果失败则返回-1
*/
public static int getIntervalDays(Date date, Date otherDate) {
int num = -1;
Date dateTmp = DateUtils.StringToDate(DateUtils.getDate(date),
DateStyle.YYYY_MM_DD);
Date otherDateTmp = DateUtils.StringToDate(DateUtils.getDate(otherDate),
DateStyle.YYYY_MM_DD);
if (dateTmp != null && otherDateTmp != null) {
long time = Math.abs(dateTmp.getTime() - otherDateTmp.getTime());
num = (int) (time / (24 * 60 * 60 * 1000));
}
return num;
} /**
* 是否晚于当前时间
*
* @param date
* @return
*/
public static boolean isAfterNow(Date date){
return date.getTime() > new Date().getTime();
} /**
* long转string类型date
* @param longStr
* @param format
* @return
*/
public static String longToDateStr(String longStr,String format){
String dateStr = "";
if(StringUtils.isBlank(longStr)){
return dateStr;
}else{
long time = Long.parseLong(longStr);
Date date = new Date(time);
SimpleDateFormat sd = new SimpleDateFormat(format);
return sd.format(date);
}
}
}

Web 开发工具类(5) | DateUtils的更多相关文章

  1. web开发工具类

    1.日期工具类 import java.text.SimpleDateFormat; import java.util.Date; public class DateUtil { public sta ...

  2. Web 开发工具类(2): HttpClientUtils

    HttpClientUtils 整合了一些 web开发中常用的httpClient操作: package com.evan.common.utils; import java.io.IOExcepti ...

  3. Web 开发工具类(1): CookieUtils

    CookieUtils 整合了常用的一些对Cookie的相关操作: package com.evan.common.utils; import java.io.UnsupportedEncodingE ...

  4. Web 开发工具类(4): IDUtils

    package com.easybuy.utils; import java.util.Random; /** * * <p>Title: IDUtils</p> * < ...

  5. Web 开发工具类(3): JsonUtils

    JsonUtils 整合了一些对Json的相关操作: package com.evan.common.utils; import java.util.List; import com.fasterxm ...

  6. 超全的web开发工具和资源

    首页 新闻 产品 地图 动态 城市 帮助 论坛 关于 登录 注册 · 不忘初心,继续前进,环境云V2接口正式上线 · 环境云测点地图全新改版 · 祝福各位环境云用户中秋快乐!   平台信息 培训互动 ...

  7. 干货100+ 最超全的web开发工具和资源大集合

    干货100+ 最超全的web开发工具和资源大集合   作为Web开发者,这是好的时代,也是坏的时代.Web开发技术也在不断变化.虽然很令人兴奋,但是这也意味着Web开发人员需要要积极主动的学习新技术和 ...

  8. Firefox上Web开发工具库一览

    Firefox的目标之一就是尽可能地使web开发者的生活更简单高效,并通过提供工具和具有很强扩展性的浏览器使人们创造出神奇的东西.使web开发者使用Firefox的时候,浏览器可以提供大量开发工具和选 ...

  9. 6个好用的Web开发工具

    在过去的几年间,涌现出了很多Web开发工具,它们大多还是比较吸引人的,方便了我们的工作.我们可以学习一下这些新东西,短时间就可以拓宽思路(PHP100推荐:学习10分钟,改变你的程序员生涯).这些应用 ...

随机推荐

  1. ELK学习实验001:Elastic Stack简介

    1 背景介绍 在我们日常生活中,我们经常需要回顾以前发生的一些事情:或者,当出现了一些问题的时候,可以从某些地方去查找原因,寻找发生问题的痕迹.无可避免需要用到文字的.图像的等等不同形式的记录.用计算 ...

  2. 005 Ceph配置文件及用户管理

    一.Ceph的配置文件 Ceph 配置文件可用于配置存储集群内的所有守护进程.或者某一类型的所有守护进程.要配置一系列守护进程,这些配置必须位于能收到配置的段落之下.默认情况下,无论是ceph的服务端 ...

  3. $HDU1848\ Fibonacci\ again\ and\ again$ 博弈论

    正解:博弈论 解题报告: 传送门! 首先按照套路显然是考虑先预处理出所有数的$SG$函数值然后全局的$SG$就是$SG(n)$^$SG(m)$^$SG(p)$,这儿应该麻油问题$QwQ$? 然后就考虑 ...

  4. MyBatis原理-拦截器

    一.MyBatis拦截器介绍 MyBatis提供了一种插件(plugin)的功能,虽然叫做插件,但其实这是拦截器功能. MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用.默认情况下,M ...

  5. 开箱即用~基于.NET Core的统一应用逻辑分层框架设计

    目前公司系统多个应用分层结构各不相同,给运维和未来的开发带来了巨大的成本,分层架构看似很简单,但保证整个研发中心都使用统一的分层架构就不容易了. 那么如何保证整个研发中心都使用统一的分层架构,以达到提 ...

  6. Using TFRecords and tf.Example

    -----这篇其实是TensorFlow的官方tutorials,由于没有翻译,笔者姑且翻译一下,用来日后思考.------- 原址:https://www.tensorflow.org/tutori ...

  7. 【原创】(十六)Linux内存管理之CMA

    背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...

  8. 道格拉斯-普克算法(JavaScript实现)

    需求: 有时候当移动速度很慢,GPS定位的轨迹点就非常的多,这时候为了缩减数据量,需要将不突出的点去掉. 思路: (1) 在曲线首尾两点间虚连一条直线,求出其余各点到该直线的距离. (2)选其最大者与 ...

  9. 【阿里云IoT+YF3300】11.物联网多设备快速通信级联

    我们见到的很多物联网设备,大都是“一跳”上网,所谓的“一跳”就是设备直接上网,内嵌物联网模块或者通过DTU直接上网.其实稍微复杂的物联网现场,往往网关下面连接若干物联网设备(如下图),并且这些物联网设 ...

  10. Spring Boot2 系列教程(二十) | SpringBoot 是如何实现日志的?

    微信公众号:一个优秀的废人.如有问题,请后台留言,反正我也不会听. 前言 休息日闲着无聊看了下 SpringBoot 中的日志实现,把我的理解跟大家说下. 门面模式 说到日志框架不得不说门面模式.门面 ...