2013-07-29 35 views
10

我有时会被java中不同的Date类型及其实际用法所困惑。这里 我试图总结一下我的理解Date vs TimeStamp vs calendar?

java.sql.Date :-围绕一个毫秒值,它允许JDBC将该类标识为SQL DATE值瘦包装

java.sql.Timestamp :- java.util.Date瘦包装器,它允许JDBC API将其标识为SQL TIMESTAMP值。它增加了保留SQL TIMESTAMP小数秒值的功能,允许将小数秒的规格 精确到几纳秒

我已经看到大多数项目更喜欢Timestamp而不是日期。我认为这样做的主要原因是时间戳可以保持数值直到 纳秒精度,而数据可以保持到毫秒。正确?

Calendar :-此类设计为日期操作,例如: - 用于在某一特定时刻和 组日历字段,诸如年,月,DAY_OF_MONTH,HOUR之间转换,等等,以及用于操纵该日历字段,如获得 下周的日期。尽管我不知道为什么这个类是抽象的,只有一个实现存在,即GregorianCalendar。

回答

13

java.sql.Timestamp一个围绕java.util.Date的薄包装,它允许JDBC API将此标识为SQL TIMESTAMP值。

如果检查java.sql.Timestamp JavaDoc,这是非常明确的,这一类扩展从java.util.Date(如java.sql.Date一样)。而在真实世界的项目中,当将数据存储在数据库中时,您必须使用简单的java.util.Date,因为它存储日期和时间值,因此大多数为java.sql.Timestamp,而java.sql.Date仅存储日期值。

另一方面,java.util.Calendar是抽象的,因为除java.util.GregorianCalendar之外还有更多的实现。如果您看到HotSpot的代码Calendar#getInstance,您会看到它调用createCalendar(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT)),并且此方法代码使用3种不同的日历:BuddhistCalendarJapaneseImperialCalendarGregorianCalendar。此代码从JDK 7的源复制:

private static Calendar createCalendar(TimeZone zone, 
             Locale aLocale) { 
    Calendar cal = null; 

    String caltype = aLocale.getUnicodeLocaleType("ca"); 
    if (caltype == null) { 
     // Calendar type is not specified. 
     // If the specified locale is a Thai locale, 
     // returns a BuddhistCalendar instance. 
     if ("th".equals(aLocale.getLanguage()) 
       && ("TH".equals(aLocale.getCountry()))) { 
      cal = new BuddhistCalendar(zone, aLocale); 
     } else { 
      cal = new GregorianCalendar(zone, aLocale); 
     } 
    } else if (caltype.equals("japanese")) { 
     cal = new JapaneseImperialCalendar(zone, aLocale); 
    } else if (caltype.equals("buddhist")) { 
     cal = new BuddhistCalendar(zone, aLocale); 
    } else { 
     // Unsupported calendar type. 
     // Use Gregorian calendar as a fallback. 
     cal = new GregorianCalendar(zone, aLocale); 
    } 

    return cal; 
} 

现在,为什么直接与Calendar,而不是GregorianCalendar工作?因为您必须在提供抽象类和接口时使用它,而不是直接使用实现。这是更好地在这里解释:What does it mean to "program to an interface"?

从这个

除此之外,如果你将日期和时间的工作,我建议使用像Joda-Time库,已处理和解决了很多与当前Java日期API的问题,也提供了一些方法在java.util.Date中检索这个日期和时间对象。

1

在原来的问题第一行包含短语“不同的日期类型的Java和自己的实际使用情况”

时间戳数据类型的实际使用是完全一样的说 - 通过SQL使用的时间戳记录通常用于交易订购的精确的按时间顺序的值。时间戳通常只用于内部...纳秒数。有外部时间戳数据的用例,但它们相对较少。

日期类型以毫秒级精度处理99%的外部非科学数据需求。

+0

当你说“日期类型”我收集你的意思是'java.util.Date'(这不是问了什么,但仍然相关)。符合[罗勒Bourque的答案](https://stackoverflow.com/a/32975887/5772882)我说使用'java.time.Instant'来代替。 –

4

您必须首先了解那些与早期版本的Java捆绑在一起的旧日期时间类是一个令人困惑的设计错误的类与黑客混乱的混乱。他们是业界首次尝试在日期时间处理的复杂设施上进行尝试,并因此获得了信任。但最终他们失败了。

它们已被Java 8及更高版本中内置的新java.time框架所取代。

  • java.sql.Date - 使用java.time.LocalDate代替
  • java.sql.Timestamp - 使用java.time.Instant代替
  • java.util.Calendar & GregorianCalendar - 使用java.time.ZonedDateTime代替

对于日期只,没有时间的天,也不时区,使用LocalDate。在UTC的时间轴上片刻,使用Instant。要为Instant分配不同的时区,请使用ZonedDateTime

对于数据库工作,我们最终应该看到更新的JDBC驱动程序直接使用这些新的java.time类型。同时寻找在新旧类别中找到的方便转换器方法。使用java.sql.Date作为仅限日期的值。使用java.sql.Timestamp获取日期时间值。

我不会在这里包含代码,因为在许多其他重复问题上已经完成了代码。请搜索StackOverflow。

相关问题