# Java 日期类
Java
日期类主要包括 java.util.Date
、 java.util.Calendar
和 java.time
包下的类。
java.util.Date
类是 Java
提供的最早的日期类,它表示自 1970 年 1 月 1 日 0 时 0 分 0 秒 (GMT) 起的毫秒数。但是它的设计存在缺陷,所以在 Java 8
之后,推荐使用 java.time 包下的日期类。
java.util.Calendar
类是一个抽象类,提供了一些基本的日期操作,比如获取某一时间的年、月、日、时、分、秒等。但是该类使用起来比较繁琐。
Java 8
之后推出了全新的日期时间 API
, java.time
包下的类,包括 LocalDate
、 LocalTime
、 LocalDateTime
、 ZonedDateTime
等,这些类提供了更简单易用的方法和更好的可读性,能够更方便地进行日期和时间的计算和格式化。
下面是一些常用的 Java 日期类的方法:
# Date
Date()
:创建一个表示当前时间的 Date 对象。getTime()
:返回自 1970 年 1 月 1 日 0 时 0 分 0 秒 (GMT) 起的毫秒数。toString()
:返回一个 String 类型的表示形式,格式为EEE MMM dd HH:mm:ss zzz yyyy
。
# Calender
getInstance()
:返回一个 Calendar 对象,表示当前时间。get(int field)
:获取指定的日期字段值,如Calendar.YEAR
、Calendar.MONTH
、Calendar.DAY_OF_MONTH
等。set(int field, int value)
:设置指定的日期字段值。getTime()
:返回一个 Date 对象,表示当前时间。
# JDK8 新增的日期类
Java 8 中引入了 java.time
包,该包提供了一组全新的日期和时间 API,其中包括 LocalDate
、 LocalDateTime
、 ZonedDateTime
等类,它们比旧的 java.util.Date
和 java.util.Calendar
更加方便易用,同时也更加安全和健壮。
以下是 LocalDate
、 LocalDateTime
的详细介绍:
# LocalDate
LocalDate
表示一个日期,不包含时间和时区信息。它可以用来表示一个生日、节日、合同签订日期等等。
创建 LocalDate
对象有多种方式,比如使用 now()
方法获取当前日期,或者使用 of()
方法指定年、月、日:
LocalDate today = LocalDate.now(); | |
LocalDate date = LocalDate.of(2023, 2, 24); |
我们可以通过 getYear()
、 getMonth()
、 getDayOfMonth()
等方法获取日期的年、月、日等信息:
int year = date.getYear(); | |
int month = date.getMonthValue(); | |
int day = date.getDayOfMonth(); |
LocalDate
还提供了很多方法,比如 plusDays()
、 minusMonths()
等,用于对日期进行加减操作。例如:
LocalDate tomorrow = today.plusDays(1); | |
LocalDate previousMonthSameDay = today.minusMonths(1); |
LocalDate
也支持一些常用的比较方法,比如 isBefore()
、 isAfter()
、 isEqual()
,用于比较两个日期的先后顺序:
boolean isBefore = today.isBefore(tomorrow); | |
boolean isAfter = today.isAfter(previousMonthSameDay); | |
boolean isEqual = today.isEqual(date); |
# LocalDateTime
LocalDateTime
表示一个日期时间,不包含时区信息。它可以用来表示一个会议时间、发布时间、交易时间等等。
创建 LocalDateTime
对象有多种方式,比如使用 now()
方法获取当前日期时间,或者使用 of()
方法指定年、月、日、时、分、秒等:
LocalDateTime now = LocalDateTime.now(); | |
LocalDateTime dateTime = LocalDateTime.of(2023, 2, 24, 10, 30, 0); |
我们可以通过 getYear()
、 getMonth()
、 getDayOfMonth()
、 getHour()
、 getMinute()
、 getSecond()
等方法获取日期时间的年、月、日、时、分、秒等信息:
int year = dateTime.getYear(); | |
int month = dateTime.getMonthValue(); | |
int day = dateTime.getDayOfMonth(); | |
int hour = dateTime.getHour(); | |
int minute = dateTime.getMinute(); | |
int second = dateTime.getSecond(); |
LocalDateTime
类是 Java 8 中的日期时间类,表示日期和时间,不带时区信息。下面是 LocalDateTime
类中常用的一些方法:
now()
:获取当前日期时间。
LocalDateTime now = LocalDateTime.now(); |
of()
:根据指定的年、月、日、时、分、秒、毫秒等参数创建一个LocalDateTime
实例。
LocalDateTime dateTime = LocalDateTime.of(2022, 3, 1, 12, 30, 0); |
plusXxx()
:在当前LocalDateTime
的基础上增加指定的时间量,其中 Xxx 可以是Years、Months、Weeks、Days、Hours、Minutes、Seconds
等。
LocalDateTime dateTime = LocalDateTime.now(); | |
LocalDateTime plusOneDay = dateTime.plusDays(1); |
minusXxx()
:在当前LocalDateTime
的基础上减少指定的时间量,其中 Xxx 可以是Years、Months、Weeks、Days、Hours、Minutes、Seconds
等。
LocalDateTime dateTime = LocalDateTime.now(); | |
LocalDateTime minusOneHour = dateTime.minusHours(1); |
getXxx()
:获取LocalDateTime
的指定部分,其中 Xxx 可以是Year、Month、DayOfMonth、DayOfWeek、DayOfYear、Hour、Minute、Second、NanoOfSecond
等。
LocalDateTime dateTime = LocalDateTime.now(); | |
int year = dateTime.getYear(); | |
Month month = dateTime.getMonth(); | |
int dayOfMonth = dateTime.getDayOfMonth(); | |
DayOfWeek dayOfWeek = dateTime.getDayOfWeek(); | |
int hour = dateTime.getHour(); | |
int minute = dateTime.getMinute(); | |
int second = dateTime.getSecond(); | |
int nano = dateTime.getNano(); |
withXxx()
:设置LocalDateTime
的指定部分,其中 Xxx 可以是Year、Month、DayOfMonth、DayOfWeek、DayOfYear、Hour、Minute、Second、NanoOfSecond
等。
LocalDateTime dateTime = LocalDateTime.now(); | |
LocalDateTime withYear2023 = dateTime.withYear(2023); |
isXxx()
:判断LocalDateTime
的指定部分是否满足某个条件,其中 Xxx 可以是LeapYear、After、Before
等。
LocalDateTime dateTime = LocalDateTime.now(); | |
boolean isLeapYear = dateTime.toLocalDate().isLeapYear(); |
toXxx()
:将LocalDateTime
转换为其他日期时间类,其中 Xxx 可以是LocalDate
、LocalTime
、Instant
等。
LocalDateTime dateTime = LocalDateTime.now(); | |
LocalDate date = dateTime.toLocalDate(); | |
LocalTime time = dateTime.toLocalTime(); | |
Instant instant = dateTime.toInstant(ZoneOffset.UTC); |
这些是 LocalDateTime
类中比较常用的方法,可以方便地对日期时间进行操作和计算。
# Instant
Java 的 Instant
类是用来表示时刻的类,可以精确到纳秒级别。它是不可变的,线程安全的。 Instant
类是在 Java 8 中引入的,它提供了与时区无关的机制来处理日期和时间。
Instant
类的实例可以从时钟获取当前时间,也可以从另一个 Instant
实例中创建,或者通过解析表示 ISO-8601 格式的字符串来创建。 Instant
类的 API 提供了许多方法来操作 Instant
实例,以下是一些常用方法:
now()
:获取当前时间戳的Instant
实例。
Instant now = Instant.now(); |
ofEpochSecond()
:根据秒数创建Instant
实例。
Instant instant = Instant.ofEpochSecond(1614305156); |
ofEpochMilli()
:根据毫秒数创建Instant
实例。
Instant instant = Instant.ofEpochMilli(1614305156000L); |
getEpochSecond()
:获取秒数。
long epochSecond = instant.getEpochSecond(); |
getNano()
:获取纳秒数。
int nano = instant.getNano(); |
plusSeconds()
:添加指定的秒数。
Instant newInstant = instant.plusSeconds(10); |
minusSeconds()
:减去指定的秒数。
Instant newInstant = instant.minusSeconds(10); |
isAfter()
:判断是否在指定的 Instant 实例之后。
boolean isAfter = instant.isAfter(anotherInstant); |
isBefore()
:判断是否在指定的Instant
实例之前。
boolean isBefore = instant.isBefore(anotherInstant); |
toString()
:将Instant
实例转换为字符串。
String str = instant.toString(); |
总之, Instant
类提供了一种简单而灵活的方式来处理日期和时间,它适用于需要精确处理时间戳的应用程序。
# Timestamp
Java 中的 Timestamp
类是用于处理数据库中日期时间类型的类,继承自 java.util.Date
类,但是它的精度要高于 Date
类,可以精确到纳秒级别。 Timestamp
类在 JDBC
程序中很常用,它可以表示精确到秒的时间戳。
Timestamp
类的构造方法有以下几种:
Timestamp(long time)
:根据指定的时间创建一个Timestamp
对象。Timestamp(String s)
:根据字符串表示的时间创建一个Timestamp
对象。Timestamp(int year, int month, int date, int hour, int minute, int second, int nano)
:根据指定的年、月、日、时、分、秒和纳秒数创建一个Timestamp
对象。
Timestamp
类中的常用方法包括:
getTime()
:返回以毫秒表示的Timestamp
值。valueOf(String s)
:将指定的字符串转换为Timestamp
类型。valueOf(LocalDateTime dateTime)
:将指定的LocalDateTime
转换为Timestamp
类型。toLocalDateTime()
:将Timestamp
对象转换为LocalDateTime
对象。compareTo(Timestamp ts)
:比较两个Timestamp
对象的大小。equals(Object ts)
:判断当前Timestamp
对象是否与指定对象相等。toString()
:将Timestamp
对象转换为字符串表示。setNanos(int n)
:设置Timestamp
对象的纳秒数。setYear(int year)
:设置Timestamp
对象的年份。setMonth(int month)
:设置Timestamp
对象的月份。setDate(int date)
:设置Timestamp
对象的日期。setHours(int hours)
:设置Timestamp
对象的小时。setMinutes(int minutes)
:设置Timestamp
对象的分钟。setSeconds(int seconds)
:设置Timestamp
对象的秒数。
总之, Timestamp
类是 Java 中处理时间戳的一个重要类,它可以很方便地将时间戳转换为日期时间类型,或者将日期时间类型转换为时间戳。在开发中,我们通常会使用 Timestamp
来操作数据库中的时间类型数据。
# Locale
Java 中的 Locale
类表示了特定地理、政治或文化区域的信息,比如国家、语言、货币等。通过 Locale
类,Java 程序可以获取与地区相关的信息,例如日期和时间格式、货币符号、语言环境等。 Locale
类的实例表示一个特定的地理、政治或文化区域,由语言代码和国家(或地区)代码组成,例如 “en_US” 表示美国英语环境。
Locale
类提供了多个构造函数和静态方法,用于创建和获取特定的地理、政治或文化区域。常用的构造函数和方法包括:
Locale(String language)
通过指定的语言代码创建一个Locale
实例,国家代码默认为 ""。Locale(String language, String country)
通过指定的语言代码和国家代码创建一个Locale
实例。Locale(String language, String country, String variant)
通过指定的语言代码、国家代码和变量创建一个Locale
实例。Locale.getDefault()
获取当前默认的Locale
实例。Locale.getAvailableLocales()
获取所有可用的Locale
实例。getCountry()
获取Locale
实例的国家代码。getLanguage()
获取Locale
实例的语言代码。getDisplayName()
获取Locale
实例的显示名称。getDisplayName(Locale inLocale)
获取在指定 Locale 环境下的Locale
实例的显示名称。
Locale
类的应用场景包括但不限于以下几种:
- 本地化日期、时间、货币等格式
- 国际化应用程序的开发
- 区域性数据的处理
- 多语言文本的翻译和处理
# Zone 相关的类
在 Java 中,关于时区的相关操作主要是通过 java.time.Zone
相关的类来完成的。
首先, ZoneId
类表示了一个时区标识符,可以使用 ZoneId.of()
方法来获取。比如,以下代码可以获取表示 "Asia/Shanghai" 时区的 ZoneId
:
ZoneId zoneId = ZoneId.of("Asia/Shanghai"); |
ZoneOffset
类表示了一个以秒为单位的时间偏移量,可以使用 ZoneOffset.ofTotalSeconds()
方法来获取。比如,以下代码可以获取表示东八区的 ZoneOffset
:
ZoneOffset offset = ZoneOffset.ofTotalSeconds(8 * 3600); |
ZonedDateTime
类表示了一个带时区的日期和时间。可以使用 ZonedDateTime.of()
方法来创建一个 ZonedDateTime
对象。比如,以下代码可以创建表示当前时间在东八区的 ZonedDateTime
:
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai")); |
另外,Java 还提供了一些方便的方法来进行时区转换。比如, LocalDateTime
可以使用 atZone()
方法将其转换为 ZonedDateTime
,然后使用 withZoneSameInstant()
方法将其转换为另一个时区的 ZonedDateTime
:
LocalDateTime localDateTime = LocalDateTime.now(); | |
ZonedDateTime shanghaiTime = localDateTime.atZone(ZoneId.of("Asia/Shanghai")); | |
ZonedDateTime newYorkTime = shanghaiTime.withZoneSameInstant(ZoneId.of("America/New_York")); |
类似的, Instant
可以使用 atZone()
方法将其转换为 ZonedDateTime
,然后使用 toInstant()
方法将其转换为 Instant
:
Instant instant = Instant.now(); | |
ZonedDateTime zonedDateTime = instant.atZone(ZoneId.of("Asia/Shanghai")); | |
Instant newYorkTime = zonedDateTime.toInstant(); |
最后,需要注意的是,在处理时区相关的操作时,一定要注意时间的格式化和解析。比如,在使用 SimpleDateFormat
进行时间格式化时,应该使用带时区的格式化器来避免时区转换时的问题。
# 日期格式化
在 Java 中,可以使用格式化来将日期对象格式化为字符串。Java 提供了两种格式化方式:
- 使用
java.text.SimpleDateFormat
类,该类可以根据指定的格式将日期格式化为字符串。
例如,下面的代码将 Date
对象格式化为字符串:
import java.text.SimpleDateFormat; | |
import java.util.Date; | |
public class DateFormatExample { | |
public static void main(String[] args) { | |
Date now = new Date(); | |
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |
String strDate = dateFormat.format(now); | |
System.out.println(strDate); | |
} | |
} |
输出结果:
2022-08-22 16:32:11 |
- 使用
java.time.format.DateTimeFormatter
类,该类是 Java 8 新引入的日期时间格式化类,使用方式类似于SimpleDateFormat
。
例如,下面的代码将 LocalDateTime
对象格式化为字符串:
import java.time.LocalDateTime; | |
import java.time.format.DateTimeFormatter; | |
public class DateTimeFormatterExample { | |
public static void main(String[] args) { | |
LocalDateTime now = LocalDateTime.now(); | |
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); | |
String strDate = now.format(formatter); | |
System.out.println(strDate); | |
} | |
} |
输出结果:
2022-08-22 16:32:11 |
需要注意的是,在使用 DateTimeFormatter
格式化 java.time
包中的日期时间类时,要使用对应的格式化模式,例如年份用大写的 yyyy
表示,月份用小写的 mm
表示等。
另外,如果需要将字符串转换为日期对象,可以使用 SimpleDateFormat
或 DateTimeFormatter
中的 parse
方法,例如:
String strDate = "2022-08-22 16:32:11"; | |
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |
Date date = dateFormat.parse(strDate); |
或者
String strDate = "2022-08-22 16:32:11"; | |
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); | |
LocalDateTime dateTime = LocalDateTime.parse(strDate, formatter); |
需要注意的是,在使用 SimpleDateFormat
解析日期字符串时,要使用与格式化模式相同的模式进行解析。而使用 DateTimeFormatter
时,可以根据需要指定格式化模式。
# 日期类的相互转化
在 Java 中,我们可以使用各种日期类进行日期的操作。这些日期类包括 java.util.Date
、 java.sql.Date
、 java.util.Calendar
、 java.time.LocalDate
、 java.time.LocalDateTime
、 java.time.Instant
等。为了进行不同日期类之间的相互转化,Java 提供了一些方法。
下面是一些常见的日期类之间的转化方法:
java.util.Date
和java.sql.Date
的转化将
java.util.Date
转换成java.sql.Date
:java.util.Date date = new java.util.Date();
java.sql.Date sqlDate = new java.sql.Date(date.getTime());
将
java.sql.Date
转换成java.util.Date
:java.sql.Date sqlDate = new java.sql.Date(System.currentTimeMillis());
java.util.Date date = new java.util.Date(sqlDate.getTime());
java.util.Date
和java.time.LocalDateTime
的转化将
java.util.Date
转换成java.time.LocalDateTime
:java.util.Date date = new java.util.Date();
Instant instant = date.toInstant();
LocalDateTime localDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
将
java.time.LocalDateTime
转换成java.util.Date
:LocalDateTime localDateTime = LocalDateTime.now();
Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
java.util.Date date = java.util.Date.from(instant);
java.util.Calendar
和java.time.LocalDateTime
的转化将
java.util.Calendar
转换成java.time.LocalDateTime
:Calendar calendar = Calendar.getInstance();
LocalDateTime localDateTime = LocalDateTime.ofInstant(calendar.toInstant(), calendar.getTimeZone().toZoneId());
将
java.time.LocalDateTime
转换成java.util.Calendar
:LocalDateTime localDateTime = LocalDateTime.now();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
java.util.Date
和java.time.Instant
的转化将
java.util.Date
转换成java.time.Instant
:java.util.Date date = new java.util.Date();
Instant instant = date.toInstant();
将
java.time.Instant
转换成java.util.Date
:Instant instant = Instant.now();
java.util.Date date = java.util.Date.from(instant);
java.util.Date
和java.time.LocalDate
的转化将
java.util.Date
转换成java.time.LocalDate
:java.util.Date date = new java.util.Date();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
将
java.time.LocalDate
转换成java.util.Date
:LocalDate localDate = LocalDate.now();
Instant instant = localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant();
java.util.Date date = java.util.Date.from(instant);