如何在Java中获取当前时刻的年、月、日、小时、分钟、秒和毫秒?

112

如何在Java中获取当前时间的年份、月份、日期、小时、分钟、秒和毫秒?我希望它们是 Strings

10个回答

275
你可以使用java.time.LocalDateTime的getter方法来实现。
LocalDateTime now = LocalDateTime.now();
int year = now.getYear();
int month = now.getMonthValue();
int day = now.getDayOfMonth();
int hour = now.getHour();
int minute = now.getMinute();
int second = now.getSecond();
int millis = now.get(ChronoField.MILLI_OF_SECOND); // Note: no direct getter available.

System.out.printf("%d-%02d-%02d %02d:%02d:%02d.%03d", year, month, day, hour, minute, second, millis);

或者,如果您尚未使用Java 8,则可以利用java.util.Calendar

Calendar now = Calendar.getInstance();
int year = now.get(Calendar.YEAR);
int month = now.get(Calendar.MONTH) + 1; // Note: zero based!
int day = now.get(Calendar.DAY_OF_MONTH);
int hour = now.get(Calendar.HOUR_OF_DAY);
int minute = now.get(Calendar.MINUTE);
int second = now.get(Calendar.SECOND);
int millis = now.get(Calendar.MILLISECOND);

System.out.printf("%d-%02d-%02d %02d:%02d:%02d.%03d", year, month, day, hour, minute, second, millis);

无论哪种方式,目前打印的结果如下:

2010-04-16 15:15:17.816

要将int转换为String,可以使用String#valueOf()


如果你的意图是将它们按照人类友好的字符串格式排列和显示,那么最好使用Java8的java.time.format.DateTimeFormatter参见此处教程)。

LocalDateTime now = LocalDateTime.now();
String format1 = now.format(DateTimeFormatter.ISO_DATE_TIME);
String format2 = now.atZone(ZoneId.of("GMT")).format(DateTimeFormatter.RFC_1123_DATE_TIME);
String format3 = now.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss", Locale.ENGLISH));

System.out.println(format1);
System.out.println(format2);
System.out.println(format3);

如果你还没有升级到Java 8,可以使用java.text.SimpleDateFormat

Date now = new Date(); // java.util.Date, NOT java.sql.Date or java.sql.Timestamp!
String format1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH).format(now);
String format2 = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH).format(now);
String format3 = new SimpleDateFormat("yyyyMMddHHmmss", Locale.ENGLISH).format(now);

System.out.println(format1);
System.out.println(format2);
System.out.println(format3);

无论哪种方式,都会得到以下结果:
2010年4月16日15:15:17.816
星期五,2010年4月16日15:15:17格林威治标准时间
20100416151517

另请参阅:


如果你要使用printf,那么最好直接使用日期/时间格式,而不是使用中间步骤,即"%1$tm %1$te,%1$tY",c(请参阅java.util.Formatter获取完整的语法)。 - M. Jessup
1
@M. Jessup:确实很好。但我从未使用过它,所以我无法脱口而出,上面的只是为了演示目的。不管怎样,我更愿意使用SimpleDateFormatDateTimeFormatter来完成特定任务 :) - BalusC
1
许多java.time功能在ThreeTen-Backport项目中被回溯到Java 6和7。 - Basil Bourque
作为一个细节,我建议您将 ZoneId 传递给 LocalDateTime.now()。这样,您就明确表示操作是时区相关的,并告诉读者您已经有意识地选择了时区。例如 ZoneId.of("America/Argentina/Salta")ZoneId.systemDefault() - Ole V.V.
我搜索了几个小时毫秒级别的获取器,但这个答案立即清楚地表明没有这样的获取器。 - Valentino Miori
显示剩余4条评论

31

切换到joda-time后,您只需要三行代码就可以实现这个功能。

DateTime jodaTime = new DateTime();

DateTimeFormatter formatter = DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss.SSS");
System.out.println("jodaTime = " + formatter.print(jodaTime));

您还可以直接访问日期的各个字段而无需使用日历。

System.out.println("year = " + jodaTime.getYear());
System.out.println("month = " + jodaTime.getMonthOfYear());
System.out.println("day = " + jodaTime.getDayOfMonth());
System.out.println("hour = " + jodaTime.getHourOfDay());
System.out.println("minute = " + jodaTime.getMinuteOfHour());
System.out.println("second = " + jodaTime.getSecondOfMinute());
System.out.println("millis = " + jodaTime.getMillisOfSecond());

输出结果如下:

jodaTime = 2010-04-16 18:09:26.060

year = 2010
month = 4
day = 16
hour = 18
minute = 9
second = 26
millis = 60

根据http://www.joda.org/joda-time/

Joda-Time是Java的事实标准日期和时间库。 从Java SE 8开始,要求用户迁移到java.time (JSR-310)。


2
Joda-Time 项目现已进入维护阶段,其团队建议迁移到 java.time 类。Joda-Time 和 java.time 都由同一人 Stephen Colebourne 领导。 - Basil Bourque

12
    // Java 8
    System.out.println(LocalDateTime.now().getYear());       // 2015
    System.out.println(LocalDateTime.now().getMonth());      // SEPTEMBER
    System.out.println(LocalDateTime.now().getDayOfMonth()); // 29
    System.out.println(LocalDateTime.now().getHour());       // 7
    System.out.println(LocalDateTime.now().getMinute());     // 36
    System.out.println(LocalDateTime.now().getSecond());     // 51
    System.out.println(LocalDateTime.now().get(ChronoField.MILLI_OF_SECOND)); // 100

    // Calendar
    System.out.println(Calendar.getInstance().get(Calendar.YEAR));         // 2015
    System.out.println(Calendar.getInstance().get(Calendar.MONTH ) + 1);   // 9
    System.out.println(Calendar.getInstance().get(Calendar.DAY_OF_MONTH)); // 29
    System.out.println(Calendar.getInstance().get(Calendar.HOUR_OF_DAY));  // 7
    System.out.println(Calendar.getInstance().get(Calendar.MINUTE));       // 35
    System.out.println(Calendar.getInstance().get(Calendar.SECOND));       // 32
    System.out.println(Calendar.getInstance().get(Calendar.MILLISECOND));  // 481

    // Joda Time
    System.out.println(new DateTime().getYear());           // 2015
    System.out.println(new DateTime().getMonthOfYear());    // 9
    System.out.println(new DateTime().getDayOfMonth());     // 29
    System.out.println(new DateTime().getHourOfDay());      // 7
    System.out.println(new DateTime().getMinuteOfHour());   // 19
    System.out.println(new DateTime().getSecondOfMinute()); // 16
    System.out.println(new DateTime().getMillisOfSecond()); // 174

    // Formatted
    // 2015-09-28 17:50:25.756
    System.out.println(new Timestamp(System.currentTimeMillis()));

    // 2015-09-28T17:50:25.772
    System.out.println(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.ENGLISH).format(new Date()));

    // Java 8
    // 2015-09-28T17:50:25.810
    System.out.println(LocalDateTime.now());

    // joda time
    // 2015-09-28 17:50:25.839
    System.out.println(DateTimeFormat.forPattern("YYYY-MM-dd HH:mm:ss.SSS").print(new org.joda.time.DateTime()));

6

使用Java 8及更高版本,可以使用java.time包

ZonedDateTime.now().getYear();
ZonedDateTime.now().getMonthValue();
ZonedDateTime.now().getDayOfMonth();
ZonedDateTime.now().getHour();
ZonedDateTime.now().getMinute();
ZonedDateTime.now().getSecond();

ZonedDateTime.now()是一个静态方法,可以返回默认时区下系统时钟的当前日期和时间。所有获取方法都返回int类型的值。


LocalDateTime 对于此任务来说是完全错误的类。由于缺乏任何时区或UTC偏移量的概念,它不能用于跟踪特定时刻,它不是时间轴上的一个点。请改用 InstantZonedDateTimeOffsetDateTime - Basil Bourque
你说得对。我已经修改了我的答案,使用了ZonedDateTime - Ortomala Lokni

6

简而言之

ZonedDateTime.now(                    // Capture current moment as seen in the wall-clock time used by the people of a particular region (a time zone).
    ZoneId.of( "America/Montreal" )   // Specify desired/expected time zone. Or pass `ZoneId.systemDefault` for the JVM’s current default time zone.
)                                     // Returns a `ZonedDateTime` object.
.getMinute()                          // Extract the minute of the hour of the time-of-day from the `ZonedDateTime` object.

42

ZonedDateTime

使用ZonedDateTime来捕获特定区域(时区)人们使用的挂钟时间所看到的当前时刻。

时区对于确定日期至关重要。对于任何给定的时刻,日期因时区而异。例如,在法国巴黎午夜过后几分钟就是新的一天,但在加拿大魁北克省蒙特利尔仍然是“昨天”。

如果未指定时区,则JVM会隐式地应用其当前默认时区。该默认值可能在运行时任意更改,因此结果可能会有所不同。最好将所需/期望的时区明确地指定为参数。

请指定一个正确的时区名称, 格式为continent/region, 例如 America/Montreal, Africa/Casablanca, 或者 Pacific/Auckland。不要使用三四个字母的缩写,如ESTIST,因为它们不是真正的时区,没有标准化,并且甚至不唯一(!)。

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;

调用任何一个getter来提取日期时间的任何部分。
int    year        = zdt.getYear() ;
int    monthNumber = zdt.getMonthValue() ;
String monthName   = zdt.getMonth().getDisplayName( TextStyle.FULL , Locale.JAPAN ) ;  // Locale determines human language and cultural norms used in localizing. Note that `Locale` has *nothing* to do with time zone.
int    dayOfMonth  = zdt.getDayOfMonth() ;
String dayOfWeek   = zdt.getDayOfWeek().getDisplayName( TextStyle.FULL , Locale.CANADA_FRENCH ) ; 
int    hour        = zdt.getHour() ;  // Extract the hour from the time-of-day.
int    minute      = zdt.getMinute() ;
int    second      = zdt.getSecond() ;
int    nano        = zdt.getNano() ;
< p > java.time 类解析为 纳秒。您的问题要求以 毫秒 为单位表示一秒钟的分数。显然,您可以通过除以一百万来将纳秒截断为毫秒,但可能会造成数据丢失。或者使用 TimeUnit 枚举进行转换。

long millis = TimeUnit.NANOSECONDS.toMillis( zdt.getNano() ) ;

DateTimeFormatter

要生成一个将文本片段组合在一起的String,请使用DateTimeFormatter类。在Stack Overflow上搜索更多信息。

Instant

通常最好跟踪UTC中的时刻。要从分区日期时间调整为UTC,请提取Instant

Instant instant = zdt.toInstant() ;

再返回。

ZonedDateTime zdt = instant.atZone( ZoneId.of( "Africa/Tunis" ) ) ;

LocalDateTime

有些其他的答案使用了LocalDateTime类。该类不适用于跟踪实际时刻,特定时间线上的时刻,因为它故意缺乏任何时区或偏移量的概念。

那么LocalDateTime适用于什么?当您打算将日期和时间应用于任何地方所有地方而不是一个特定的地方时,请使用LocalDateTime

例如,今年的圣诞节从 LocalDateTime.parse( "2018-12-25T00:00:00" ) 开始。这个值没有意义,直到你应用一个时区(ZoneId)来获取一个 ZonedDateTime。圣诞节先在基里巴斯发生,然后在新西兰和远东亚洲发生。几个小时后,圣诞节在印度开始。更多小时后,在非洲和欧洲开始。而在美洲,几个小时后才开始庆祝圣诞节。任何一个地方开始的圣诞节都应该用 ZonedDateTime 来表示。而全球范围内的圣诞节则应该用 LocalDateTime 来表示。

关于 java.time

java.time 框架是内置于 Java 8 及更高版本中的。这些类取代了老旧且麻烦的传统日期时间类,例如 java.util.Date, Calendar, 和 SimpleDateFormat

Joda-Time项目现在处于维护模式,建议迁移到java.time类。

了解更多信息,请参见Oracle教程。并在Stack Overflow上搜索许多示例和说明。规范是JSR 310

您可以直接与数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC驱动程序。无需字符串,无需java.sql.*类。

如何获取java.time类?


2

或者使用java.sql.Timestamp。Calendar有点重,我建议不要在生产代码中使用它。Joda更好一些。

import java.sql.Timestamp;

public class DateTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println(new Timestamp(System.currentTimeMillis()));
    }
}

1
我认为你误解了问题和 sql 时间戳的用法。在这里,通常会使用 new Date()。但是,如何轻松地获取所请求的各个部分呢? - BalusC
1
FYI,随着JDBC 4.2的到来,java.sql.Timestamp已被java.time.Instant取代。 - Basil Bourque

1

在Java 7中,日历只需一行代码。

new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS").format(Calendar.getInstance().getTime())

2
令人烦恼的Calendar和SimpleDateFormat类现已过时,完全被java.time类所取代。请参见BalusC的答案以了解现代方法。 java.time的许多功能在ThreeTen-Backport项目中向Java 6和7进行了后移植。 - Basil Bourque

0
使用格式化模式“dd-MM-yyyy HH:mm:ss aa”获取日期,例如21-10-2020 20:53:42 pm

-2
请查看java.util.Calendar类及其派生类的API文档(您可能特别感兴趣的是GregorianCalendar类)。

请注意,像java.util.Datejava.util.Calendarjava.text.SimpleDateFormat这样的老旧日期时间类现在已经成为遗留系统,被内置于Java 8及更高版本中的java.time类所取代。请参阅Oracle的教程 - Basil Bourque

-2

现在 = 新日历() // 或者新公历(GregorianCalendar),或任何你需要的版本

now.MONTH now.HOUR

等等。


4
你好,我很难理解为什么你要以低劣的方式重复已经给出的答案。请详细阐述一下 :) - BalusC
4
MONTHHOURCalendar 类的静态常量,而不是实例属性。 - Joseph Earl

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