MySQL 日期类型:日期格式、所占存储空间、日期范围 比较。
日期类型 存储空间 日期格式 日期范围
------------ --------- --------------------- -----------------------------------------
datetime 8 bytes YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00 ~ 9999-12-31 23:59:59
timestamp 4 bytes YYYY-MM-DD HH:MM:SS 1970-01-01 00:00:01 ~ 2038
date 3 bytes YYYY-MM-DD 1000-01-01 ~ 9999-12-31
year 1 bytes YYYY 1901 ~ 2155
在 MySQL 中创建表时,对照上面的表格,很容易就能选择到合适自己的数据类型。不过到底是选择 datetime 还是 timestamp,可能会有点犯难。这两个日期时间类型各有优点:datetime 的日期范围比较大;timestamp 所占存储空间比较小,只是 datetime 的一半。
另外,timestamp 类型的列还有个特性:默认情况下,在 insert, update 数据时,timestamp 列会自动以当前时间(CURRENT_TIMESTAMP)填充/更新。“自动”的意思就是,你不去管它,MySQL 会替你去处理。
建表的代码为:
create table t8 (
`id1` timestamp NOT NULL default CURRENT_TIMESTAMP,
`id2` datetime default NULL
);
一般情况下,我倾向于使用 datetime 日期类型。
两者之间的比较:
1. timestamp容易所支持的范围比timedate要小。 并且容易出现超出的情况
2.timestamp比较受时区timezone的影响以及MYSQL版本和服务器的SQL MODE的影响.
MySQL 时间类型:时间格式、所占存储空间、时间范围。
时间类型 存储空间 时间格式 时间范围
------------ --------- --------------------- -----------------------------------------
time 3 bytes HH:MM:SS -838:59:59 ~ 838:59:59
time 时间范围居然有这么大的范围,特别是 time 可以取负值,有点奇怪。后来,看了 MySQL 手册才知道这是为了满足两个日期时间相减才这样设计的。
select timediff('2000:01:31 23:59:59', '2000:01:01 00:00:00'); -- 743:59:59
select timediff('2000:01:01 00:00:00', '2000:01:31 23:59:59'); -- -743:59:59
select timediff('23:59:59', '12:00:00'); -- 11:59:59
注意,timediff 的两个参数只能是 datetime/timestamp, time 类型的,并且这两个参数类型要相同。即:datetime/timestamp 和 datetime/timestamp 比较;time 和 time 相比较。
虽然 MySQL 中的日期时间类型比较丰富,但遗憾的是,目前(2008-08-08)这些日期时间类型只能支持到秒级别,不支持毫秒、微秒。也没有产生毫秒的函数。
参考自:http://m.jb51.net/article/23966.htm 还有MySQL的时间函数部分
二:java.util.Date java.sql.Date java.sql.Time java.sql.Timestamp区别和联系
在Web开发中,避免不了对日期的操作,常用的关于时间的类有这么几个:
java.util.Date、java.sql.Date、java.sql.Time、java.sql.Timestamp,这几个类在JDK的定义如下所示:
java.lang.Object
....|__java.util.Date
..........|__java.sql.Date/java.sql.Timestamp/java.sql.Time
....|__java.security.Timestamp
java.util.Date日期格式为:年月日时分秒
java.sql.Date日期格式为:年月日[只存储日期数据不存储时间数据,是专门针对sql设计]
java.sql.Time日期格式为:时分秒
java.sql.Timestamp日期格式为:年月日时分秒纳秒(毫微秒)
这些类的关系如下所示:
java.util.Date这个类是java.sql.Date, java.sql.Time, java.slq.Timestamp这三个类的父类。这三个类对java.util.Date类进行了包装。
java.sql.Date类屏蔽了java.util.Date类的时间有关的方法(形如:hh:mm:ss),因此,不可以通过这个类访问时间有关的信息,比如,如果你通过sqlDate.getHour()方法去访问小时信息,此方法会抛出一个IllegalArgumentException异常。这是因为java.sql.Date在继承java.util.Date类的时候对父类进行了重写,禁用了时间访问的方法。之所以这么处理,是为了和数据库的Date数据类型相匹配,数据库的Date数据类只是保存日期有关的字段。但是它java.sql.Date类有getTime方法返回毫秒数,所以它可以与java.util.Date进行互换:
java.sql.Date转为java.util.Date
java.sql.Date sqlDate=new java.sql.Date();
java.util.Date utilDate=new java.util.Date (sqlDate.getTime());
java.util.Date转为java.sql.Date
java.util.Date utilDate=new Date();
java.sql.Date sqlDate=new java.sql.Date(utilDate.getTime());
java.sql.Time类屏蔽了java.util.Date的日期有关的字段(形如:yyyy-MM-dd),因此,不能通过这个类访问日期有关的信息,比如:如果你通过sqlTime.getYear()方法去获取年有关的信息,此方法会抛出一个IllegalArgumentException异常。这是因为java.sql.Time在继承java.util.Date类的时候对父类进行了重写,禁用了日期访问的方法。之所以这么处理,是为了和数据库的Time数据类型相匹配,数据库的Time数据类行只是保存时间有关的字段。
java.sql.date 是只包含了日期。而 java.sql.time 只包含了一个时间。java.sql.time java.sql.date 二者如何组合成一个java.util.date呢?取毫秒相加,作为java.util.date的构造方法参数就可以了。
java.sql.Date d = new java.sql.Date(new java.util.Date().getTime());
java.sql.Time t = new java.sql.Time(new java.util.Date().getTime());
java.util.Date day = new java.util.Date(d.getTime() + t.getTime());
java.sql.Timestamp字段则对java.util.Date这个类进行了扩充,它在java.util.Date类的基础上增加了毫秒的时间访问控制,因此,你可以通过getNanos方法去获取时间的毫微秒数(注意此处获取的时间是以毫微秒为单位的,1秒等于十亿毫微秒),同样的,这也是为了和数据库中的Timestamp数据类型进行匹配。
理清了上述四个类的关系,那么java.util.Date和java.util.Calendar类有什么关系呢?
java.util.Calendar类是java.util.Date类的一个更加深入,更加全面的替代。Java.util.Calendar类支持java.util.Date的所有功能,此外,Calendar还引入了多语言,多区域的特性,可以根据需要获取不同区域,不同时区的时间,Calendar还增加了比Date更加方便和快捷的许多操作,如获取一年当中的第几个星期,各个月的天数等便捷的方法。
Java.util.Calendar区别与java.util.Date的几个地方也需要注意一下:首先,Calendar增加了毫秒的时间段,通过它可以获取时间点的毫秒值,而java.util.Date只是精确到秒。其次,Calendar获取年的时候是当前年份比如:2010,而Date获取年份的时获取到的是当前年份-1900的一个值(2010-1900=110,因此,你调用getYear后过去的值就是110)。最后Calendar是一个抽象类,之所以能够实例化,是因为此处的Calendar充当了一个类似于工厂的作用,在getInstance方法中实例化了Calendar子类GregorianCalendar,并把它返回给用户使用。
date java.sql.Date
datetime java.sql.Timestamp
timestamp java.sql.Timestamp
time java.sql.Time
year java.sql.Date
Java代码
//获得系统时间
java.util.Date date = new java.util.Date();
//将时间格式转换成符合Timestamp要求的格式
String nowTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
java.sql.Timestamp ts_date = java.sql.Timestamp.valueOf(nowTime)
// ......
preparedStatement.setTimestamp(1, ts_date );
// ......
// 使用毫秒时间值构造 Timestamp 构造方法里面可以写new java.util.Date().getTime() 或者 System.currentTimeMillis()
Timestamp date=new Timestamp(System.currentTimeMillis());
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd a HH:mm:ss");
JDBCTemplate jdbc=new JDBCTemplate();
jdbc.update("insert into message values(?,?,?)",username,date,context);
在mapper中从数据库读取数据:
Message a = new Message();
a.setTime(rs.getTimestamp("time"));
注意数据库中时间类型要和Javah中时间类型和上面说的一一对应 就不会出现问题
DAY_OF_MONTH
get
和 set
的字段数字,指示一个月中的某天 例如
Calendar c=Calendar.getInstance();
//把这个calendar的日(默认系统当前月的)设置为1号
c.set(Calendar.DAY_OF_MONTH,1);
<pre name="code" class="java">//获取当前月份天数的最大值
double days=c.getActualMaximum(Calendar.DAY_OF_MONTH);
//这个1号所在星期的星期 返回是星期几(1-7从星期天开始) -1表示从0开始0~6
double firstDay=c.get(Calendar.DAY_OF_WEEK)-1;
获得某月的天数
Calendar time=Calendar.getInstance();
time.clear();
time.set(Calendar.YEAR,year);
//year年
time.set(Calendar.MONTH,month-1);
//Calendar对象默认一月为0,month月
int day=time.getActualMaximum(Calendar.DAY_OF_MONTH);//本月份的天数