add method for ChineseDate

This commit is contained in:
Looly 2020-03-20 10:44:11 +08:00
parent 887a2634e9
commit 77aee971a5
7 changed files with 229 additions and 48 deletions

View File

@ -15,12 +15,14 @@
* 【core 】 增加CallerUtil.getCallerMethodName方法 * 【core 】 增加CallerUtil.getCallerMethodName方法
* 【core 】 Tree增加getParent方法可以获取父节点抽象Node接口 * 【core 】 Tree增加getParent方法可以获取父节点抽象Node接口
* 【core 】 增加社会信用代码工具CreditCodeUtilpr#112@Gitee * 【core 】 增加社会信用代码工具CreditCodeUtilpr#112@Gitee
* 【core 】 ChineseDate增加构造重载增加toStringNormalissue#792@Github
### Bug修复 ### Bug修复
* 【core 】 修复TypeUtil无法获取泛型接口的泛型参数问题issue#I1BRFI@Gitee * 【core 】 修复TypeUtil无法获取泛型接口的泛型参数问题issue#I1BRFI@Gitee
* 【core 】 修复MySQL中0000报错问题 * 【core 】 修复MySQL中0000报错问题
* 【core 】 修复BeanPath从Map取值为空的问题issue#790@Github * 【core 】 修复BeanPath从Map取值为空的问题issue#790@Github
* 【poi 】 修复添加图片尺寸的单位问题issue#I1C2ER@Gitee * 【poi 】 修复添加图片尺寸的单位问题issue#I1C2ER@Gitee
* 【setting】 修复getStr中逻辑问题pr#113@Gitee
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
## 5.2.3 ## 5.2.3

View File

@ -131,6 +131,20 @@ public class ChineseDate {
day = offset + 1; day = offset + 1;
} }
/**
* 构造方法传入日期
*
* @param chineseYear 农历年
* @param chineseMonth 农历月1表示一月正月
* @param chineseDay 农历日1表示初一
* @since 5.2.4
*/
public ChineseDate(int chineseYear, int chineseMonth, int chineseDay) {
this.day = chineseDay;
this.month = chineseMonth;
this.year = chineseYear;
this.leap = DateUtil.isLeapYear(chineseYear);
}
/** /**
* 获得农历年份 * 获得农历年份
@ -142,7 +156,17 @@ public class ChineseDate {
} }
/** /**
* 获得农历月份 * 获取农历的月从1开始计数
*
* @return 农历的月
* @since 5.2.4
*/
public int getMonth() {
return this.month;
}
/**
* 获得农历月份中文例如二月十二月或者润一月
* *
* @return 返回农历月份 * @return 返回农历月份
*/ */
@ -151,7 +175,7 @@ public class ChineseDate {
} }
/** /**
* 获得农历月称呼 * 获得农历月称呼中文例如二月腊月或者润正月
* *
* @return 返回农历月份称呼 * @return 返回农历月份称呼
*/ */
@ -159,6 +183,16 @@ public class ChineseDate {
return (leap ? "" : "") + chineseNumberName[month - 1] + ""; return (leap ? "" : "") + chineseNumberName[month - 1] + "";
} }
/**
* 获取农历的日从1开始计数
*
* @return 农历的日从1开始计数
* @since 5.2.4
*/
public int getDay() {
return this.day;
}
/** /**
* 获得农历日 * 获得农历日
* *
@ -230,6 +264,16 @@ public class ChineseDate {
return (cyclicalm(num)); return (cyclicalm(num));
} }
/**
* 转换为标准的日期格式来表示农历日期例如2020-01-13
*
* @return 标准的日期格式
* @since 5.2.4
*/
public String toStringNormal(){
return String.format("%04d-%02d-%02d", this.year, this.month, this.day);
}
@Override @Override
public String toString() { public String toString() {
return String.format("%s%s年 %s%s", getCyclical(), getChineseZodiac(), getChineseMonthName(), getChineseDay()); return String.format("%s%s年 %s%s", getCyclical(), getChineseZodiac(), getChineseMonthName(), getChineseDay());

View File

@ -275,6 +275,48 @@ public class ObjectUtil {
return (null != object) ? object : defaultValue; return (null != object) ? object : defaultValue;
} }
/**
* 如果给定对象为{@code null}或者 "" 返回默认值
*
* <pre>
* ObjectUtil.defaultIfEmpty(null, null) = null
* ObjectUtil.defaultIfEmpty(null, "") = ""
* ObjectUtil.defaultIfEmpty("", "zz") = "zz"
* ObjectUtil.defaultIfEmpty(" ", "zz") = " "
* ObjectUtil.defaultIfEmpty("abc", *) = "abc"
* </pre>
*
* @param <T> 对象类型必须实现CharSequence接口
* @param str 被检查对象可能为{@code null}
* @param defaultValue 被检查对象为{@code null}或者 ""返回的默认值可以为{@code null}或者 ""
* @return 被检查对象为{@code null}或者 ""返回默认值否则返回原值
* @since 5.0.4
*/
public static <T extends CharSequence> T defaultIfEmpty(final T str, final T defaultValue) {
return StrUtil.isEmpty(str) ? defaultValue : str;
}
/**
* 如果给定对象为{@code null}或者""或者空白符返回默认值
*
* <pre>
* ObjectUtil.defaultIfEmpty(null, null) = null
* ObjectUtil.defaultIfEmpty(null, "") = ""
* ObjectUtil.defaultIfEmpty("", "zz") = "zz"
* ObjectUtil.defaultIfEmpty(" ", "zz") = "zz"
* ObjectUtil.defaultIfEmpty("abc", *) = "abc"
* </pre>
*
* @param <T> 对象类型必须实现CharSequence接口
* @param str 被检查对象可能为{@code null}
* @param defaultValue 被检查对象为{@code null}或者 ""或者空白符返回的默认值可以为{@code null}或者 ""或者空白符
* @return 被检查对象为{@code null}或者 ""或者空白符返回默认值否则返回原值
* @since 5.0.4
*/
public static <T extends CharSequence> T defaultIfBlank(final T str, final T defaultValue) {
return StrUtil.isBlank(str) ? defaultValue : str;
}
/** /**
* 克隆对象<br> * 克隆对象<br>
* 如果对象实现Cloneable接口调用其clone方法<br> * 如果对象实现Cloneable接口调用其clone方法<br>

View File

@ -9,9 +9,15 @@ public class ChineseDateTest {
public void chineseDateTest() { public void chineseDateTest() {
ChineseDate date = new ChineseDate(DateUtil.parseDate("2020-01-25")); ChineseDate date = new ChineseDate(DateUtil.parseDate("2020-01-25"));
Assert.assertEquals(2020, date.getChineseYear()); Assert.assertEquals(2020, date.getChineseYear());
Assert.assertEquals(1, date.getMonth());
Assert.assertEquals("一月", date.getChineseMonth()); Assert.assertEquals("一月", date.getChineseMonth());
Assert.assertEquals("正月", date.getChineseMonthName()); Assert.assertEquals("正月", date.getChineseMonthName());
Assert.assertEquals(1, date.getDay());
Assert.assertEquals("初一", date.getChineseDay()); Assert.assertEquals("初一", date.getChineseDay());
Assert.assertEquals("庚子", date.getCyclical()); Assert.assertEquals("庚子", date.getCyclical());
Assert.assertEquals("", date.getChineseZodiac()); Assert.assertEquals("", date.getChineseZodiac());
Assert.assertEquals("春节", date.getFestivals()); Assert.assertEquals("春节", date.getFestivals());
@ -21,5 +27,13 @@ public class ChineseDateTest {
Assert.assertEquals("己亥猪年 腊月二十", date.toString()); Assert.assertEquals("己亥猪年 腊月二十", date.toString());
date = new ChineseDate(DateUtil.parseDate("2020-01-24")); date = new ChineseDate(DateUtil.parseDate("2020-01-24"));
Assert.assertEquals("己亥猪年 腊月三十", date.toString()); Assert.assertEquals("己亥猪年 腊月三十", date.toString());
Assert.assertEquals("2019-12-30", date.toStringNormal());
}
@Test
public void toStringNormalTest(){
ChineseDate date = new ChineseDate(DateUtil.parseDate("2020-03-1"));
Assert.assertEquals("2020-02-08", date.toStringNormal());
} }
} }

View File

@ -2,68 +2,127 @@ package cn.hutool.http;
/** /**
* Http 头域 * Http 头域
* @author Looly
* *
* @author Looly
*/ */
public enum Header { public enum Header {
//------------------------------------------------------------- 通用头域 //------------------------------------------------------------- 通用头域
/**提供日期和时间标志,说明报文是什么时间创建的*/ /**
* 提供验证头
*/
AUTHORIZATION("Authorization"),
/**
* 提供日期和时间标志,说明报文是什么时间创建的
*/
DATE("Date"), DATE("Date"),
/**允许客户端和服务器指定与请求/响应连接有关的选项*/ /**
* 允许客户端和服务器指定与请求/响应连接有关的选项
*/
CONNECTION("Connection"), CONNECTION("Connection"),
/**给出发送端使用的MIME版本*/ /**
* 给出发送端使用的MIME版本
*/
MIME_VERSION("MIME-Version"), MIME_VERSION("MIME-Version"),
/**如果报文采用了分块传输编码(chunked transfer encoding) 方式,就可以用这个首部列出位于报文拖挂(trailer)部分的首部集合*/ /**
* 如果报文采用了分块传输编码(chunked transfer encoding) 方式,就可以用这个首部列出位于报文拖挂(trailer)部分的首部集合
*/
TRAILER("Trailer"), TRAILER("Trailer"),
/**告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式*/ /**
* 告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式
*/
TRANSFER_ENCODING("Transfer-Encoding"), TRANSFER_ENCODING("Transfer-Encoding"),
/**给出了发送端可能想要"升级"使用的新版本和协议*/ /**
* 给出了发送端可能想要"升级"使用的新版本和协议
*/
UPGRADE("Upgrade"), UPGRADE("Upgrade"),
/**显示了报文经过的中间节点*/ /**
* 显示了报文经过的中间节点
*/
VIA("Via"), VIA("Via"),
/**指定请求和响应遵循的缓存机制*/ /**
* 指定请求和响应遵循的缓存机制
*/
CACHE_CONTROL("Cache-Control"), CACHE_CONTROL("Cache-Control"),
/**用来包含实现特定的指令最常用的是Pragma:no-cache。在HTTP/1.1协议中它的含义和Cache- Control:no-cache相同*/ /**
* 用来包含实现特定的指令最常用的是Pragma:no-cache在HTTP/1.1协议中它的含义和Cache- Control:no-cache相同
*/
PRAGMA("Pragma"), PRAGMA("Pragma"),
/**请求表示提交内容类型或返回返回内容的MIME类型*/ /**
* 请求表示提交内容类型或返回返回内容的MIME类型
*/
CONTENT_TYPE("Content-Type"), CONTENT_TYPE("Content-Type"),
//------------------------------------------------------------- 请求头域 //------------------------------------------------------------- 请求头域
/**指定请求资源的Intenet主机和端口号必须表示请求url的原始服务器或网关的位置。HTTP/1.1请求必须包含主机头域否则系统会以400状态码返回*/ /**
* 指定请求资源的Intenet主机和端口号必须表示请求url的原始服务器或网关的位置HTTP/1.1请求必须包含主机头域否则系统会以400状态码返回
*/
HOST("Host"), HOST("Host"),
/**允许客户端指定请求uri的源资源地址这可以允许服务器生成回退链表可用来登陆、优化cache等。他也允许废除的或错误的连接由于维护的目的被 追踪。如果请求的uri没有自己的uri地址Referer不能被发送。如果指定的是部分uri地址则此地址应该是一个相对地址*/ /**
* 允许客户端指定请求uri的源资源地址这可以允许服务器生成回退链表可用来登陆优化cache等他也允许废除的或错误的连接由于维护的目的被 追踪如果请求的uri没有自己的uri地址Referer不能被发送如果指定的是部分uri地址则此地址应该是一个相对地址
*/
REFERER("Referer"), REFERER("Referer"),
/** 指定请求的域 */ /**
* 指定请求的域
*/
ORIGIN("Origin"), ORIGIN("Origin"),
/**HTTP客户端运行的浏览器类型的详细信息。通过该头部信息web服务器可以判断到当前HTTP请求的客户端浏览器类别*/ /**
* HTTP客户端运行的浏览器类型的详细信息通过该头部信息web服务器可以判断到当前HTTP请求的客户端浏览器类别
*/
USER_AGENT("User-Agent"), USER_AGENT("User-Agent"),
/**指定客户端能够接收的内容类型,内容类型中的先后次序表示客户端接收的先后次序*/ /**
* 指定客户端能够接收的内容类型内容类型中的先后次序表示客户端接收的先后次序
*/
ACCEPT("Accept"), ACCEPT("Accept"),
/**指定HTTP客户端浏览器用来展示返回信息所优先选择的语言*/ /**
* 指定HTTP客户端浏览器用来展示返回信息所优先选择的语言
*/
ACCEPT_LANGUAGE("Accept-Language"), ACCEPT_LANGUAGE("Accept-Language"),
/**指定客户端浏览器可以支持的web服务器返回内容压缩编码类型*/ /**
* 指定客户端浏览器可以支持的web服务器返回内容压缩编码类型
*/
ACCEPT_ENCODING("Accept-Encoding"), ACCEPT_ENCODING("Accept-Encoding"),
/**浏览器可以接受的字符编码集*/ /**
* 浏览器可以接受的字符编码集
*/
ACCEPT_CHARSET("Accept-Charset"), ACCEPT_CHARSET("Accept-Charset"),
/**HTTP请求发送时会把保存在该请求域名下的所有cookie值一起发送给web服务器*/ /**
* HTTP请求发送时会把保存在该请求域名下的所有cookie值一起发送给web服务器
*/
COOKIE("Cookie"), COOKIE("Cookie"),
/**请求的内容长度*/ /**
* 请求的内容长度
*/
CONTENT_LENGTH("Content-Length"), CONTENT_LENGTH("Content-Length"),
//------------------------------------------------------------- 响应头域 //------------------------------------------------------------- 响应头域
/**Cookie*/ /**
* 提供WWW验证响应头
*/
WWW_AUTHENTICATE("WWW-Authenticate"),
/**
* Cookie
*/
SET_COOKIE("Set-Cookie"), SET_COOKIE("Set-Cookie"),
/**Content-Encoding*/ /**
* Content-Encoding
*/
CONTENT_ENCODING("Content-Encoding"), CONTENT_ENCODING("Content-Encoding"),
/**Content-Disposition*/ /**
* Content-Disposition
*/
CONTENT_DISPOSITION("Content-Disposition"), CONTENT_DISPOSITION("Content-Disposition"),
/**ETag*/ /**
* ETag
*/
ETAG("ETag"), ETAG("ETag"),
/** 重定向指示到的URL */ /**
* 重定向指示到的URL
*/
LOCATION("Location"); LOCATION("Location");
private String value; private String value;
Header(String value) { Header(String value) {
this.value = value; this.value = value;
} }

View File

@ -957,12 +957,20 @@ public class HttpRequest extends HttpBase<HttpRequest> {
public HttpRequest basicAuth(String username, String password) { public HttpRequest basicAuth(String username, String password) {
final String data = username.concat(":").concat(password); final String data = username.concat(":").concat(password);
final String base64 = Base64.encode(data, charset); final String base64 = Base64.encode(data, charset);
return auth("Basic " + base64);
header("Authorization", "Basic " + base64, true);
return this;
} }
/**
* 验证简单插入Authorization头
*
* @param content 验证内容
* @return HttpRequest
* @since 5.2.4
*/
public HttpRequest auth(String content) {
header(Header.AUTHORIZATION, content, true);
return this;
}
// ---------------------------------------------------------------- Private method start // ---------------------------------------------------------------- Private method start
/** /**

View File

@ -8,6 +8,7 @@ import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.bean.copier.ValueProvider; import cn.hutool.core.bean.copier.ValueProvider;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.getter.OptNullBasicTypeFromStringGetter; import cn.hutool.core.getter.OptNullBasicTypeFromStringGetter;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log; import cn.hutool.log.Log;
@ -42,14 +43,25 @@ public abstract class AbsSetting implements OptNullBasicTypeFromStringGetter<Str
* @param key KEY * @param key KEY
* @param group 分组 * @param group 分组
* @param defaultValue 默认值 * @param defaultValue 默认值
* @return 默认值 * @return 如果字符串为{@code null}返回默认值
*/ */
public String getStr(String key, String group, String defaultValue) { public String getStr(String key, String group, String defaultValue) {
final String value = getByGroup(key, group); final String value = getByGroup(key, group);
if (value == null) { return ObjectUtil.defaultIfNull(value, defaultValue);
return defaultValue; }
}
return value; /**
* 获得字符串类型值如果字符串为{@code null}或者""返回默认值
*
* @param key KEY
* @param group 分组
* @param defaultValue 默认值
* @return 如果字符串为{@code null}或者""返回默认值
* @since 5.24
*/
public String getStrNotEmpty(String key, String group, String defaultValue) {
final String value = getByGroup(key, group);
return ObjectUtil.defaultIfEmpty(value, defaultValue);
} }
/** /**
@ -268,7 +280,7 @@ public abstract class AbsSetting implements OptNullBasicTypeFromStringGetter<Str
* 将setting中的键值关系映射到对象中原理是调用对象对应的set方法<br> * 将setting中的键值关系映射到对象中原理是调用对象对应的set方法<br>
* 只支持基本类型的转换 * 只支持基本类型的转换
* *
* @param <T> Bean类型 * @param <T> Bean类型
* @param group 分组 * @param group 分组
* @param bean Bean对象 * @param bean Bean对象
* @return Bean * @return Bean
@ -292,9 +304,9 @@ public abstract class AbsSetting implements OptNullBasicTypeFromStringGetter<Str
* 将setting中的键值关系映射到对象中原理是调用对象对应的set方法<br> * 将setting中的键值关系映射到对象中原理是调用对象对应的set方法<br>
* 只支持基本类型的转换 * 只支持基本类型的转换
* *
* @param <T> Bean类型 * @param <T> Bean类型
* @param group 分组 * @param group 分组
* @param beanClass Bean类型 * @param beanClass Bean类型
* @return Bean * @return Bean
* @since 5.0.6 * @since 5.0.6
*/ */
@ -306,7 +318,7 @@ public abstract class AbsSetting implements OptNullBasicTypeFromStringGetter<Str
* 将setting中的键值关系映射到对象中原理是调用对象对应的set方法<br> * 将setting中的键值关系映射到对象中原理是调用对象对应的set方法<br>
* 只支持基本类型的转换 * 只支持基本类型的转换
* *
* @param <T> bean类型 * @param <T> bean类型
* @param bean Bean * @param bean Bean
* @return Bean * @return Bean
*/ */
@ -318,7 +330,7 @@ public abstract class AbsSetting implements OptNullBasicTypeFromStringGetter<Str
* 将setting中的键值关系映射到对象中原理是调用对象对应的set方法<br> * 将setting中的键值关系映射到对象中原理是调用对象对应的set方法<br>
* 只支持基本类型的转换 * 只支持基本类型的转换
* *
* @param <T> bean类型 * @param <T> bean类型
* @param beanClass Bean类型 * @param beanClass Bean类型
* @return Bean * @return Bean
* @since 5.0.6 * @since 5.0.6