java中的日期和时间

一、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
time 3 bytes HH:MM:SS  -838:59:59  ~ 838:59:59
                        
解释:
1、在 MySQL 中创建表时,对照上面的表格,很容易就能选择到合适自己的数据类型。不过到底是选择 datetime 还是 timestamp,可能会有点犯难。这两个日期时间类型各有优点:datetime 的日期范围比较大;timestamp 所占存储空间比较小,只是 datetime 的一半。 个人倾向于使用 datetime 日期类型。
2、timestamp 类型的列还有个特性:默认情况下,在 insert, update 数据时,timestamp 列会自动以当前时间(CURRENT_TIMESTAMP)填充/更新。“自动”的意思就是,你不去管它,MySQL 会替你去处理;而其他时间类型不会。       
3、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 相比较。                       

二、java代码与数据库时间字段读写

1、实例

在说明之前,我们先来做个例子:
①在数据库中创建表“date_and_time”,除id外,其他字段是数据库中各类型的时间字段
Field Type Comment
id int(11) 主键
dateDemo date date类型
datetimeDemo datetime datetime类型
timestampDemo timestamp Timestamp类型
timeDemo time time类型
yearDemo year(4) year类型
并添加一条数据:
 

②在程序中查询该条数据,并打印每个字段的数据类型,调用代码如下:
   
   
  1. //数据库连接代码省略
  2. //查询
  3. findPst = conn.prepareStatement("select * from date_and_time where id=?");
  4. findPst.setInt(1, 8);
  5. ResultSet rs = findPst.executeQuery();
  6. ResultSetMetaData rsmd = rs.getMetaData();
  7. int columnCount = rsmd.getColumnCount();
  8. while(rs.next()){
  9. for (int i=1; i<=columnCount; i++) {
  10. Object obj = rs.getObject(i);
  11. //打印字段名称、字段内容、字段的数据类型
  12. System.out.println(rsmd.getColumnName(i)+":"+obj+","+obj.getClass());
  13. }
  14. }
③在控制台输出,打印结果如下:
    
    
  1. id:1,class java.lang.Integer
  2. dateDemo:2017-06-22,class java.sql.Date
  3. datetimeDemo:2017-06-22 15:33:08.0,class java.sql.Timestamp
  4. timestampDemo:2017-06-22 15:33:08.0,class java.sql.Timestamp
  5. timeDemo:15:33:08,class java.sql.Time
  6. yearDemo:1990-01-01,class java.sql.Date
④从打印结果可以看出,数据库的时间类型,对应的都是java.sql.*包下面的类。对应关系如下表:
MySql的时间类型 Java中与之对应的时间类型
date java.sql.Date
Datetime java.sql.Timestamp
Timestamp java.sql.Timestamp
Time java.sql.Time
Year java.sql.Date
所以从数据库中取出时,也可以使用对应的getXXX方法进行取出。如getTimestamp()、getDate()、getTime() 方法;其中getTimestamp()、getDate()方法可以取出数据库中全部的时间类型字段,并将字段转化java.sql.Timestamp、java.sql.Date类型,不过会丢失精度或补全数据,如下:
    
    
  1. //连接数据库、获取结果集的代码略过
  2. while(rs.next()){
  3. for (int i=2; i<=columnCount; i++) {
  4. java.sql.Date obj = rs.getDate(i);
  5. //打印字段名称、字段内容、字段的数据类型
  6. System.out.println(rsmd.getColumnName(i)+":"+obj+","+obj.getClass());
  7. Timestamp timestamp = rs.getTimestamp(i);
  8. System.out.println(rsmd.getColumnName(i)+":"+timestamp+","+timestamp.getClass());
  9. }
  10. }
     
     
  1. dateDemo:2017-06-22,class java.sql.Date
  2. dateDemo:2017-06-22 00:00:00.0,class java.sql.Timestamp
  3. datetimeDemo:2017-06-22,class java.sql.Date
  4. datetimeDemo:2017-06-22 15:33:08.0,class java.sql.Timestamp
  5. timestampDemo:2017-06-22,class java.sql.Date
  6. timestampDemo:2017-06-22 15:33:08.0,class java.sql.Timestamp
  7. timeDemo:1970-01-01,class java.sql.Date
  8. timeDemo:1970-01-01 15:33:08.0,class java.sql.Timestamp
  9. yearDemo:1990-01-01,class java.sql.Date
  10. yearDemo:1990-01-01 00:00:00.0,class java.sql.Timestamp
getTime() 方法不能取出year类型的字段,其他字段可以获取并转化类型。
    
    
  1. dateDemo:00:00:00,class java.sql.Time
  2. datetimeDemo:15:33:08,class java.sql.Time
  3. timestampDemo:15:33:08,class java.sql.Time
  4. timeDemo:15:33:08,class java.sql.Time
当然也可以通过getString()方法,将字段都转化成字符串。
     
     
  1. datetimeDemo:2017-06-22 15:33:08.0,class java.lang.String
  2. timestampDemo:2017-06-22 15:33:08.0,class java.lang.String
  3. timeDemo:15:33:08,class java.lang.String
  4. yearDemo:1990-01-01,class java.lang.String
通过结果和源码可以看出,都是先将字段变为对应的java类型,然后转化成String类型。

2、java.util.Date和java.sql.Date、Time、Timestamp

java.sqlDate,Time,Timestamp三个类有共同的父类,就是java.util.Date。它们的日期格式如下 (其实通过上面的例子也可以看出格式) :           
java.util.Date日期格式为:年月日时分秒 
java.sql.Date日期格式为:年月日
java.sql.Time日期格式为:时分秒 
java.sql.Timestamp日期格式为:年月日时分秒纳秒(毫微秒)

相互之间可以通过转换成“long”类型,进行转换
     
     
  1. java.util.Date utildate = new java.util.Date();
  2. System.out.println("utildate:"+utildate);
  3. java.sql.Date sqlDate = new java.sql.Date(utildate.getTime());
  4. System.out.println("sqlDate:"+sqlDate);
  5. java.sql.Time sqlTime = new java.sql.Time(utildate.getTime());
  6. System.out.println("sqlTime:"+sqlTime);
  7. java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(utildate.getTime());
  8. System.out.println("sqlTimestamp:"+sqlTimestamp);
      
      
  1. utildate:Fri Jun 23 17:16:02 CST 2017
  2. sqlDate:2017-06-23
  3. sqlTime:17:16:02
  4. sqlTimestamp:2017-06-23 17:16:02.843

3、写入数据库

将程序中的日期和时间数据写入数据库中,有以下几个方式:
①像上面一样,通过java.util.Date转化为对应类型的数据,进行保存和写入
     
     
  1. pst = conn.prepareStatement("INSERT INTO date_and_time(`dateDemo`,`datetimeDemo`,`timestampDemo`,`timeDemo`,`yearDemo`) VALUES (?,?,?,?,?)");
  2. java.util.Date utildate = new java.util.Date();
  3. java.sql.Date sqlDate = new java.sql.Date(utildate.getTime());
  4. java.sql.Time sqlTime = new java.sql.Time(utildate.getTime());
  5. java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(utildate.getTime());
  6. //添加参数
  7. pst.setDate(1,sqlDate);
  8. pst.setTimestamp(2,sqlTimestamp);
  9. pst.setTimestamp(3,sqlTimestamp);
  10. pst.setTime(4,sqlTime);
  11. pst.setInt(5, 11);
  12. pst.executeUpdate();

注:YEAR(1byte)年份类型。允许的值是1901到2155,MySQL以YYYY格式来显示YEAR值,但是允许你把使用字符串或数字值赋给YEAR列。

或者不用转化,直接使用java.util.Date
     
     
  1. pst.setObject(1,new Date());
  2. pst.setObject(2,new Date());
  3. pst.setObject(3,new Date());
  4. pst.setObject(4,new Date());
  5. pst.setInt(5, 2011);

③也可以使用字符串类型,但格式必须正确,格式不正确会报com.mysql.jdbc.MysqlDataTruncation异常。
     
     
  1. pst.setObject(1,"2017-1-1");
  2. pst.setObject(2,"2017-10-05 10:10:10");
  3. pst.setObject(3,"2017-5-05 10:10:10");
  4. pst.setObject(4,"23:59:59");
  5. pst.setInt(5, 11);
  6. pst.executeUpdate();


三、java.util.Calendar与java.text.SimpleDateFormat

除了上面说的 java.sqlDate,Time,Timestamp和java.util.Date类外,还有两个与时间有关的类,那就是java.util.Calenda和java.text.SimpleDateFormat。

1、Calendar

java.util.Calendar['kælɪndə] 类(日历类):Calendar类是一个抽象基类,主要用于日期之间的各种计算。它为特定瞬间与一组诸如 YEARMONTHDAY_OF_MONTHHOUR 等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。瞬间可用毫秒值来表示,它是距历元(即格林威治标准时间 1970 年 1 月 1 日的 00:00:00.000,格里高利历)的偏移量。
获取Calendar实例的方法:Calendar 提供了一个类方法 getInstance,以获得此类型的一个通用的对象。Calendar  getInstance 方法返回一个 Calendar 对象,其日历字段已由当前日期和时间初始化:

    
    
      
      
  1. Calendar rightNow = Calendar.getInstance();

日历字段:
    YEAR                           这是哪年
    MONTH                      这是月(从0开始)
    WEEK_OF_YEAR          今年的第几星期
    WEEK_OF_MONTH     这个月的第几星期(从一开始)
    DATE                          今天几号
    DAY_OF_MONTH       这个月的第几天
    DAY_OF_YEAR            这一年的第几天
    DAY_OF_WEEK           这周周几(从星期天开始计算,从1计算)
    DAY_OF_WEEK_IN_MONTH 第几周(从第一天开始算一周)
    AM_PM                      上午还是下午 0为上午,1为下午
    HOUR                         12小时制几点
    HOUR_OF_DAY          24小时制几点
    MINUTE                     多少分
    SECOND                    多少秒
    MILLISECOND           多少毫秒
    ZONE_OFFSET           时区

通过一个例子来看java.util.Calendar的使用:
     
     
  1. public static void main(String[] args) throws SQLException{
  2. //通过格式化输出日期
  3. java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
  4. //取得年月日、小时分钟秒
  5. Calendar cal = Calendar.getInstance();
  6. System.out.println("年:"+cal.get(Calendar.YEAR));
  7. System.out.println("月:"+cal.get(Calendar.MONTH)); // 0 - 11;java月份是从0-11,月份设置时要减1.
  8. System.out.println("日:"+cal.get(Calendar.DATE));
  9. System.out.println("时:"+cal.get(Calendar.HOUR_OF_DAY));
  10. System.out.println("分:"+cal.get(Calendar.MINUTE));
  11. System.out.println("秒:"+cal.get(Calendar.SECOND));
  12. //取当前日期的前一天
  13. Calendar cal1 = Calendar.getInstance();
  14. cal1.add(Calendar.DAY_OF_MONTH, -1);
  15. System.out.println("当前日期的前一天:"+format.format(cal1.getTime()));
  16. //取当前日期的后一天
  17. Calendar cal2 = Calendar.getInstance();
  18. cal2.add(Calendar.DAY_OF_MONTH, +1);
  19. System.out.println("当前日期的后一天:"+format.format(cal2.getTime()));
  20. //判断当前月份的最大天数
  21. Calendar cal3 = Calendar.getInstance();
  22. int day=cal3.getActualMaximum(Calendar.DAY_OF_MONTH);
  23. System.out.println("当前月份的最大天数:"+day);
  24. //5小时前的时间
  25. Calendar Cal4 = Calendar.getInstance();
  26. Cal4.add(Calendar.HOUR_OF_DAY,-5);
  27. System.out.println("5小时前的时间:"+format.format(Cal4.getTime()));
  28. //加12个月
  29. cal.set(Calendar.MONTH, 12);
  30. //前一天
  31. cal.set(Calendar.DATE, -1);
  32. //根据今天获取星期一和星期天
  33. System.out.println("今天 :"+format.format(new Date()));
  34. Calendar c=Calendar.getInstance();
  35. c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
  36. System.out.println("星期一:"+format.format(c.getTime()));
  37. c.set(Calendar.DAY_OF_WEEK, Calendar.SATURDAY);
  38. System.out.println("星期六:"+format.format(c.getTime()));
  39. }

 Calendar 与 Date 的转换非常简单:

    Calendar calendar = Calendar.getInstance();
    // 从一个 Calendar 对象中获取 Date 对象
    Date date = calendar.getTime();
    // 将 Date 对象反应到一个 Calendar 对象中,
    // Calendar/GregorianCalendar 没有构造函数可以接受 Date 对象
    // 所以我们必需先获得一个实例,然后设置 Date 对象
    calendar.setTime(date);



2、java.text.SimpleDateFormat

SimpleDateFormat主要有两个功能:时间日期的格式化和字符串解析为时间,全部时间类型都可以被SimpleDateFormat格式化format()为字符串对象,如下例:
     
     
  1. String pattern_ymd_hms = "yyyy-MM-dd HH:mm:ss"; // pattern_ymdtime
  2. DateFormat format = new SimpleDateFormat(pattern_ymd_hms);
  3. java.util.Date utildate = new java.util.Date();
  4. java.sql.Date sqlDate = new java.sql.Date(utildate.getTime());
  5. java.sql.Time sqlTime = new java.sql.Time(utildate.getTime());
  6. java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(utildate.getTime());
  7. System.out.println("utildate格式转换:"+format.format(utildate));
  8. System.out.println("sqlDate格式转换:"+format.format(sqlDate));
  9. System.out.println("sqlTime格式转换:"+format.format(sqlTime));
  10. System.out.println("sqlTimestamp格式转换:"+format.format(sqlTimestamp));
      
      
  1. utildate格式转换:2017-06-26 11:00:01
  2. sqlDate格式转换:2017-06-26 11:00:01
  3. sqlTime格式转换:2017-06-26 11:00:01
  4. sqlTimestamp格式转换:2017-06-26 11:00:01

将字符串解析为时间类型:
      
      
  1. SimpleDateFormat format = new SimpleDateFormat(pattern_ymd_hms);
  2. try {
  3. format.parse(date);
  4. } catch (ParseException e) {
  5. e.printStackTrace();
  6. }


3、Date and Time Patterns

在上面的例子中,我们看到“yyyy-MM-dd HH:mm:ss”这样的时间格式,它们每个字母都代表什么意思呢。下面是我查询JDK的API文档获得的内容(只列举了常用的一些):
Letter Date or Time Component Presentation Examples
y Year Year 199696
Y Week year Year 200909
M Month in year Month JulyJul07
w Week in year Number 27
W Week in month Number 2
D Day in year Number 189
d Day in month Number 10
E Day name in week Text TuesdayTue
u Day number of week (1 = Monday, ..., 7 = Sunday) Number 1
H Hour in day (0-23) Number 0
k Hour in day (1-24) Number 24
K Hour in am/pm (0-11) Number 0
h Hour in am/pm (1-12) Number 12
m Minute in hour Number 30
s Second in minute Number 55
S Millisecond Number 978
其中需要注意的有:
1、HH和hh:HH代表的是24小时制;hh代表的是12小时制。
2、yyyy和YYYY的区别,其中大写的Y,代表的是week year,其意思是当天所在的周属于的年份,一周从周日开始,周六结束,只要本周跨年,那么这周就算入下一年,例如2010.12.26,日历长成这样
 12.26所在的周的最后一天是2011.1.1,这天属于2011,所以2010.12.26的Week year就是2011,用YYYY做格式化,就会得到2011.12.26。








  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值