如何获取当前日期和时间

371

如何在Java中获取当前日期和时间?

我正在寻找与C#中的DateTime.Now等效的方法。


1
这个问题比这个问题更早,曾被标记为重复。因此,我撤销了标记,重新打开了这个问题,并将较新的问题标记为重复。 - Basil Bourque
3
@BasilBourque,唯一的问题是最近的问题也有更好的答案,这意味着它更加更新。在2022年之后,这里建议的Date方法中的大多数已被弃用,因此在我看来它基本上是无用的。 - Arturo Mendes
任何偶然发现这个问题的人,请注意这一页上大多数答案已经过时,您不应该使用它们。这里唯一真正好的答案是@BasilBourque的答案,因此您可以阅读那个答案,或者访问Basil也回答了的重复问题 - Dawood ibn Kareem
2
@ArturoMendes 是的,你说得对。我后悔当时撤销重复标记的行为。当时我认为规则是较旧的问题应该优先考虑。自那以后,我在 Meta 页面上了解到,规则是问题的质量和答案的质量应该优先考虑,而不是年龄。 - Basil Bourque
10个回答

434

只需构建一个没有任何参数的新 Date 对象; 这将为新对象分配当前日期和时间。

import java.util.Date;

Date d = new Date();

根据Javadocs零参数构造函数的说法:

分配一个Date对象并初始化它,以表示它被分配的时间,精确到最近的毫秒。

请确保使用的是java.util.Date而不是java.sql.Date——后者没有零参数构造函数,并且具有不同的语义,这是完全不同的对话主题。:)


13
请注意,GregorianCalendar和许多类似的对象的工作方式是相同的。因此,无论您正在使用哪种类型的日期/日历对象,零参数构造函数通常会将对象初始化为当前日期/时间。 - Peter Di Cecco
从日期文档:自JDK 1.1起,应使用Calendar类在日期和时间字段之间进行转换,并使用DateFormat类格式化和解析日期字符串。 - Paolo M
12
请考虑使用新的Java8 API - LocalDateTime.now()和ZonedDateTime.now() - Oleg Mikheev

57

许多人认为Java的DateCalendar类设计不佳。建议您查看Joda Time,这是一个常用于替代Java内置日期库的库。

Joda Time中与DateTime.Now等效的方法是:

DateTime dt = new DateTime();

更新

如评论中所述,最新版本的Joda Time有一个DateTime.now()方法,因此:

DateTime dt = DateTime.now();

4
Joda目前(2.1版本)似乎有一个静态的DateTime.now方法(可选接受DateTimeZone或Chronology)。http://joda-time.sourceforge.net/apidocs/org/joda/time/DateTime.html#now%28%29 - Roman A. Taycher
2
请注意,此答案发布于2010年。Java 8已经吸收了Joda Time的许多最佳功能。有关更多信息,请参阅官方文档和许多其他在线文章。 - DavidS

54

简而言之

Instant.now()

java.time

Java 8及以上版本已经淘汰了java.util.Date类,新的java.time包 (Tutorial)取而代之。旧的java.util.Date/.Calendar类出了名的麻烦、令人困惑和有缺陷。请避免使用它们。

ZonedDateTime

获取当前时刻的java.time。

ZonedDateTime now = ZonedDateTime.now();

ZonedDateTime封装了以下内容:

  • 日期。
  • 时分秒,精确到纳秒
  • 时区。

如果未指定时区,则会默认使用JVM的当前时区。最好明确指定所需的时区,而不是隐式依赖于默认时区。

ZoneId z = ZoneId.of( "Pacific/Auckland" );
ZonedDateTime zdt = ZonedDateTime.now( z );

UTC

通常最好养成在UTC时区执行后端工作(业务逻辑、数据库、存储、数据交换)的习惯。上面的代码隐式地依赖于JVM当前默认时区。

Instant类表示时间线上的一个瞬间,其分辨率为纳秒,并以UTC为基准。

Instant instant = Instant.now();

Instant类是java.time中的基本构建块类,可能经常在您的代码中使用。

当您需要更灵活的格式化时,可以转换为OffsetDateTime。指定一个ZoneOffset对象。对于UTC,请使用方便的UTC常量

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC );

时区

您可以轻松地为用户调整到另一个时区进行展示。使用正确的时区名称绝不要使用3-4个字母的代码,如ESTIST

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime nowMontreal = instant.atZone( z );

生成本地化的日期时间值的字符串表示形式。
String output = DateTimeFormatter
    .ofLocalizedDate( FormatStyle.FULL )
    .withLocale( Locale.CANADA_FRENCH )
    .format ( nowMontreal );

Instant

或者,为了保持UTC时间,使用Instant。一个Instant对象表示时间线上的一个时刻,精确到纳秒,始终在UTC时间上。这为带有时区分配的区域日期时间提供了构建块。您可以将其概念化为:

ZonedDateTime = Instant + ZoneId

您可以从ZonedDateTime中提取Instant

Instant instantNow = zdt.toInstant();

您可以从即时开始。这里不需要指定时区,因为Instant始终处于UTC。
Instant now = Instant.now();

1
我还在一个重复的问题上发布了另一个答案,提供更多详细信息。 - Basil Bourque

16

5
可以简单地使用Calendar.getInstance() - draw

14

在Java 8中,它是这样的:

ZonedDateTime dateTime = ZonedDateTime.now();

12
import java.util.Date;   
Date now = new Date();

请注意,Date对象是可变的,如果您想做任何复杂的操作,请使用Joda-Time


10

java.lang.System.currentTimeMillis();将返回自时代以来的日期时间。


适用于日志记录,但需要解析和转换才能显示给用户。 - Rishi Dua

6
import org.joda.time.DateTime;

DateTime now = DateTime.now();

5

如果您创建一个新的日期对象,默认情况下它将被设置为当前时间:

import java.util.Date;
Date now = new Date();

3

Java一直缺乏对日期和时间用例的充分支持。例如,现有的类(如java.util.DateSimpleDateFormatter)不是线程安全的,这可能会导致并发问题。此外,API 中存在某些缺陷。例如,在java.util.Date中,年份从1900年开始,月份从1开始,天数从0开始——不太直观。这些问题导致第三方日期和时间库(例如Joda-Time)变得流行。为了解决这些问题,为Java SE 8设计了一个新的日期和时间API。

LocalDateTime timePoint = LocalDateTime.now();
System.out.println(timePoint);

根据文档now()方法使用系统时钟和默认时区返回当前日期时间,不为null。它从默认时区的系统时钟获取当前日期时间。这将在默认时区中查询系统时钟以获取当前日期时间。使用此方法将防止使用备用时钟进行测试,因为时钟是硬编码的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接