Java版农历、节气
This commit is contained in:
+2
-2
@@ -10,6 +10,6 @@ target
|
||||
*.springBeans
|
||||
.gradle
|
||||
build
|
||||
.buildpath
|
||||
dependency-reduced-pom.xml
|
||||
/src
|
||||
|
||||
/src
|
||||
@@ -88,5 +88,30 @@
|
||||
<version>17.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- jsoup html解析类库 -->
|
||||
<dependency>
|
||||
<groupId>org.jsoup</groupId>
|
||||
<artifactId>jsoup</artifactId>
|
||||
<version>1.7.3</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
<version>2.6</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.ning</groupId>
|
||||
<artifactId>async-http-client</artifactId>
|
||||
<version>1.8.13</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -0,0 +1,280 @@
|
||||
package net.aimeizi.tutorials;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
|
||||
/**
|
||||
* 转农历
|
||||
* @author
|
||||
*/
|
||||
public class CalendarToLauar {
|
||||
|
||||
private static int monCyl, dayCyl, yearCyl;
|
||||
|
||||
private static int year, month, day;
|
||||
|
||||
private static boolean isLeap;
|
||||
|
||||
private static int[] lunarInfo = { 0x04bd8, 0x04ae0, 0x0a570, 0x054d5,
|
||||
0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, 0x04ae0,
|
||||
0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2,
|
||||
0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40,
|
||||
0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, 0x06566, 0x0d4a0,
|
||||
0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7,
|
||||
0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0,
|
||||
0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550, 0x15355,
|
||||
0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0,
|
||||
0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263,
|
||||
0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0,
|
||||
0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6, 0x095b0,
|
||||
0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46,
|
||||
0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50,
|
||||
0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, 0x0c960, 0x0d954,
|
||||
0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0,
|
||||
0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0,
|
||||
0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0, 0x0ad50,
|
||||
0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,
|
||||
0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6,
|
||||
0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2, 0x049b0,
|
||||
0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0 };
|
||||
|
||||
private static int[] solarMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,30, 31 };
|
||||
|
||||
private static String[] Gan = { "甲", "乙", "丙", "丁", "戊", "己", "庚", "辛",
|
||||
"壬", "癸" };
|
||||
|
||||
private static String[] Zhi = { "子", "丑", "寅", "卯", "辰", "巳", "午", "未",
|
||||
"申", "酉", "戌", "亥" };
|
||||
|
||||
private static String[] Animals = { "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊",
|
||||
"猴", "鸡", "狗", "猪" };
|
||||
|
||||
private static int[] sTermInfo = { 0, 21208, 42467, 63836, 85337, 107014,
|
||||
128867, 150921, 173149, 195551, 218072, 240693, 263343, 285989,
|
||||
308563, 331033, 353350, 375494, 397447, 419210, 440795, 462224,
|
||||
483532, 504758 };
|
||||
|
||||
private static String[] nStr1 = { "日", "一", "二", "三", "四", "五", "六", "七",
|
||||
"八", "九", "十" };
|
||||
|
||||
private static String[] nStr2 = { "初", "十", "廿十", "卅十", " " };
|
||||
|
||||
private static String[] monthNong = { "正", "正", "二", "三", "四", "五", "六",
|
||||
"七", "八", "九", "十", "十一", "十二" };
|
||||
|
||||
private static String[] yearName = { "零", "壹", "贰", "叁", "肆", "伍", "陆",
|
||||
"柒", "捌", "玖" };
|
||||
|
||||
|
||||
|
||||
//====================================== 传回农历 y年的总天数
|
||||
private static int lYearDays(int y) {
|
||||
int i;
|
||||
int sum = 348; //29*12
|
||||
for (i = 0x8000; i > 0x8; i >>= 1) {
|
||||
//OurLog.debug("i="+i);
|
||||
sum += (lunarInfo[y - 1900] & i) == 0 ? 0 : 1; //大月+1天
|
||||
}
|
||||
return (sum + leapDays(y)); //+闰月的天数
|
||||
}
|
||||
|
||||
//====================================== 传回农历 y年闰月的天数
|
||||
private static int leapDays(int y) {
|
||||
if (leapMonth(y) != 0)
|
||||
return ((lunarInfo[y - 1900] & 0x10000) == 0 ? 29 : 30);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
//====================================== 传回农历 y年闰哪个月 1-12 , 没闰传回 0
|
||||
private static int leapMonth(int y) {
|
||||
return (lunarInfo[y - 1900] & 0xf);
|
||||
}
|
||||
|
||||
//====================================== 传回农历 y年m月的总天数
|
||||
private static int monthDays(int y, int m) {
|
||||
return ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0 ? 29 : 30);
|
||||
}
|
||||
|
||||
//====================================== 算出农历, 传入日期物件, 传回农历日期物件
|
||||
// 该物件属性有 .year .month .day .isLeap .yearCyl .dayCyl .monCyl
|
||||
private static void Lunar1(Date objDate) {
|
||||
int i, leap = 0, temp = 0;
|
||||
Calendar cl = Calendar.getInstance();
|
||||
cl.set(1900, 0, 31);
|
||||
Date baseDate = cl.getTime();
|
||||
|
||||
int offset = (int) ((objDate.getTime() - baseDate.getTime()) / 86400000); //天数(86400000=24*60*60*1000)
|
||||
dayCyl = offset + 40;
|
||||
monCyl = 14;
|
||||
//得到年数
|
||||
for (i = 1900; i < 2050 && offset > 0; i++) {
|
||||
temp = lYearDays(i); //农历每年天数
|
||||
offset -= temp;
|
||||
monCyl += 12;
|
||||
}
|
||||
if (offset < 0) {
|
||||
offset += temp;
|
||||
i--;
|
||||
monCyl -= 12;
|
||||
}
|
||||
year = i; //农历年份
|
||||
yearCyl = i - 1864; //1864年是甲子年
|
||||
leap = leapMonth(i); //闰哪个月
|
||||
isLeap = false;
|
||||
for (i = 1; i < 13 && offset > 0; i++) {
|
||||
//闰月
|
||||
if (leap > 0 && i == (leap + 1) && isLeap == false) {
|
||||
--i;
|
||||
isLeap = true;
|
||||
temp = leapDays(year);
|
||||
} else {
|
||||
temp = monthDays(year, i);
|
||||
}
|
||||
//解除闰月
|
||||
if (isLeap == true && i == (leap + 1))
|
||||
isLeap = false;
|
||||
offset -= temp;
|
||||
if (isLeap == false)
|
||||
monCyl++;
|
||||
}
|
||||
if (offset == 0 && leap > 0 && i == leap + 1)
|
||||
if (isLeap) {
|
||||
isLeap = false;
|
||||
} else {
|
||||
isLeap = true;
|
||||
--i;
|
||||
--monCyl;
|
||||
}
|
||||
if (offset < 0) {
|
||||
offset += temp;
|
||||
--i;
|
||||
--monCyl;
|
||||
}
|
||||
month = i; //农历月份
|
||||
day = offset + 1; //农历天份
|
||||
//System.out.println(day);
|
||||
}
|
||||
|
||||
private static int getYear() {
|
||||
return (year);
|
||||
}
|
||||
|
||||
private static int getMonth() {
|
||||
return (month);
|
||||
}
|
||||
|
||||
private static int getDay() {
|
||||
return (day);
|
||||
}
|
||||
|
||||
private static int getMonCyl() {
|
||||
return (monCyl);
|
||||
}
|
||||
|
||||
private static int getYearCyl() {
|
||||
return (yearCyl);
|
||||
}
|
||||
|
||||
private static int getDayCyl() {
|
||||
return (dayCyl);
|
||||
}
|
||||
|
||||
private static boolean getIsLeap() {
|
||||
return (isLeap);
|
||||
}
|
||||
|
||||
//============================== 传入 offset 传回干支, 0=甲子
|
||||
private static String cyclical(int num) {
|
||||
return (Gan[num % 10] + Zhi[num % 12]);
|
||||
}
|
||||
|
||||
//====================== 中文日期
|
||||
private static String cDay(int d) {
|
||||
String s;
|
||||
switch (d) {
|
||||
case 10:
|
||||
s = "初十";
|
||||
break;
|
||||
case 20:
|
||||
s = "二十";
|
||||
break;
|
||||
case 30:
|
||||
s = "三十";
|
||||
break;
|
||||
default:
|
||||
s = nStr2[(int) (d / 10)];//取商
|
||||
s += nStr1[d % 10];//取余
|
||||
}
|
||||
return (s);
|
||||
}
|
||||
|
||||
private static String cYear(int y) {
|
||||
String s = " ";
|
||||
int d;
|
||||
while (y > 0) {
|
||||
d = y % 10;
|
||||
y = (y - d) / 10;
|
||||
s = yearName[d] + s;
|
||||
}
|
||||
return (s);
|
||||
}
|
||||
|
||||
public static String getLunar(String year, String month, String day) {
|
||||
|
||||
Date sDObj;
|
||||
String s;
|
||||
int SY, SM, SD;
|
||||
|
||||
int sy;
|
||||
SY = Integer.parseInt(year);
|
||||
SM = Integer.parseInt(month);
|
||||
SD = Integer.parseInt(day);
|
||||
sy = (SY - 4) % 12;
|
||||
Calendar cl = Calendar.getInstance();
|
||||
cl.set(SY, SM - 1, SD);
|
||||
sDObj = cl.getTime();
|
||||
|
||||
//日期
|
||||
Lunar1(sDObj); //农历
|
||||
s = "农历 " + "【" + Animals[sy] + "】" + cYear(getYear()) + "年" + " ";
|
||||
|
||||
s += (getIsLeap() ? "闰" : "") + monthNong[getMonth()] + "月"
|
||||
+ (monthDays(getYear(), getMonth()) == 29 ? "小" : "大");
|
||||
s += cDay(getDay()) + " ";
|
||||
s += cyclical(getYearCyl()) + "年" + cyclical(getMonCyl()) + "月"
|
||||
+ cyclical(getDayCyl()) + "日";
|
||||
return s;
|
||||
}
|
||||
public static String getSimpleLunar(String year, String month, String day)
|
||||
{
|
||||
|
||||
Date sDObj;
|
||||
String s;
|
||||
int SY, SM, SD;
|
||||
|
||||
int sy;
|
||||
|
||||
SY = Integer.parseInt(year);
|
||||
SM = Integer.parseInt(month);
|
||||
SD = Integer.parseInt(day);
|
||||
sy = (SY - 4) % 12;
|
||||
Calendar cl = Calendar.getInstance();
|
||||
cl.set(SY, SM - 1, SD);
|
||||
sDObj = cl.getTime();
|
||||
|
||||
//日期
|
||||
Lunar1(sDObj); //农历
|
||||
s =monthNong[getMonth()] + "月" + cDay(getDay()) + "";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(getLunar("2014", "8", "1"));//含天干地支的农历格式 (农历 【马】贰零壹肆 年 七月小初六 甲午年壬申月甲辰日)
|
||||
System.out.println(CalendarToLauar.getSimpleLunar("2014", "8", "1"));//简短的农历格式 (七月初六)
|
||||
System.out.println(SolarTerm.getSoralTerm(2014,8,7));//获取节气 (立秋)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
package net.aimeizi.tutorials;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
|
||||
|
||||
/**
|
||||
* 下载HTML中的非本地图片,并替换内容
|
||||
* @author 冯靖
|
||||
*
|
||||
*/
|
||||
public class HTMLImageFetcher {
|
||||
|
||||
protected final static String img_path = "target/";//下载后图片存放目录
|
||||
|
||||
private final static String user_agent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0";
|
||||
|
||||
protected final static SimpleDateFormat FMT_FN = new SimpleDateFormat("yyyyMM/ddHHmmss_");
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
String html = "这张图片很漂亮啊!"
|
||||
+ "<img src='https://avatars3.githubusercontent.com/u/887836?v=1&s=460' alt='github'/>"//演示远程图片,抓取到本地,并修改为本地图片路径
|
||||
+ "<img src='http://su.bdimg.com/static/superplus/img/logo_white.png' alt='baidu'/>"
|
||||
+ " ,太帅了!<img src='/images/logo.gif' alt='oschina'/>";//本地图片,则不做处理
|
||||
System.out.println(fetchHTML_Images(html));
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载HTML文档中的所有图片
|
||||
* @param html
|
||||
* @return
|
||||
*/
|
||||
protected static String fetchHTML_Images(String html) {
|
||||
if (StringUtils.isBlank(html)) {
|
||||
return html;
|
||||
}
|
||||
HashMap<String, String> img_urls = new HashMap<String, String>();
|
||||
Document doc = Jsoup.parse(html);
|
||||
Elements imgs = doc.select("img");
|
||||
for (int i = 0; i < imgs.size(); i++) {
|
||||
Element img = imgs.get(i);
|
||||
String src = img.attr("src");
|
||||
if (!src.startsWith("/")) {
|
||||
try {
|
||||
URL imgUrl = new URL(src);
|
||||
String imgHost = imgUrl.getHost().toLowerCase();
|
||||
if (!imgHost.endsWith(".oschina.net")) {//排除域名为oschina.net的图片(如果图片地址中包含oschina.net,则不进行抓取)
|
||||
String new_src = img_urls.get(src);
|
||||
if (new_src == null) {
|
||||
new_src = fetchImageViaHttp(imgUrl);
|
||||
img_urls.put(src, new_src);
|
||||
}
|
||||
img.attr("src", new_src);
|
||||
}
|
||||
} catch (MalformedURLException e) {
|
||||
img.remove();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
img.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
return doc.body().html();
|
||||
}
|
||||
|
||||
private static String fetchImageViaHttp(URL imgUrl) throws IOException {
|
||||
String sURL = imgUrl.toString();
|
||||
String imgFile = imgUrl.getPath();
|
||||
HttpURLConnection conn = (HttpURLConnection) imgUrl.openConnection();
|
||||
String uri = null;
|
||||
try {
|
||||
conn.setAllowUserInteraction(false);
|
||||
conn.setDoOutput(true);
|
||||
conn.addRequestProperty("Cache-Control", "no-cache");
|
||||
conn.addRequestProperty("User-Agent", user_agent);
|
||||
conn.addRequestProperty("Referer", sURL.substring(0, sURL.indexOf('/', sURL.indexOf('.')) + 1));
|
||||
conn.connect();
|
||||
|
||||
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
|
||||
return null;
|
||||
}
|
||||
|
||||
InputStream imgData = conn.getInputStream();
|
||||
String ext = FilenameUtils.getExtension(imgFile).toLowerCase();
|
||||
|
||||
if (!isImageFile("aa." + ext)) {
|
||||
ext = "jpg";
|
||||
}
|
||||
|
||||
uri = FMT_FN.format(new Date()) + RandomStringUtils.randomAlphanumeric(4) + '.' + ext;
|
||||
|
||||
System.err.println(uri);
|
||||
|
||||
File fileDest = new File(img_path + uri);
|
||||
if (!fileDest.getParentFile().exists()) {
|
||||
fileDest.getParentFile().mkdirs();
|
||||
}
|
||||
|
||||
FileOutputStream fos = new FileOutputStream(fileDest);
|
||||
|
||||
try {
|
||||
IOUtils.copy(imgData, fos);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(imgData);
|
||||
IOUtils.closeQuietly(fos);
|
||||
}
|
||||
|
||||
} finally {
|
||||
conn.disconnect();
|
||||
}
|
||||
return img_path + uri;
|
||||
}
|
||||
|
||||
private static boolean isImageFile(String fileName) {
|
||||
String[] imgSuffixs = {
|
||||
".gif", ".jpg", ".jpeg", ".png",
|
||||
".tiff", ".bmp",
|
||||
};
|
||||
for(String suffix : imgSuffixs) {
|
||||
if(fileName.endsWith(suffix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
package net.aimeizi.tutorials;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
public class LunarCalendar {
|
||||
|
||||
private int year; //农历的年份
|
||||
private int month;
|
||||
private int day;
|
||||
private String lunarMonth; //农历的月份
|
||||
private boolean leap;
|
||||
public int leapMonth = 0; //闰的是哪个月
|
||||
|
||||
final static String chineseNumber[] = { "一", "二", "三", "四", "五", "六", "七","八", "九", "十", "十一", "十二" };
|
||||
|
||||
static SimpleDateFormat chineseDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
|
||||
|
||||
final static long[] lunarInfo = new long[] { 0x04bd8, 0x04ae0, 0x0a570,
|
||||
0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,
|
||||
0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0,
|
||||
0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50,
|
||||
0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, 0x06566,
|
||||
0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0,
|
||||
0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4,
|
||||
0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550,
|
||||
0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950,
|
||||
0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260,
|
||||
0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, 0x04ad0,
|
||||
0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6,
|
||||
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40,
|
||||
0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0, 0x074a3,
|
||||
0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0, 0x0c960,
|
||||
0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0,
|
||||
0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9,
|
||||
0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0,
|
||||
0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65,
|
||||
0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0,
|
||||
0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2,
|
||||
0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0 };
|
||||
|
||||
//农历部分假日
|
||||
final static String[] lunarHoliday = new String[]{
|
||||
"0101 春节",
|
||||
"0115 元宵",
|
||||
"0505 端午",
|
||||
"0707 七夕情人",
|
||||
"0715 中元",
|
||||
"0815 中秋",
|
||||
"0909 重阳",
|
||||
"1208 腊八",
|
||||
"1224 小年",
|
||||
"0100 除夕"
|
||||
};
|
||||
|
||||
//公历部分节假日
|
||||
final static String[] solarHoliday = new String[]{
|
||||
"0101 元旦",
|
||||
"0214 情人",
|
||||
"0308 妇女",
|
||||
"0312 植树",
|
||||
"0315 消费者权益日",
|
||||
"0401 愚人",
|
||||
"0501 劳动",
|
||||
"0504 青年",
|
||||
"0512 护士",
|
||||
"0601 儿童",
|
||||
"0701 建党",
|
||||
"0801 建军",
|
||||
"0808 父亲",
|
||||
"0909 毛泽东逝世纪念",
|
||||
"0910 教师",
|
||||
"0928 孔子诞辰",
|
||||
"1001 国庆",
|
||||
"1006 老人",
|
||||
"1024 联合国日",
|
||||
"1112 孙中山诞辰纪念",
|
||||
"1220 澳门回归纪念",
|
||||
"1225 圣诞",
|
||||
"1226 毛泽东诞辰纪念"
|
||||
};
|
||||
|
||||
// ====== 传回农历 y年的总天数
|
||||
final private static int yearDays(int y) {
|
||||
int i, sum = 348;
|
||||
for (i = 0x8000; i > 0x8; i >>= 1) {
|
||||
if ((lunarInfo[y - 1900] & i) != 0)
|
||||
sum += 1;
|
||||
}
|
||||
return (sum + leapDays(y));
|
||||
}
|
||||
|
||||
// ====== 传回农历 y年闰月的天数
|
||||
final private static int leapDays(int y) {
|
||||
if (leapMonth(y) != 0) {
|
||||
if ((lunarInfo[y - 1900] & 0x10000) != 0)
|
||||
return 30;
|
||||
else
|
||||
return 29;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ====== 传回农历 y年闰哪个月 1-12 , 没闰传回 0
|
||||
final private static int leapMonth(int y) {
|
||||
return (int) (lunarInfo[y - 1900] & 0xf);
|
||||
}
|
||||
|
||||
// ====== 传回农历 y年m月的总天数
|
||||
final private static int monthDays(int y, int m) {
|
||||
if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0)
|
||||
return 29;
|
||||
else
|
||||
return 30;
|
||||
}
|
||||
|
||||
// ====== 传回农历 y年的生肖
|
||||
final public String animalsYear(int year) {
|
||||
final String[] Animals = new String[] { "鼠", "牛", "虎", "兔", "龙", "蛇",
|
||||
"马", "羊", "猴", "鸡", "狗", "猪" };
|
||||
return Animals[(year - 4) % 12];
|
||||
}
|
||||
|
||||
// ====== 传入 月日的offset 传回干支, 0=甲子
|
||||
final private static String cyclicalm(int num) {
|
||||
final String[] Gan = new String[] { "甲", "乙", "丙", "丁", "戊", "己", "庚",
|
||||
"辛", "壬", "癸" };
|
||||
final String[] Zhi = new String[] { "子", "丑", "寅", "卯", "辰", "巳", "午",
|
||||
"未", "申", "酉", "戌", "亥" };
|
||||
return (Gan[num % 10] + Zhi[num % 12]);
|
||||
}
|
||||
|
||||
// ====== 传入 offset 传回干支, 0=甲子
|
||||
final public String cyclical(int year) {
|
||||
int num = year - 1900 + 36;
|
||||
return (cyclicalm(num));
|
||||
}
|
||||
|
||||
public static String getChinaDayString(int day) {
|
||||
String chineseTen[] = { "初", "十", "廿", "卅" };
|
||||
int n = day % 10 == 0 ? 9 : day % 10 - 1;
|
||||
if (day > 30)
|
||||
return "";
|
||||
if (day == 10)
|
||||
return "初十";
|
||||
else
|
||||
return chineseTen[day / 10] + chineseNumber[n];
|
||||
}
|
||||
|
||||
/**
|
||||
* 传出y年m月d日对应的农历.
|
||||
* yearCyl3:农历年与1864的相差数
|
||||
* monCyl4:从1900年1月31日以来,闰月数
|
||||
* dayCyl5:与1900年1月31日相差的天数,再加40
|
||||
* isday: 这个参数为false---日期为节假日时,阴历日期就返回节假日 ,true---不管日期是否为节假日依然返回这天对应的阴历日期
|
||||
* @param cal
|
||||
* @return
|
||||
*/
|
||||
public String getLunarDate(int year_log, int month_log, int day_log, boolean isday) {
|
||||
int yearCyl, monCyl, dayCyl;
|
||||
String nowadays;
|
||||
Date baseDate = null;
|
||||
Date nowaday = null;
|
||||
try {
|
||||
baseDate = chineseDateFormat.parse("1900年1月31日");
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
nowadays = year_log + "年" + month_log + "月" + day_log + "日";
|
||||
try {
|
||||
nowaday = chineseDateFormat.parse(nowadays);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// 求出和1900年1月31日相差的天数
|
||||
int offset = (int) ((nowaday.getTime() - baseDate.getTime()) / 86400000L);
|
||||
dayCyl = offset + 40;
|
||||
monCyl = 14;
|
||||
|
||||
// 用offset减去每农历年的天数
|
||||
// 计算当天是农历第几天
|
||||
// i最终结果是农历的年份
|
||||
// offset是当年的第几天
|
||||
int iYear, daysOfYear = 0;
|
||||
for (iYear = 1900; iYear < 10000 && offset > 0; iYear++) {
|
||||
daysOfYear = yearDays(iYear);
|
||||
offset -= daysOfYear;
|
||||
monCyl += 12;
|
||||
}
|
||||
if (offset < 0) {
|
||||
offset += daysOfYear;
|
||||
iYear--;
|
||||
monCyl -= 12;
|
||||
}
|
||||
// 农历年份
|
||||
year = iYear;
|
||||
setYear(year); //设置公历对应的农历年份
|
||||
|
||||
yearCyl = iYear - 1864;
|
||||
leapMonth = leapMonth(iYear); // 闰哪个月,1-12
|
||||
leap = false;
|
||||
|
||||
// 用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
|
||||
int iMonth, daysOfMonth = 0;
|
||||
for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) {
|
||||
// 闰月
|
||||
if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) {
|
||||
--iMonth;
|
||||
leap = true;
|
||||
daysOfMonth = leapDays(year);
|
||||
} else
|
||||
daysOfMonth = monthDays(year, iMonth);
|
||||
|
||||
offset -= daysOfMonth;
|
||||
// 解除闰月
|
||||
if (leap && iMonth == (leapMonth + 1))
|
||||
leap = false;
|
||||
if (!leap)
|
||||
monCyl++;
|
||||
}
|
||||
// offset为0时,并且刚才计算的月份是闰月,要校正
|
||||
if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) {
|
||||
if (leap) {
|
||||
leap = false;
|
||||
} else {
|
||||
leap = true;
|
||||
--iMonth;
|
||||
--monCyl;
|
||||
}
|
||||
}
|
||||
// offset小于0时,也要校正
|
||||
if (offset < 0) {
|
||||
offset += daysOfMonth;
|
||||
--iMonth;
|
||||
--monCyl;
|
||||
}
|
||||
month = iMonth;
|
||||
setLunarMonth(chineseNumber[month - 1] + "月"); //设置对应的阴历月份
|
||||
day = offset + 1;
|
||||
|
||||
if(!isday){
|
||||
//如果日期为节假日则阴历日期则返回节假日
|
||||
for(int i = 0; i < solarHoliday.length; i++){
|
||||
//返回公历节假日名称
|
||||
String sd = solarHoliday[i].split(" ")[0]; //节假日的日期
|
||||
String sdv = solarHoliday[i].split(" ")[1]; //节假日的名称
|
||||
String smonth_v = month_log+"";
|
||||
String sday_v = day_log+"";
|
||||
String smd = "";
|
||||
if(month_log < 10){
|
||||
smonth_v = "0"+month_log;
|
||||
}
|
||||
if(day_log < 10){
|
||||
sday_v = "0"+day_log;
|
||||
}
|
||||
smd = smonth_v+sday_v;
|
||||
if(sd.trim().equals(smd.trim())){
|
||||
return sdv;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < lunarHoliday.length; i++){
|
||||
//返回农历节假日名称
|
||||
String ld =lunarHoliday[i].split(" ")[0]; //节假日的日期
|
||||
String ldv = lunarHoliday[i].split(" ")[1]; //节假日的名称
|
||||
String lmonth_v = month+"";
|
||||
String lday_v = day+"";
|
||||
String lmd = "";
|
||||
if(month < 10){
|
||||
lmonth_v = "0"+month;
|
||||
}
|
||||
if(day < 10){
|
||||
lday_v = "0"+day;
|
||||
}
|
||||
lmd = lmonth_v+lday_v;
|
||||
if(ld.trim().equals(lmd.trim())){
|
||||
return ldv;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (day == 1)
|
||||
return chineseNumber[month - 1] + "月";
|
||||
else
|
||||
return getChinaDayString(day);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(new LunarCalendar().getLunarDate(2014, 8, 2,false));
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
if (chineseNumber[month - 1] == "一" && getChinaDayString(day) == "初一")
|
||||
return "农历" + year + "年";
|
||||
else if (getChinaDayString(day) == "初一")
|
||||
return chineseNumber[month - 1] + "月";
|
||||
else
|
||||
return getChinaDayString(day);
|
||||
// return year + "年" + (leap ? "闰" : "") + chineseNumber[month - 1] + "月" + getChinaDayString(day);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getLeapMonth() {
|
||||
return leapMonth;
|
||||
}
|
||||
|
||||
public void setLeapMonth(int leapMonth) {
|
||||
this.leapMonth = leapMonth;
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到当前日期对应的阴历月份
|
||||
* @return
|
||||
*/
|
||||
public String getLunarMonth() {
|
||||
return lunarMonth;
|
||||
}
|
||||
|
||||
public void setLunarMonth(String lunarMonth) {
|
||||
this.lunarMonth = lunarMonth;
|
||||
}
|
||||
|
||||
/**
|
||||
* 得到当前年对应的农历年份
|
||||
* @return
|
||||
*/
|
||||
public int getYear() {
|
||||
return year;
|
||||
}
|
||||
|
||||
public void setYear(int year) {
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package net.aimeizi.tutorials;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 显示友好的时间
|
||||
*
|
||||
* @author 冯靖
|
||||
*
|
||||
*/
|
||||
public class RelativeTime {
|
||||
|
||||
|
||||
public static String timeAgo(String timeStr) {
|
||||
Date date = null;
|
||||
try {
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
|
||||
date = format.parse(timeStr);
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
return "";
|
||||
}
|
||||
|
||||
long timeStamp = date.getTime();
|
||||
|
||||
Date currentTime = new Date();
|
||||
long currentTimeStamp = currentTime.getTime();
|
||||
long seconds = (currentTimeStamp - timeStamp) / 1000;
|
||||
|
||||
long minutes = Math.abs(seconds / 60);
|
||||
long hours = Math.abs(minutes / 60);
|
||||
long days = Math.abs(hours / 24);
|
||||
|
||||
if (seconds <= 15) {
|
||||
return "刚刚";
|
||||
} else if (seconds < 60) {
|
||||
return seconds + "秒前";
|
||||
} else if (seconds < 120) {
|
||||
return "1分钟前";
|
||||
} else if (minutes < 60) {
|
||||
return minutes + "分钟前";
|
||||
} else if (minutes < 120) {
|
||||
return "1小时前";
|
||||
} else if (hours < 24) {
|
||||
return hours + "小时前";
|
||||
} else if (hours < 24 * 2) {
|
||||
return "1天前";
|
||||
} else if (days < 7) {//一周以内
|
||||
return days + "天前";
|
||||
} else {
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日");
|
||||
String dateString = formatter.format(date);
|
||||
return dateString;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println(timeAgo("2014/07/31 22:35:59"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package net.aimeizi.tutorials;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.LineIterator;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
/**
|
||||
* Java敏感词过滤
|
||||
* @author 冯靖
|
||||
*
|
||||
*/
|
||||
public class SensitiveWord {
|
||||
|
||||
private final static File wordfilter = new File("src/main/resources/wordfilter.txt");
|
||||
|
||||
private static long lastModified = 0L;
|
||||
|
||||
private static List<String> words = new ArrayList<String>();
|
||||
|
||||
private static void _CheckReload(){
|
||||
if(wordfilter.lastModified() > lastModified){
|
||||
synchronized(SensitiveWord.class){
|
||||
try{
|
||||
lastModified = wordfilter.lastModified();
|
||||
LineIterator lines = FileUtils.lineIterator(wordfilter, "utf-8");
|
||||
while(lines.hasNext()){
|
||||
String line = lines.nextLine();
|
||||
if(StringUtils.isNotBlank(line))
|
||||
words.add(StringUtils.trim(line).toLowerCase());
|
||||
}
|
||||
}catch(IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查敏感字内容
|
||||
* @param contents
|
||||
*/
|
||||
public static String Check(String...contents) {
|
||||
if(!wordfilter.exists())
|
||||
return null;
|
||||
_CheckReload();
|
||||
for(String word : words){
|
||||
for(String content : contents)
|
||||
if(content!=null && content.indexOf(word) >= 0)
|
||||
return word;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<String> List() {
|
||||
_CheckReload();
|
||||
return words;
|
||||
}
|
||||
|
||||
public static void Add(String word) throws IOException {
|
||||
word = word.toLowerCase();
|
||||
if(!words.contains(word)){
|
||||
words.add(word);
|
||||
FileUtils.writeLines(wordfilter, "UTF-8", words);
|
||||
lastModified = wordfilter.lastModified();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Delete(String word) throws IOException {
|
||||
word = word.toLowerCase();
|
||||
words.remove(word);
|
||||
FileUtils.writeLines(wordfilter, "UTF-8", words);
|
||||
lastModified = wordfilter.lastModified();
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception{
|
||||
|
||||
String mgz = "法论功大法好!苍井空是世界的!";
|
||||
|
||||
System.out.println("-----------------------敏感字列表----------------------------");
|
||||
System.out.println(Arrays.toString(SensitiveWord.List().toArray()));
|
||||
System.out.println("----------------------------------------------------------");
|
||||
System.out.println("检查敏感字:"+SensitiveWord.Check(mgz));
|
||||
System.out.println("-----------------------敏感字词替换----------------------------");
|
||||
System.out.println(mgz.replace(SensitiveWord.Check(mgz), "*"));
|
||||
System.out.println("----------------------------------------------------------");
|
||||
System.out.println("添加敏感字:法论功");
|
||||
SensitiveWord.Add("法论功");
|
||||
System.out.println("-----------------------敏感字列表----------------------------");
|
||||
System.out.println(Arrays.toString(SensitiveWord.List().toArray()));
|
||||
System.out.println("----------------------------------------------------------");
|
||||
System.out.println("删除敏感字:法论功");
|
||||
SensitiveWord.Delete("法论功");
|
||||
System.out.println("-----------------------敏感字列表----------------------------");
|
||||
System.out.println(Arrays.toString(SensitiveWord.List().toArray()));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package net.aimeizi.tutorials;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 二十四节气
|
||||
* @author welcome
|
||||
*
|
||||
*/
|
||||
public class SolarTerm {
|
||||
|
||||
final static long[] STermInfo = new long[] { 0, 21208, 42467, 63836, 85337,
|
||||
107014, 128867, 150921, 173149, 195551, 218072, 240693, 263343,
|
||||
285989, 308563, 331033, 353350, 375494, 397447, 419210, 440795,
|
||||
462224, 483532, 504758 };
|
||||
|
||||
private static final String[] SolarTerm = new String[] { "小寒", "大寒", "立春",
|
||||
"雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑",
|
||||
"立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至" };
|
||||
|
||||
|
||||
/** 核心方法 根据日期得到节气 */
|
||||
public static String getSoralTerm(Date Date) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.setTime(Date);
|
||||
|
||||
int y = cal.get(Calendar.YEAR);
|
||||
int m = cal.get(Calendar.MONTH) + 1;
|
||||
int d = cal.get(Calendar.DAY_OF_MONTH);
|
||||
|
||||
return getSoralTerm(y, m, d);
|
||||
}
|
||||
|
||||
/** 核心方法 根据日期(y年m月d日得到节气 */
|
||||
public static String getSoralTerm(int y, int m, int d) {
|
||||
String solarTerms;
|
||||
if (d == sTerm(y, (m - 1) * 2))
|
||||
solarTerms = SolarTerm[(m - 1) * 2];
|
||||
else if (d == sTerm(y, (m - 1) * 2 + 1))
|
||||
solarTerms = SolarTerm[(m - 1) * 2 + 1];
|
||||
else {
|
||||
// 到这里说明非节气时间
|
||||
solarTerms = "";
|
||||
}
|
||||
return solarTerms;
|
||||
}
|
||||
|
||||
// ===== y年的第n个节气为几日(从小寒起算)
|
||||
private static int sTerm(int y, int n) {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.set(1900, 0, 6, 2, 5, 0);
|
||||
long temp = cal.getTime().getTime();
|
||||
cal.setTime(new Date((long) ((31556925974.7 * (y - 1900) + STermInfo[n] * 60000L) + temp)));
|
||||
return cal.get(Calendar.DAY_OF_MONTH);
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(getSoralTerm(2014,8,7));//获取节气 (立秋)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
毛
|
||||
毛线
|
||||
毛泽东
|
||||
苍井空
|
||||
Reference in New Issue
Block a user