获取当前日期:
Oracle : sysdate
Sqlserver : getdate()
MySQL:curdate()
获取当前周一:
MySQL: select subdate(curdate(),date_format(curdate(),'%w')-1)
获取当前周日:
MySQL: select subdate(curdate(),date_format(curdate(),'%w')-7)
本月第一日:
Oracle : trunc(sysdate, 'mm')
Sqlserver : Year(getdate())+ Month(getdate()) + '01'
MySQL:select date_add(curdate(),interval -day(curdate())+1 day) ;
pg:select date_trunc('month',current_date)
本月最后一日:
oracle: select last_day(trunc(sysdate)) from dual
sqlserver: EOMONTH(GETDATE()) 上个月最后一日:select EOMONTH(GETDATE(),-1)
MySQL:select last_day(curdate());
pg: select date_trunc('month',current_date) + interval'1 month - 1 day' //基于当月第一天,增加一个月,再倒退1天
上月第一日:
Oracle: trunc(add_months(sysdate, -1), 'mm')
SqlServer:DateFromParts(year(getdate()), month(getdate())-1, 1)
MySQL:select date_add(curdate()-day(curdate())+1,interval -1 month)
上月最后一日:
Oracle:last_day(add_months(sysdate,-1))
SqlServer: EOMONTH(GETDATE(),-1)
或DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-1, -1)
MySQL:select last_day(date_sub(now(),interval 1 month))
pg: select date_trunc('month',current_date) - interval'1 day' //基于当月第一天,倒退1天
本季度第一日:
ORACLE: trunc(sysdate, 'Q')
SQLSERVER: Year(getdate())+quarter (getdate()) + '01'
Case DATEPART(QUARTER,GETDATE()) when '1' then Year(getdate())+'01'+ '01'
when ‘2’ then Year(getdate())+'04'+ '01'
when ‘3’ then Year(getdate())+'07'+ '01'
when ‘4’ then Year(getdate())+'10'+ '01'
end
本年第一天:
Oracle: trunc(sysdate, 'y')
Sqlserver: Year(getdate())+'01'+ '01'
MySQL:select date_sub(curdate(), interval dayofyear(curdate())-1 day);
pg:select date_trunc( 'year', now() );
本年最后一天:
Oracle: select last_day(add_months(trunc(SYSDATE,'y'),11)) from dual
Sqlserver: Year(getdate())+'12'+ '31'
MySQL:select concat(year(curdate()),'-12-31')
pg:select date_trunc( 'year', now() )+interval '1 year' -interval '1 day';
SqlServer 部分:
SQL Server 日期格式和日期操作
SQL Server发展至今,
1、关于日期的格式的控制方法,
有传统的方法,比如CONVERT(),
也有比较便利的新方法,比如FORMAT(); eg: FORMAT(CAST(date AS DATE),'yyyy-MM') ps:年要用小写的yyyy, 月大写MM
2、同样,关于日期的操作函数,也分为传统方法:DATEADD()等,
也有便利的新方法:EOMonth()等。
一,日期的格式化
格式化是指把日期类型(Date)、日期和时间类型转化为字符类型,通常使用CONVERT()和FORMAT()函数。
1,传统的CONVERT()
SQL Server控制日期的的显示格式,通常使用CONVERT()函数,通过控制style参数来控制日期显示的格式,但是,style很多,不利于记忆。
CONVERT ( data_type [ ( length ) ] , expression [ , style ] )
符合东方人阅读习惯的style及其显示格式如下:
- 101: mm/dd/yyyy
- 110: mm-dd-yyyy
- 111: yyyy/mm/dd
- 112: yyyymmdd
- 120: yyyy-mm-dd hh:mm:ss
- 121: yyyy-mm-dd hh:mm:sssssss
CONVERT()函数的style是数字,记忆起来比较困难,并且只能按照系统定义的格式来显示,不够灵活。SQL Server提供更为灵活的转换函数FORMAT()。
2,便利的FORMAT()函数
FORMAT()函数,可以方便和灵活地控制数值、日期和时间类型的显示格式,通常情况下,FORMAT()函数主要用于格式化显示date/time类型和数值类型,参数format用于指定显示的格式,给予用户对格式更自由地控制,culture参数是可选的,用于指定显示的语言,该函数返回值的数据类型是NVARCHAR,如果格式转换失败,该函数返回NULL:
FORMAT ( value, format [, culture ] )
参数format使用#表示一个数值,参数 format 使用以下占位符来表示日期/时间的格式:
- yyyy、MM、dd:表示年、月、日
- hh:mm:ss fffffff:表示时、分、秒、毫秒
- 使用“/”,“-”等作为连接各个部分(part)的分割符号
(1)把date/time格式化
在format参数中指定日期/时间显示的格式,以特定的格式: “yyyy:MMdd hh:mm:ss fffffff” 显式日期/时间,例如:
select format(SYSDATETIME(),'yyyy-MM-dd hh:mm:ss fffffff')
(2)转换数值类型
在参数format中使用#代表一个数字,使用相应的连接符,拼接成数字的格式字符,例如:
FORMAT(123456789,'###-##-####') AS 'Custom Number Result
二,日期和时间的结构
常用的日期的构成(datepart)是:year、month、day、hour、minute、second、ns、TZoffset(简写为 tz)
DATEPART ( datepart , date )
YEAR ( date )
MONTH ( date )
DAY ( date )
在实际的产品环境中,周、季度等都很有用途:
- quarter:季度,取值范围是 1、2、3、4
- week:周在年中的序数,取值范围是 1 - 53
- dayofyear:天在年中的序数,取值范围是 1 - 366
- weekday:天在一周中的序数,取值范围是 1 - 7
DATEPART()返回的datepart是int类型,如果想要返回字符类型,可以使用DATENAME()函数:
DATENAME ( datepart , date )
通过datepart来构造日期,常用的函数有:
DATEFROMPARTS ( year, month, day )
DATETIME2FROMPARTS ( year, month, day, hour, minute, seconds, fractions, precision )
DATETIMEOFFSETFROMPARTS ( year, month, day, hour, minute, seconds, fractions, hour_offset, minute_offset, precision )
TIMEFROMPARTS ( hour, minute, seconds, fractions, precision )
参数precision 是指小数秒的精度,指的是DateTime2(n)、DateTimeOffset(n),Time(n)中的n值,表示以多少位小数表示1s。
三,日期操作
日期函数:EOMonth、Format、DateAdd、DateDiff、SwitchOffset
1,月份的最后一天
函数 EOMonth() 返回指定日期的最后一天
EOMONTH ( start_date [, month_to_add ] )
参数注释:
- start_date: 有两种输入方式,能够转换为Date的字符串类型 和 date 数据类型
- month_to_add: 是int 类型,能够为正整数,负整数和0,默认值是0,如果省略,那么使用默认值0。
例如,查看当前月的最后一天、下一个月的最后一天、上一个月的最后一天:
declare @date date
set @date=getdate()
select EOMONTH(@date) as CurrentMonth_EndDay,
EOMONTH(@date,1) as NextMonth_EndDay,
EOMONTH(@date,-1) as LastMonth_EndDay
2,月份的第一天
使用DateFromParts() 函数,能够从3个正整数(year,month,day)中获取date 类型,只需要将day 参数设置1,就能获取月份的第一天的日期。
declare @date date
set @date=getdate()
select DATEFROMPARTS(year(@date),month(@date),1)
也可以使用Format() 函数, 以字符串形式返回月份的第一天,例如,获取当前月份的第一天:
FORMAT(GETDATE(),'yyyyMM01')
3,切换时区
把DateTimeOffset类型的数据切换到指定的时区,在转换过程中,UTC时间是固定的,依据固定的UTC时间,切换到特定时区的本地时间:
SWITCHOFFSET ( DATETIMEOFFSET, time_zone )
参数注释:
- DATETIMEOFFSET:DateTimeOffset(n)类型的变量
- time_zone:指定的目标时区数据,格式是 [+|-] hh:mm
使用SwitchOffset()函数把DateTimeOffset的时区偏移(Offset)切换到指定的时区中,例如,把本地时间的时区东八区切换到东七区:
DECLARE @remote DATETIMEOFFSET
DECLARE @local DATETIMEOFFSET
SET @local = SYSDATETIMEOFFSET()
SET @remote = SWITCHOFFSET (@local, '+07:00')
SELECT @remote AS remote_time,@local AS local_time
可以看到,东7区的时间比东8区的时间晚一个小时。
4,当前日期是周几
在SQL Server中,通过DataFirst选项设置一周的第一天,序数是从1到7,表示一周的7天。
SET DATEFIRST { number | @number_var }
(1)可以通过@@datefirst来获取设置的值
set DATEFIRST 1
select @@datefirst
(2)使用函数datepart函数获取当天是周几
set DATEFIRST 1
select datepart(WEEKDAY,getutcdate())
set DATEFIRST 2
--select @@datefirst
select datepart(WEEKDAY,getutcdate())
由于设置不同的DateFirst,会导致datepart返回不同的数值,所以必须借助@@DateFirst
set DATEFIRST 2
select Datepart(weekday, getdate()+@@datefirst - 1)
set DATEFIRST 1
select Datepart(weekday, getdate()+@@datefirst - 1)
4,使用DateName获取WeekDay的名字
WeekDay的名字跟系统的语言设置有管,跟DateFirst的设置没有关系
(1) 查看当前的语言设置
select @@language
(2) 查看系统支持的语言
select alias,name, *
from sys.syslanguages
(3) 设置语言
set LANGUAGE 'Simplified Chinese'
set LANGUAGE 'us_english'
(4) 使用DateName获取WeekDay的名字
set LANGUAGE 'Simplified Chinese'
select DATENAME(WEEKDAY,getutcdate())
set LANGUAGE 'us_english'
select DATENAME(WEEKDAY,getutcdate())
SqlServer部分:
GETDATE() :获取当前时间,时间格式默认。
DATENAME:参数为两个,取值区间 interval 和时间 date
date 就是时间;
interval 包括 年,月,日,星期等
e.g:
YEAR 年;YYYY 年;YY 年;
QUARTER 季度;QQ 季度 ;Q 季度;
MONTH 月(05);MM 月(05);M 月(05);
WEEKDAY 星期几;DW 星期几;W 星期几;
WEEK 一年的第几周;WK 一年的第几周;WW 一年的第几周;ISOWK 一年的第几周;ISOWW 一年的第几周;ISO_WEEK 一年的第几周;
DAY 天;DD 天;D 天;
DAYOFYEAR 一年的第几天;DY 一年的第几天;Y 一年的第几天;
HOUR 小时;HH 小时;
MINUTE 分钟;MI 分钟;N 分钟;
SECOND 秒;SS 秒;S 秒;
MCS 微秒(略);MICROSECOND 微秒(略);MILLISECOND 毫秒(略);MS 毫秒(略) ; NANOSECOND 十亿分之一秒(略);NS 十亿分之一秒(略);
DATEPART:参数参考DATENAME,不过返回值不一样,DATENAME返回varchar,DATEPART返回int
CONVERT 函数转换格式:主要注意第三个参数 date_style ;格式:select CONVERT(varchar,GETDATE(),0)
最后的 date_style 可以有 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,100,
101,102,103,104,105,106,107,108,109,110,111,112,113,114,120,121,126,127,130,131等
常用的 20,23,24,102,111,112,120等;
示例:
select CONVERT(varchar,GETDATE(),20) --2017-05-12 17:22:22
select CONVERT(varchar,GETDATE(),23) --2017-05-12
select CONVERT(varchar,GETDATE(),24) --17:23:42
select CONVERT(varchar,GETDATE(),102) --2017.05.12
select CONVERT(varchar,GETDATE(),111) --2017/05/12
select CONVERT(varchar,GETDATE(),112) --20170512
字符串转日期:select CONVERT(datetime,'2017-05-12',20) 第三个参数参考以上。
===================================================
ORACLE部分:
Oracle 按月分组:
SELECT to_char(日期字段,'yyyymm'),count(*)
FROM [TableName]
group by to_char(日期字段,'yyyymm')
order by to_char(日期字段,'yyyymm')
-
oracle相关时间计算,得到季度第一天、最后一天
-
------------------------------------------------ Oracle 日期------------------------------------------
-
Oracle取得本周,本月度,本季,本年的第一天和最后一天
--本周
select trunc(sysdate,'d')+1 from dual;
select trunc(sysdate,'d')+7 from dual;
--本月
select trunc(sysdate,'mm') from dual;
select last_day(trunc(sysdate)) from dual;
--本季
select trunc(sysdate,'Q') from dual;
select add_months(trunc(sysdate,'Q'),3)-1 from dual;
--本年
select trunc(sysdate,'yyyy') from dual;
select add_months(trunc(sysdate,'yyyy'),12)-1 from dual; -
-------------------------------------------------------------------------------------
-
-- 本季度第一天
-
SELECT to_char(TRUNC(SYSDATE, 'Q'), 'YYYY-MM-DD') FROM dual;
-
-- 上个季度最后一天(可以用本季度第一天减去1得到)
-
三种方法:
-
select last_day(trunc(sysdate, 'q')-1)from dual
-
select to_char(last_day(add_months(trunc(sysdate, 'Q'), -1)), 'yyyy-mm-dd') from dualSELECT to_char(TRUNC(SYSDATE, 'Q') - 1, 'YYYY-MM-DD') FROM dual;
-
-- 上个季度第一天(本季度第一天 减 3个月)
-
SELECT to_char(add_months(TRUNC(SYSDATE, 'Q'), -3), 'YYYY-MM-DD')
-
FROM dual;
-
-- 上个季度第一天(本季度减一个月之后的月份的最后一天)
-
select to_char(last_day(add_months(trunc(sysdate, 'Q'), -1)), 'yyyy-mm-dd')
-
from dual
-
--№1: 取得当前日期是本月的第几周
-
select to_char(sysdate,'YYYYMMDD W HH24:MI:SS') from dual;
-
select to_char(sysdate, 'W') from dual;
-
--№2:取得当前日期是一个星期中的第几天,注意星期日是第一天
-
select sysdate, to_char(sysdate, 'D') from dual;
-
--类似:
-
select to_char(sysdate, 'yyyy') from dual; --当前年
-
select to_char(sysdate, 'Q' ) from dual; --当前季度
-
select to_char(sysdate, 'mm') from dual; --当前月
-
select to_char(sysdate, 'dd') from dual; --当前日
-
--№3:取当前日期是星期几的中文显示:
-
select to_char(sysdate, 'day') from dual;
-
--№4:如果一个表在一个date类型的字段上面建立了索引,如何使用
-
alter session set NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS'
-
--№5: 得到当前的日期
-
select sysdate from dual;
-
--№6: 得到当天凌晨0点0分0秒的日期
-
select to_char(trunc(sysdate), 'yyyymmdd hh:mi:ss' ) from dual;
-
-- 得到这天的最后一秒
-
select trunc(sysdate) + 0.99999 from dual;
-
-- 得到小时的具体数值
-
select trunc(sysdate) + 1 / 24 from dual;
-
select trunc(sysdate) + 7 / 24 from dual;
-
--№7:得到明天凌晨0点0分0秒的日期
-
select trunc(sysdate + 1) from dual;
-
select trunc(sysdate) + 1 from dual;
-
--№8: 本月一日的日期
-
select trunc(sysdate, 'mm') from dual;
-
--№9:得到下月一日的日期
-
select add_months(trunc(sysdate, 'mm'), 1) from dual;
-
select trunc(add_months(sysdate, 1), 'mm') from dual;
-
-- №10:返回当前月的最后一天?
-
select last_day(sysdate) from dual;
-
select last_day(trunc(sysdate)) from dual;
-
select trunc(last_day(sysdate)) from dual;
-
select trunc(add_months(sysdate, 1), 'mm') - 1 from dual;
-
--№11: 得到一年的第一天
-
select trunc(sysdate, 'y') from dual
-
--№11: 得到一年的每一天
-
select trunc(sysdate, 'yyyy') + rn - 1 date0
-
from (select rownum rn from all_objects where rownum < 366) t;
-
--№12:今天是今年的第N天
-
SELECT TO_CHAR(SYSDATE, 'DDD') FROM DUAL;
-
--№13:如何在给现有的日期加上2年
-
select add_months(sysdate, 24) from dual;
-
--№14:判断某一日子所在年分是否为润年
-
select last_day(trunc(sysdate, 'yyyy') + 31) from dual -- 通过一年的第一天加上31天到2月,然后取2月最后一天
-
select decode(to_char(last_day(trunc(sysdate, 'y') + 31), 'dd'),
-
'29',
-
'闰年',
-
'平年')
-
from dual;
-
--№15:判断两年后是否为润年
-
select decode(to_char(last_day(trunc(add_months(sysdate, 24), 'y') + 31), 'dd'),
-
'29',
-
'闰年',
-
'平年')
-
from dual;
-
--№16:得到日期的季度
-
select trunc(sysdate, 'mi') from dual ;
-
select to_number(to_char(sysdate,'mm')) from dual;
-
select ceil(to_number(to_char(sysdate,'mm'))/3) from dual;
-
select to_char(sysdate, 'Q') from dual;
-
--No17:返回某个月的最后一天
-
select to_char(last_day(sysdate), 'dd') from dual
-
--本周的第一天和最后一天,考虑到中国人习惯是周一为每周的第一天(国际惯例是周日为第一天,oracle也是这样)
-
select trunc(sysdate,'d')+1,trunc(sysdate,'d')+7 from dual where to_char(sysdate,'day')<>'星期日'
-
union all
-
select trunc(sysdate,'d')+1-7,trunc(sysdate,'d')+7-7 from dual where to_char(sysdate,'day')='星期日'
-
--当前季度的第一天
-
select to_char(trunc(sysdate,'Q'),'yyyy-mm-dd') from dual;
-
--当前季度的最后一天
-
SELECT to_char(add_months(TRUNC(SYSDATE, 'Q'), +3)-1, 'YYYY-MM-DD')
-
FROM dual;
-
select to_char(trunc(add_months(last_day(sysdate), -1) + 1), 'yyyy-mm-dd') "本月第一天",
Oracle 按月分组:
SELECT to_char(日期字段,'yyyymm'),count(*)
FROM [TableName]
group by to_char(日期字段,'yyyymm')
order by to_char(日期字段,'yyyymm')
TRUNC():类似截取函数,按指定的格式截取输入的数据。
1.【trunc(for dates)】TRUNC()函数处理日期
语法格式:TRUNC(date[,fmt])
其中:date 一个日期值;fmt 日期格式。
该日期将按指定的日期格式截取;忽略它则由最近的日期截取。
示例:
select trunc(sysdate) from dual;--2017/2/13,返回当前时间
select trunc(sysdate,'yy') from dual;--2017/1/1,返回当年第一天
select trunc(sysdate,'mm') from dual;--2017/2/1,返回当月的第一天
SELECT to_char(TRUNC(SYSDATE, 'Q'), 'YYYY-MM-DD') FROM dual 本季度第一天
select trunc(sysdate,'d') from dual;--2017/2/12,返回当前星期的第一天,即星期天
select trunc(sysdate,'dd') from dual;--2017/2/13,返回当前日期,今天是2017/2/13
select trunc(sysdate ,'HH24') from dual;--2017/2/13 15:00:00,返回本小时的开始时间
select trunc(sysdate ,'MI') from dual;--2017/2/13 15:13:00,返回本分钟的开始时间
2.【TRUNC(for number)】TRUNC()函数处理number型数字
语法格式:TRUNC(number[,decimals])
其中: number 待做截取处理的数值;decimals 指明需保留小数点后面的位数,可选项,忽略它则截去所有的小数部分。
注意:截取时并不对数据进行四舍五入。
示例:
select trunc(123.567,2) from dual;--123.56,将小数点右边指定位数后面的截去;
select trunc(123.567,-2) from dual;--100,第二个参数可以为负数,表示将小数点左边指定位数后面的部分截去,即均以0记;
select trunc(123.567) from dual;--123,默认截去小数点后面的部分;
Oracle的Extract函数获取:当前年、月、周
获取年:Select Extract(yearfrom sysdate) from dual
获取季度: select to_char(sysdate,'Q') from dual
获取月:Select Extract(year from sysdate) from dual
获取周: select to_char(sysdate,'IW') from dual
获取天:Select Extract(day from sysdate) from dual
====================================================================================
Mysql部分:
#获取当前日期
select curdate();
#获取当前年月时分秒
select now();
# 获取当前年
select year(now());
# 获取当前月
select month(now());
#获取当月最后一天
select last_day(curdate());
#获取本月的第一天
select date_add(curdate(),interval -day(curdate())+1 day) ;
#获取下个月的第一天
select date_add(curdate() - day(curdate()) +1,interval 1 month );
#获取当前月已过了几天
select day(curdate());
#日期转换为 yyyymmdd, eg:20220803
SELECT DATE_FORMAT(Now() ,'%Y%m%d')
ps:大写Y
#日期转换为 yyyy-MM-dd HH:mm:ss 格式, eg:20220803 12:02:14
SELECT DATE_FORMAT(Now() ,'%Y%m%d %H:%i:%s')
#获取当前月的天数(先加一个月,再减今天是第几天,得到当前月的最后一天,最后求最后一天是几号)
select day(date_add( date_add(curdate(),interval 1 month),interval -day(curdate()) day ));
#上个月的第一天
select date_sub(date_sub(date_format(now(),'%y-%m-%d'),interval extract(
day from now())-1 day),interval 1 month)
#上个月的最后一天:
select date_sub(date_sub(date_format(now(),'%y-%m-%d'),interval extract(
day from now()) day),interval 0 month) as date
#这个月的第一天:
select date_sub(date_sub(date_format(now(),'%y-%m-%d'),interval extract(
day from now())-1 day),interval 0 month)
#获取当月最后一天
select last_day(curdate());
postgre部分:
1、以下方法只能获取当前年份:
select to_char(current_date,'yyyy') 为 character varying格式类型
select extract(year from now()) 为double precision 格式类型
select to_char((SELECT now()::timestamp),'yyyy') 为character varying格式类型
2、获取下一年的年份:
select to_char((SELECT now()::timestamp + '1 year'),'yyyy') 为character varying格式类型
3、获取上一年的年份:
select to_char((SELECT now()::timestamp + '-1 year'),'yyyy') 为character varying格式类型
hive对日期的操作
固定日期转换成时间戳
select unix_timestamp('2016-08-16','yyyy-MM-dd') --1471276800
select unix_timestamp('20160816','yyyyMMdd') --1471276800
select unix_timestamp('2016-08-16T10:02:41Z', "yyyy-MM-dd'T'HH:mm:ss'Z'") --1471312961
16/Mar/2017:12:25:01 +0800 转成正常格式(yyyy-MM-dd hh:mm:ss)
select from_unixtime(to_unix_timestamp('16/Mar/2017:12:25:01 +0800', 'dd/MMM/yyy:HH:mm:ss Z'))
时间戳转换程固定日期
select from_unixtime(1471276800,'yyyy-MM-dd') --2016-08-16
select from_unixtime(1471276800,'yyyyMMdd') --20160816
select from_unixtime(1471312961) -- 2016-08-16 10:02:41
select from_unixtime( unix_timestamp('20160816','yyyyMMdd'),'yyyy-MM-dd') --2016-08-16
select date_format('2016-08-16','yyyyMMdd') --20160816
返回日期时间字段中的日期部分
select to_date('2016-08-16 10:03:01') --2016-08-16
取当前时间
select from_unixtime(unix_timestamp(),'yyyy-MM-dd HH:mm:ss')
select from_unixtime(unix_timestamp(),'yyyy-MM-dd')
返回日期中的年
select year('2016-08-16 10:03:01') --2016
返回日期中的月
select month('2016-08-16 10:03:01') --8
返回日期中的日
select day('2016-08-16 10:03:01') --16
返回日期中的时
select hour('2016-08-16 10:03:01') --10
返回日期中的分
select minute('2016-08-16 10:03:01') --3
返回日期中的秒
select second('2016-08-16 10:03:01') --1
返回日期在当前的周数
select weekofyear('2016-08-16 10:03:01') --33
返回结束日期减去开始日期的天数
select datediff('2016-08-16','2016-08-11')
返回开始日期startdate增加days天后的日期
select date_add('2016-08-16',10)
返回开始日期startdate减少days天后的日期
select date_sub('2016-08-16',10)
返回当天三种方式
SELECT CURRENT_DATE;
--2017-06-15
SELECT CURRENT_TIMESTAMP;--返回时分秒
--2017-06-15 19:54:44
SELECT from_unixtime(unix_timestamp());
--2017-06-15 19:55:04
返回当前时间戳
Select current_timestamp--2018-06-18 10:37:53.278
返回当月的第一天
select trunc('2016-08-16','MM') --2016-08-01
返回当年的第一天
select trunc('2016-08-16','YEAR') --2016-01-01