1.Date.getTime() 和 Calendar.getTimeInMillis() 返回自 1970 年 1 月 1 日 00:00:00 GMT+0 以来此 Date 对象表示的毫秒数。
证明
package com.siyuan.test.jdk; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; public class TimeTest { public static void main(String[] args) throws ParseException { SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Calendar calendar = Calendar.getInstance(); String timeStr = "1970-01-01 00:00:00"; Date time = dateFmt.parse(timeStr); System.out.println(time.getTime()); calendar.setTime(time); System.out.println(calendar.getTimeInMillis()); System.out.println(TimeZone.getDefault()); } }
输出结果
-28800000 -28800000 sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null]
-28800000 = 8 * 3600 * 1000
Asia/Shanghai 位于 GMT+0800
2.TimeZone对DateFormat的影响
package com.siyuan.test.jdk; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.TimeZone; public class DateFormatTest { public static void main(String[] args) { SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Calendar calendar = Calendar.getInstance(); System.out.println(dateFmt.format(calendar.getTime())); System.out.println(dateFmt.getTimeZone()); System.out.println(TimeZone.getDefault()); System.out.println("======================================================"); dateFmt.setTimeZone(TimeZone.getTimeZone("GMT+00")); System.out.println(dateFmt.format(calendar.getTime())); } }
输出结果
2014-10-20 22:34:44 sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null] sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null] ====================================================== 2014-10-20 14:34:44
3.MySQL中的DateTime数据类型
1)建表
CREATE TABLE `t_date_i18n` ( `FID` int(11) NOT NULL AUTO_INCREMENT, `FDate` datetime DEFAULT NULL, `FTimeStamp` timestamp NULL DEFAULT NULL, PRIMARY KEY (`FID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2)JDBC操作
--存储
package com.siyuan.test.jdk; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Timestamp; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; public class DBDateTest { public static String DRIVER_CLASS_NAME = "com.mysql.jdbc.Driver"; public static String USER_NAME = "root"; public static String PASSWORD = "123456"; public static String URL = "jdbc:mysql://localhost:3306/study"; public static Connection getConnection() throws ClassNotFoundException, SQLException { Class.forName(DRIVER_CLASS_NAME); return DriverManager.getConnection(URL, USER_NAME, PASSWORD); } public static final String SQL_SAVE = "INSERT INTO t_date_i18n(FDate, FTimeStamp) values(?, ?)"; /** * 使用setDate方法存储 */ public void save(Date date) { Connection conn = null; PreparedStatement pstat = null; try { conn = DBDateTest.getConnection(); conn.setAutoCommit(false); pstat = conn.prepareStatement(SQL_SAVE); java.sql.Date dateSaved = new java.sql.Date(date.getTime()); pstat.setDate(1, dateSaved); pstat.setDate(2, dateSaved); pstat.executeUpdate(); conn.commit(); } catch (Exception e) { e.printStackTrace(); } finally { try { pstat.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } /** * 使用setTimestamp方法存储 */ public void save_2(Date date) { Connection conn = null; PreparedStatement pstat = null; try { conn = DBDateTest.getConnection(); conn.setAutoCommit(false); pstat = conn.prepareStatement(SQL_SAVE); Timestamp timestampSaved = new Timestamp(date.getTime()); pstat.setTimestamp(1, timestampSaved); pstat.setTimestamp(2, timestampSaved); pstat.executeUpdate(); conn.commit(); } catch (Exception e) { e.printStackTrace(); } finally { try { pstat.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } public static void main(String[] args) throws ParseException { DBDateTest test = new DBDateTest(); DateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateStr = "2014-10-25 00:00:00"; Date date1 = dateFmt.parse(dateStr); test.save(date1); dateFmt.setTimeZone(TimeZone.getTimeZone("GMT+00")); Date date2 = dateFmt.parse(dateStr); test.save_2(date2); TimeZone.setDefault(TimeZone.getTimeZone("GMT+02")); DateFormat dateFmt2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); date1 = dateFmt2.parse(dateStr); test.save(date1); dateFmt2.setTimeZone(TimeZone.getTimeZone("GMT+00")); date2 = dateFmt2.parse(dateStr); test.save_2(date2); } }
结果:
java.sql.Date
为了与 SQL DATE
的定义一致,由 java.sql.Date
实例包装的毫秒值必须通过将小时、分钟、秒和毫秒设置为与该实例相关的特定时区中的零来“规范化”。
java.sql.Timestamp
将时间转化为JDK默认TimeZone对应的时间进行存储。
存储时均和数据库的时区无关。
--读取
package com.siyuan.test.jdk; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; public class DBDateTest { public static String DRIVER_CLASS_NAME = "com.mysql.jdbc.Driver"; public static String USER_NAME = "root"; public static String PASSWORD = "123456"; public static String URL = "jdbc:mysql://localhost:3306/study"; public static Connection getConnection() throws ClassNotFoundException, SQLException { Class.forName(DRIVER_CLASS_NAME); return DriverManager.getConnection(URL, USER_NAME, PASSWORD); } public static final String SQL_GET = "SELECT FDate, FTimeStamp FROM t_date_i18n WHERE FID = ?"; /** * 使用setDate方法存储 */ public void get(int id) { Connection conn = null; PreparedStatement pstat = null; try { conn = DBDateTest.getConnection(); conn.setAutoCommit(false); pstat = conn.prepareStatement(SQL_GET); pstat.setInt(1, id); ResultSet rs = pstat.executeQuery(); if (rs.next()) { System.out.println(format(rs.getDate(1))); System.out.println(format(rs.getTimestamp(2))); } conn.commit(); } catch (Exception e) { e.printStackTrace(); } finally { try { pstat.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } public static String format(Date date) { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); } public static void main(String[] args) throws ParseException { DBDateTest test = new DBDateTest(); test.get(1); TimeZone.setDefault(TimeZone.getTimeZone("GMT+02")); test.get(1); } }
结果
2014-10-25 00:00:00 2014-10-25 00:00:00 2014-10-25 00:00:00 2014-10-25 00:00:00
结论:
读取时保持时间一致,不管当前JDK的默认TimeZone是多少
3)MyBatis操作
--存储
package com.siyuan.test.mybatis.dao; import java.io.IOException; import java.io.InputStream; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.TimeZone; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import com.siyuan.test.mybatis.entity.DateI18N; public class DateI18NTest { public static void main(String[] args) throws IOException, ParseException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session2 = sqlSessionFactory.openSession(); try { DateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String dateStr = "2014-10-25 00:00:00"; DateI18N dateI18N = new DateI18N(); DateI18NDAO dateI18NDAO = session2.getMapper(DateI18NDAO.class); Date date1 = dateFmt.parse(dateStr); dateI18N.setDate(date1); dateI18NDAO.insert(dateI18N); dateFmt.setTimeZone(TimeZone.getTimeZone("GMT+00")); Date date2 = dateFmt.parse(dateStr); dateI18N.setDate(date2); dateI18NDAO.insert(dateI18N); TimeZone.setDefault(TimeZone.getTimeZone("GMT+02")); dateFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); date1 = dateFmt.parse(dateStr); dateI18N.setDate(date1); dateI18NDAO.insert(dateI18N); dateFmt.setTimeZone(TimeZone.getTimeZone("GMT+00")); date2 = dateFmt.parse(dateStr); dateI18N.setDate(date2); dateI18NDAO.insert(dateI18N); session2.commit(); } finally { session2.close(); } } }
DateI18N.java
package com.siyuan.test.mybatis.entity; import java.util.Date; public class DateI18N { private Date date; public DateI18N() { } public Date getDate() { return date; } public void setDate(Date date) { this.date = date; } }
DateI18NDAO.java
package com.siyuan.test.mybatis.dao; import com.siyuan.test.mybatis.entity.DateI18N; public interface DateI18NDAO { void insert(DateI18N dateI18N); }
DateI18NDAO.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.siyuan.test.mybatis.dao.DateI18NDAO"> <insert id="insert" parameterType="DateI18N"> INSERT INTO t_date_i18n (FDate) VALUES (#{date}) </insert> </mapper>
结果:
MyBatis的DateTypeHandler是采用Timestamp来处理Date对象的
4.国际化Date的方案
1)在对应的表里面新增一个字段,保存TimeZone
2)保存时统一为某一固定的TimeZone,读取时根据所需TimeZone进行转化
相关推荐
总结来说,`Date`和`Calendar`是Java中处理日期和时间的基础,它们提供了创建、修改和格式化日期的能力。虽然Java 8引入了更好的日期时间API,但了解和掌握这两个类的用法对于维护和理解老代码仍然是必不可少的。
【解析Date & Calendar类】 Java中的Date和Calendar类是处理日期和时间的核心工具。这两个类在Java编程中扮演着重要角色,特别是在处理日期计算、格式化以及与数据库交互时。 1. **java.util.Date** - **字符串转...
- 在处理国际化日期和时间格式时,`Calendar`提供了更多的灵活性和控制能力。 - 使用`Calendar`时,可以方便地进行日期的增减操作,而使用`Date`时则可以直接获取一个时间点的表示。 掌握这两种类型之间的转换方法...
在Java编程语言中,`Calendar`和`Date`类是处理日期和时间的核心组件。这两个类在处理日期、时间计算以及格式化等任务时扮演着关键角色。理解并熟练运用它们,对于提升Java开发能力至关重要。 `Date`类是Java早期...
### Date与Calendar详解:深入理解Java中的日期与时间操作 #### Date类的解析与应用 在Java编程中,`java.util.Date`类是用于表示特定时刻的类,它以自格林尼治时间(GMT)1970年1月1日午夜以来经过的毫秒数来存储...
总结来说,Java中的`Date`和`Calendar`类提供了基本的时间处理功能,`DateFormat`和`SimpleDateFormat`则负责日期和时间的格式化,使我们能够根据需要将日期和时间转换为人类可读的字符串。在实际开发中,这些类经常...
与`Date`相比,`Calendar`更适合进行日期计算和格式化。 接下来,我们来看一下如何使用`Calendar`来计算上月某一天的日期。假设我们要找到上个月的第一天,可以这样做: ```java Calendar calendar = Calendar....
最后,我们可以通过`getTime()`方法将修改后的Calendar对象转换回Date,然后再次使用DateFormat进行格式化输出: ```java Date updatedDate = calendar.getTime(); System.out.println(formatter.format(updated...
然而,`Date`类的格式化能力有限,它默认的`toString()`方法输出的格式并不符合常见的日期和时间格式,因此通常需要配合`SimpleDateFormat`或`DateTimeFormatter`(Java 8及以后版本)进行格式化。 ```java ...
为了解决这个问题,一位开发者使用C#编程语言创建了一个名为"DateCalendar"的自定义日历控件,旨在提供更加灵活和个性化的日期选择功能。 DateCalendar控件的核心特性在于其`DisplayMode`属性。通过对这个属性的...
在Java编程中,`new Date()` 和 `Calendar.getInstance().getTime()` 都是获取当前系统时间的方法,但有时可能会出现获取到的时间与预期不符的情况。这种问题通常与时区设置、系统时间、Java运行环境以及代码逻辑...
要将`Calendar`对象转换为`String`,我们首先需要通过`getTime()`方法获取`Date`对象,然后使用`SimpleDateFormat`格式化这个日期。 ```java Calendar calendar = Calendar.getInstance(); SimpleDateFormat sdf = ...
将`Calendar`对象转换为`Date`,再用`SimpleDateFormat`格式化: ```java String dateString = formatter.format(calendar.getTime()); ``` 在实际开发中,Java 8引入了`java.time`包,其中的`LocalDateTime`、...
`java.util.Date`和`java.util.Calendar`是两个核心的类,用于表示和操作日期。尽管`Date`类提供了许多功能,但它的某些方法如`getYear()`、`getMonth()`等在后续版本中被废弃,取而代之的是使用`Calendar`类来进行...
在实际编程中,这些类通常结合使用,例如,通过`Date`获取当前时间,然后利用`Calendar`进行修改,最后用`DateFormat`格式化输出。理解并熟练运用这些基础知识对于Java开发者来说至关重要,因为它们构成了Java日期和...
关于java中date和Calendar日期处理小结,包含一些常用方法等
在早期的JDK版本中,Date类是主要的日期时间表示类,但在JDK1.1之后,为了更好地支持国际化和增强功能,推荐使用Calendar类。 Date类: 1. **表示当前时间**:Date类有一个无参构造函数,创建的实例代表当前系统...
详细地Date、String、Calendar之间的转换
031105_【第11章:Java常用类库】_日期操作类(Date、Calendar)笔记
在上面的代码中,我们首先实例化了一个Calendar对象,然后使用`calendar.setTime(date)`方法将Date对象转换为Calendar对象。 三、Calendar和Date的异同 Calendar和Date都是Java中用于处理日期和时间的类,但是它们...