java 和 mysql 获取周 星期 的第一天 最后一天 或者 月的 日期(字符串转日期,日期转字符串,日期加减)
2016-05-05 15:41
831 查看
获取周的第一天,最后一天
System.out.println(getStartEndDate("2016-05-01",1));
获取星期的第一天和最后一天
System.out.println(getStartEndDate("2016-05-01",0));
这几天在研究字符串与指定类型的转换,阴差阳错地研究起java的日期应用了,记录下来,希望你有帮助。
System.out.println(getStartEndDate("2016-05-01",1));
获取星期的第一天和最后一天
System.out.println(getStartEndDate("2016-05-01",0));
publicstaticStringgetStartEndDate(StringaDay,inttype){ SimpleDateFormatdf=newSimpleDateFormat("yyyy年M月d日");//("yyyy-MM-ddH:m:s"); Calendarca=Calendar.getInstance(); try{ ca.setTime(newSimpleDateFormat("yyyy-MM-dd").parse(aDay)); }catch(ParseExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } Datedate1=null,date2=null; if(type==0){ intdayOfWeek=ca.get(Calendar.DAY_OF_WEEK); //中国习惯:周一是一周的开始 if(dayOfWeek==1){ dayOfWeek=7; }else{ dayOfWeek--; } System.out.println(("tag"+"dayofweek="+dayOfWeek+"min="+ca.getActualMinimum(Calendar.DAY_OF_WEEK)+"max="+ca .getActualMaximum(Calendar.DAY_OF_WEEK))); Calendarcal=(Calendar)ca.clone(); cal.add(Calendar.DATE,1-dayOfWeek); date1=cal.getTime(); cal=(Calendar)ca.clone(); cal.add(Calendar.DATE,7-dayOfWeek); date2=cal.getTime(); }elseif(type==1){ intmaximum=ca.getActualMaximum(Calendar.DAY_OF_MONTH); intminmum=ca.getActualMinimum(Calendar.DAY_OF_MONTH); intday=ca.get(Calendar.DAY_OF_MONTH); Calendarcal=(Calendar)ca.clone(); cal.add(Calendar.DATE,minmum-day); date1=cal.getTime(); cal=(Calendar)ca.clone(); cal.add(Calendar.DATE,maximum-day); date2=cal.getTime(); } Stringstr1=df.format(date1); Stringstr2=df.format(date2); System.out.println("tag"+"date1="+str1+"date2="+str2); returnstr1+"--"+str2; }
这几天在研究字符串与指定类型的转换,阴差阳错地研究起java的日期应用了,记录下来,希望你有帮助。
根据指定格式的字符串,转换为Date(可研究根据指定格式的字符串,转化为其他指定的类型,如json转换为javaBean)
需要使用到的特殊类:importjava.text.ParsePosition;
/**
*
*<p>Theparsewilltryeachparsepatterninturn.
*Aparseisonlydeemedsuccessfulifitparsesthewholeoftheinputstring.
*
*@paramstrthedatetoparse,notnull
*@paramparsePatternsthedateformatpatternstouse,seeSimpleDateFormat,notnull
*@paramlenientSpecifywhetherornotdate/timeparsingistobelenient.
*@returntheparseddate
*@throwsIllegalArgumentExceptionifthedatestringorpatternarrayisnull
*@throwsParseExceptionifnoneofthedatepatternsweresuitable
*@seejava.util.Calender#isLenient()
*/
private
static
DateparseDateWithLeniency(
Stringstr,String[]parsePatterns,
boolean
lenient)
throws
ParseException{
if
(str==
null
||parsePatterns==
null
){
throw
new
IllegalArgumentException(
"DateandPatternsmustnotbenull"
);
}
SimpleDateFormatparser=
new
SimpleDateFormat();
parser.setLenient(lenient);
ParsePositionpos=
new
ParsePosition(
0
);
for
(StringparsePattern:parsePatterns){
Stringpattern=parsePattern;
//LANG-530-needtomakesure'ZZ'outputdoesn'tgetpassedtoSimpleDateFormat
if
(parsePattern.endsWith(
"ZZ"
)){
pattern=pattern.substring(
0
,pattern.length()-
1
);
}
parser.applyPattern(pattern);
pos.setIndex(
0
);
Stringstr2=str;
//LANG-530-needtomakesure'ZZ'outputdoesn'thitSimpleDateFormatasitwillParseException
if
(parsePattern.endsWith(
"ZZ"
)){
str2=str.replaceAll(
"([-+][0-9][0-9]):([0-9][0-9])$"
,
"$1$2"
);
}
Datedate=parser.parse(str2,pos);
if
(date!=
null
&&pos.getIndex()==str2.length()){
return
date;
}
}
throw
new
ParseException(
"Unabletoparsethedate:"
+str,-
1
);
}
在java日期格式里,"ZZ"代表的是时区。在java里,格式化需要借助类Formate,同时,parse的时候一般需要借助类parsePosition,
ParsePosition是
Format及其子类所使用的简单类,用来在解析过程中跟踪当前位置。各种
Format类中的
parseObject方法要求将
ParsePosition对象作为一个变量。
日期解释的宽松性:
Calendar有两种解释日历字段的模式,即lenient和non-lenient。当
Calendar处于lenient模式时,它可接受比它所生成的日历字段范围更大范围内的值。当
Calendar重新计算日历字段值,以便由
get()返回这些值时,所有日历字段都被标准化。例如,lenient模式下的
GregorianCalendar将
MONTH==JANUARY、
DAY_OF_MONTH==32解释为February1。
当
Calendar处于non-lenient模式时,如果其日历字段中存在任何不一致性,它都会抛出一个异常。例如,
GregorianCalendar总是在1与月份的长度之间生成
DAY_OF_MONTH值。如果已经设置了任何超出范围的字段值,那么在计算时间或日历字段值时,处于non-lenient模式下的
GregorianCalendar会抛出一个异常。(在non-lenient状态下,可以用来检测用户输入的日期是否合法)
日期加减(Calendar的add&&set&&roll)
set(intfield,intamount)方法,并不会立刻就计算出新的日期的值,而是在调用getXxx(),add(),roll()方法才会计算出新的日期的值,即多次调用set方法,也不会产生多余的计算。
add(intfiled,intamount)方法,调用add方法,会立刻计算出新的日期的值。
roll(intfielde,intamount)方法,调用roll方法,也会立刻计算出新的日期的值,与add不同的是,在进行计算完之后,不更改更高字段的值。
举例如下:假设一个日期(Calendar类型)是date20140831
1)调用date.set(Calendar.Month,Calendar.September),在调用set(Calendar.Data,1),c.getTime()返回的时间是20140901
2)调用date.add(Calendar.Month,1),c.getTime()返回的日期是,20141001。(如果是设置了c.setLeniency(true),返回的日期是20141001,如果是设置了c.setLeniency(false),返回的是20140930)
3)调用date.roll(Calendar.Month,13),c.setLeniency(flase),c.getTime()返回的日期是20140930,请注意这里返回的不是20141231
对于设置日期的值,可以这样编写代码:
private static Dateset(Datedate, int calendarField, int amount){ if (date== null ){ throw new IllegalArgumentException( "Thedatemustnotbenull" ); } //getInstance()returnsanewobject,sothismethodisthreadsafe. Calendarc=Calendar.getInstance(); c.setLenient( false );//这里使用严格模式,要求设置日期的值必须正确 c.setTime(date); c.set(calendarField,amount); return c.getTime(); } |
private static Dateadd(Datedate, int calendarField, int amount){ if (date== null ){ throw new IllegalArgumentException( "Thedatemustnotbenull" ); } Calendarc=Calendar.getInstance(); c.setTime(date); c.add(calendarField,amount); return c.getTime(); } |
private
static
Dateroll(Datedate,
int
calendarField,
int
amount){
if
(date==
null
){
throw
new
IllegalArgumentException(
"Thedatemustnotbenull"
);
}
Calendarc=Calendar.getInstance();
c.setTime(date);
c.roll(calendarField,amount);
return
c.getTime();
}
对应的设置年、月、日、时、分、秒,可以这样编写代码:(其他的可以仿写)
public static DatesetMinutes(Datedate, int amount){ return set(date,Calendar.MINUTE,amount); } |
如:get(intfiele)获取给定日历字段的值;getFirstDayOfWeek()获取一星期的第一天的值(1~7)(在不同的地区,每周的第一天会有所不一样,在中是默认一星期的第一天是周日1)。通过这两个函数,我们可以获取任意一天其所在周的第一天的日期值,如20140902周二,我们可以获取到周日的日期值为20140831。具体方法如下:
构造一个20140902的Calendar,通过getFirstDayOfWeek(),获取本周第一天的值(返回1),通过get(Calendar.day_of_week)获取当前日期是本周的第几天,进而获取天数差,再将当前日期减去天数差,即可获取本周第一天的日期值。
函数如下:
public static DategetFirstDateOfWeek(Datedate){ Calendarc=Calendar.getInstance(); c.setTime(date); //获取本周第一天的值 int firstDayOfWeek=c.getFirstDayOfWeek(); //当前日期是本周的第几天 int dayOfWeek=c.get(Calendar.DAY_OF_WEEK); int day_diff= 1 ; //天数差的绝对值,20140901~20140903天数差为3 if (firstDayOfWeek<dayOfWeek){ day_diff=Math.abs(dayOfWeek-firstDayOfWeek)+ 1 ; } c.add(Calendar.DATE, 1 -day_diff); return c.getTime(); } |
为了本地化,我们可以用GregorianCalendar构造Calendar,
GregorianCalendarcalendar=newGregorianCalendar(Local.getDefault());
类似地,我们可以得到本周最后一天的日期:
public
static
DategetLastDateOfWeek(Datedate){
Calendarc=Calendar.getInstance();
c.setTime(date);
//获取本周第一天的值
int
firstDayOfWeek=c.getFirstDayOfWeek();
//当前日期是本周的第几天
int
dayOfWeek=c.get(Calendar.DAY_OF_WEEK);
int
day_diff=
1
;
//天数差的绝对值
if
(firstDayOfWeek<dayOfWeek){
day_diff=Math.abs(dayOfWeek-firstDayOfWeek)+
1
;
}
c.add(Calendar.DATE,
7
-day_diff);
return
c.getTime();
}
再借助
给定此getActualMaximum (intfield)
Calendar的时间值,返回指定日历字段可能拥有的最大值。
给定此getActualMinimum (intfield)
Calendar的时间值,返回指定日历字段可能拥有的最小值。借助这两个函数,我们可以获取一天所在月的第一天/最后一天的日期。方法如下:
public
static
DategetFirstDateOfMonth(Datedate){
if
(date==
null
){
throw
new
IllegalArgumentException(
"thedatemustnotbenull"
);
}
Calendarc=Calendar.getInstance();
c.setTime(date);
//getthemindateinthismonth
int
min_day=c.getActualMinimum(Calendar.DATE);
c.set(Calendar.DATE,min_day);
return
c.getTime();
}
public
static
DategetLastDateOfMonth(Datedate){
if
(date==
null
){
throw
new
IllegalArgumentException(
"thedatemustnotbenull"
);
}
Calendarc=Calendar.getInstance();
c.setTime(date);
//getthemaxdateinthemonth
int
max_day=c.getActualMaximum(Calendar.DATE);
c.set(Calendar.DATE,max_day);
return
c.getTime();
}
聪明的我们,是否马上就会想到,能否通过getActualMaximum和getActualMininum来获取一周day_of_week的最大/小值呢??是的,通过这两个方法,我们可以减少一定的计算量,如下:
public static DategetFirstDateOfWeek(Datedate){ Calendarc=Calendar.getInstance(); c.setTime(date); ////获取本周第一天的值 //intfirstDayOfWeek=c.getFirstDayOfWeek(); ////当前日期是本周的第几天 //intdayOfWeek=c.get(Calendar.DAY_OF_WEEK); // //intday_diff=1;//天数差的绝对值,20140901~20140903天数差为3 // //if(firstDayOfWeek<dayOfWeek){ //day_diff=Math.abs(dayOfWeek-firstDayOfWeek)+1; //} // //c.add(Calendar.DATE,1-day_diff); int min_day=c.getActualMinimum(Calendar.DAY_OF_WEEK); c.set(Calendar.DAY_OF_WEEK,min_day); return c.getTime(); } |
在这里再谈一下,如果获取季度的起始/结束日期,方法如下:
对于给定的日期,如果我们可以获取到其所在季度的起始月份和结束月份,自然就可以获取到季度的起始日期和结束日期。函数如下:
在这里我们初始化静态数组,用来存储每个月所在季度第一个和最后一个月份的值,注意在java里,月份的范围是[0,11]
private static final int []seasonFirstMonth= new int []{ 0 , 0 , 0 , 3 , 3 , 3 , 6 , 6 , 6 , 9 , 9 , 9 }; private static final int []seasonLastMonth= new int []{ 2 , 2 , 2 , 5 , 5 , 5 , 8 , 8 , 8 , 11 , 11 , 11 }; public static DategetFirstDateOfSeason(Datedate){ if (date== null ){ throw new IllegalArgumentException( "thedatemustnotbenull" ); } Calendarc=Calendar.getInstance(); c.setTime(date); c.set(Calendar.MONTH,seasonFirstMonth[c.get(Calendar.MONTH)]); c.set(Calendar.DATE,c.getActualMinimum(Calendar.DATE)); return c.getTime(); } public static DategetLastDateOfSeason(Datedate){ if (date== null ){ throw new IllegalArgumentException( "thedatemustnotbenull" ); } Calendarc=Calendar.getInstance(); c.setTime(date); c.set(Calendar.MONTH,seasonLastMonth[c.get(Calendar.MONTH)]); c.set(Calendar.DATE,c.getActualMaximum(Calendar.DATE)); return c.getTime(); } |
public
static
long
getDaysBetweenTwoDate(Datedate1,Datedate2){
if
(date1==
null
||date2==
null
){
throw
new
IllegalArgumentException(
"date1anddate2mustnotbenull"
);
}
Calendarc1=Calendar.getInstance();
c1.setTime(date1);
Calendarc2=Calendar.getInstance();
c2.setTime(date2);
long
mills_one_day=
60
*
60
*
24
*
1000
;
return
Math.abs(c1.getTimeInMillis()-c2.getTimeInMillis())/mills_one_day+
1
;
}
附:通过阅读JavaAPI,借助一些基础的推算逻辑,我们可以合成很多很有用工具类,让我们彼此一起努力。在这一次学习当中,本人更感兴趣的,如何通过指定的字符串格式构造指定的对象(如通过字符串构造日期),又如何通过指定格式输出制定对象(如根据yyyyMMdd格式输出日期对象)。
MYSQL中的获取:
#当年第一天:
SELECTDATE_SUB(CURDATE(),INTERVALdayofyear(now())-1DAY);
#当年最后一天:
SELECTconcat(YEAR(now()),'-12-31');
#当前week的第一天:
selectdate_sub(curdate(),INTERVALWEEKDAY(curdate())+1DAY);
#当前week的最后一天:
selectdate_sub(curdate(),INTERVALWEEKDAY(curdate())-5DAY);
#前一week的第一天:
selectdate_sub(curdate(),INTERVALWEEKDAY(curdate())+8DAY);
#前一week的最后一天:
selectdate_sub(curdate(),INTERVALWEEKDAY(curdate())+1DAY);
#前两week的第一天:
selectdate_sub(curdate(),INTERVALWEEKDAY(curdate())+15DAY);
#前两week的最后一天:
selectdate_sub(curdate(),INTERVALWEEKDAY(curdate())+9DAY);
#当前month的第一天:
SELECTconcat(date_format(LAST_DAY(now()),'%Y-%m-'),'01');
#当前month的最后一天:
SELECTLAST_DAY(now());
#前一month的第一天:
SELECTconcat(date_format(LAST_DAY(now()-interval1month),'%Y-%m-'),'01');
#前一month的最后一天:
SELECTLAST_DAY(now()-interval1month);
#前两month的第一天:
SELECTconcat(date_format(LAST_DAY(now()-interval2month),'%Y-%m-'),'01');
#前两month的最后一天:
SELECTLAST_DAY(now()-interval2month);
#当前quarter的第一天:
selectconcat(date_format(LAST_DAY(MAKEDATE(EXTRACT(YEARFROMCURDATE()),1)+intervalQUARTER(CURDATE())*3-3month),'%Y-%m-'),'01');
#当前quarter的最后一天:
selectLAST_DAY(MAKEDATE(EXTRACT(YEARFROMCURDATE()),1)+intervalQUARTER(CURDATE())*3-1month);
#前一quarter的第一天:
selectconcat(date_format(LAST_DAY(MAKEDATE(EXTRACT(YEARFROMCURDATE()),1)+intervalQUARTER(CURDATE())*3-6month),'%Y-%m-'),'01');
#前一quarter的最后一天:
selectLAST_DAY(MAKEDATE(EXTRACT(YEARFROMCURDATE()),1)+intervalQUARTER(CURDATE())*3-4month);
#前两quarter的第一天:
selectconcat(date_format(LAST_DAY(MAKEDATE(EXTRACT(YEARFROMCURDATE()),1)+intervalQUARTER(CURDATE())*3-9month),'%Y-%m-'),'01');
#前两quarter的最后一天:
selectLAST_DAY(MAKEDATE(EXTRACT(YEARFROMCURDATE()),1)+intervalQUARTER(CURDATE())*3-7month);
相关文章推荐
- Java 线程安全
- Java中Properties类的使用
- Leetcode第9题Palindrome Number
- SSM整合--增删改查
- 如何在myeclipse中开启两个console?
- Java ConcurrentModificationException异常原因和解决方法
- Java并发编程:同步容器
- Java并发编程:深入剖析ThreadLocal
- Struts2 jsp页面向 action传参(三种)
- Java static块和static方法
- Java并发编程:volatile关键字解析
- SSM框架——详细整合教程(Spring+SpringMVC+MyBatis)
- SpringMVC调度
- java web ajax设置context-type
- myeclipse下安装js提示工具spket
- Struts2后端向前端传参
- Java 多线程编程
- jdk动态代理接口
- Java并发编程:Lock
- Java并发编程:synchronized