如何在Java中以YYYY-MM-DD HH:MI:Sec.Millisecond格式获取当前时间?

806

下面的代码可以获取当前时间,但没有提供毫秒级的信息。

public static String getCurrentTimeStamp() {
    SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//dd/MM/yyyy
    Date now = new Date();
    String strDate = sdfDate.format(now);
    return strDate;
}

我有一个日期,格式为YYYY-MM-DD HH:MM:SS2009-09-22 16:47:08)。

但是我想以YYYY-MM-DD HH:MM:SS.MS的格式检索出当前时间(例如:2009-09-22 16:47:08.128,其中128表示毫秒)。

SimpleTextFormat将有效,它的最低时间单位是秒,但是如何获取毫秒?


37
当其他方法都失败时,阅读文档 - Hot Licks
6
FYI,像java.util.Datejava.util.Calendarjava.text.SimpleTextFormat这样的麻烦的旧日期时间类现在已经过时了,被java.time类替换。请参阅Oracle的教程 - Basil Bourque
16个回答

1216
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

1
出于好奇,使用SimpleDateFormat相比仅使用dateTime.ToString("yyyy-MM-dd HH:mm:ss.SSS")有什么好处? - NickG
10
@NickG 这个 toString(String format) 方法在哪里?java.util.Date 似乎没有这个方法。你是在指 Joda Time API 吗?但其中一个可能的好处是重用相同的格式化对象,另一个好处是不必添加 API - Date 类是标准的 Java 库类。 - ADTC
25
在Java 8中,您可以使用DateTimeFormatter实现相同的目的。 - Vitalii Fedorenko
7
SimpleDateFormat不是线程安全的,但较新的DateTimeFormatter是线程安全的。 - devdanke
34
使用Java 8的日期时间API:LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")) - rsinha
显示剩余3条评论

253

一个Java单行代码

public String getCurrentTimeStamp() {
    return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format(new Date());
}

JDK8风格

public String getCurrentLocalDateTimeStamp() {
    return LocalDateTime.now()
       .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
}

13
LocalDateTime和DateTimeFormatter是线程安全的,不像SimpleDateFormat。 - Maxple
@Maxple SimpleDateFormat 会引起问题的情况有吗? - Gaurav
3
@gaurav 这是你的饼干:https://www.callicoder.com/java-simpledateformat-thread-safety-issues/ 该文章讨论了Java中SimpleDateFormat类的线程安全问题。在多线程环境下,如果不小心使用SimpleDateFormat实例,可能会导致日期格式化错误和程序崩溃。文中提供了几种解决方案来避免这些问题,并建议开发人员在编写多线程代码时要格外小心。 - kidnan1991
但是这两个例子都是线程安全的,或者我漏掉了什么? - Johannes Stadler
是的,这些示例是线程安全的。每次都会创建一个新的SimpleDateFormat。 - Joram

119

您只需在日期格式字符串中添加毫秒字段:

new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

SimpleDateFormat的API文档详细描述了格式字符串。


49

试试这个:

http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html

DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
Date date = new Date();
System.out.println(dateFormat.format(date));
或者
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Calendar cal = Calendar.getInstance();
System.out.println(dateFormat.format(cal.getTime()));

45

简短概述

Instant.now()
       .toString()

2016-05-06T23:24:25.694Z

ZonedDateTime
.now
( 
    ZoneId.of( "America/Montreal" ) 
)
.format(  DateTimeFormatter.ISO_LOCAL_DATE_TIME )
.replace( "T" , " " )

2016年5月6日19点24分25.694秒

java.time

在Java 8及以后的版本中,我们有内置于Java 8及以后版本的java.time框架。这些新类取代了麻烦的旧的java.util.Date/.Calendar类。新类受到高度成功的Joda-Time框架的启发,旨在成为其继承者,概念类似但重新架构。由JSR 310定义。由ThreeTen-Extra项目扩展。请参阅Tutorial
请注意java.time可以实现纳秒分辨率(秒的小数部分有9位数字),而java.util.Date和Joda-Time只能实现毫秒分辨率(3位数字)。因此,在格式化显示时仅显示3个小数位,您可能会隐藏数据。
如果要消除任何微秒或纳秒的数据,请截断。
Instant instant2 = instant.truncatedTo( ChronoUnit.MILLIS ) ;

Java.time类在解析/生成字符串时默认使用ISO 8601格式。结尾处的Z代表Zulu,表示UTCInstant表示UTC时间线上的一个瞬间,分辨率高达纳秒。在Java 8中捕获当前时刻仅限于毫秒,而Java 9中有一个新实现,可以根据计算机硬件时钟的能力捕获高达纳秒的时间。捕获当前时刻
Instant instant = Instant.now (); // Current date-time in UTC.
String output = instant.toString ();

2016-05-06T23:24:25.694Z

将中间的 T 替换为一个空格,将 Z 替换为空,即可得到所需的输出。
String output = instant.toString ().replace ( "T" , " " ).replace( "Z" , "" ; // Replace 'T', delete 'Z'. I recommend leaving the `Z` or any other such [offset-from-UTC][7] or [time zone][7] indicator to make the meaning clear, but your choice of course.

2016年05月06日23时24分25.694秒

如果您不关心包含偏移量或时区,请创建一个与任何特定地点无关的“本地”日期时间。

String output = LocalDateTime.now ( ).toString ().replace ( "T", " " );

Joda-Time

广受欢迎的Joda-Time库是java.time框架的灵感来源。建议在方便时迁移到java.time。

ISO 8601格式包括毫秒,并且是Joda-Time 2.4库的默认格式。

System.out.println( "Now: " + new DateTime ( DateTimeZone.UTC ) );

当运行时...

Now: 2013-11-26T20:25:12.014Z

此外,如果需要,您可以请求毫秒级别的小数部分作为数字:
int millisOfSecond = myDateTime.getMillisOfSecond ();

13

我会使用类似这样的东西:

String.format("%tF %<tT.%<tL", dateTime);

变量dateTime可以是任何日期和/或时间值,请参见Formatter的JavaDoc


是的,但你必须使用同一参数的多个副本,就像这样:String.format("%tF %<tT.%<tL", dateTime, dateTime, dateTime); - Mic
2
不,你不需要。字符“<”表示使用前一个参数而不是下一个参数... - Usagi Miyamoto

12

最简单的方法是在Java 8之前使用,

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

但是 SimpleDateFormat 不是线程安全的,而且 java.util.Date 也不是。这将导致潜在的并发问题,给用户带来麻烦。这些现有设计中存在很多问题。为了克服这些问题,Java 8 现在有一个单独的包叫做 java.time。这份 Java SE 8 Date and Time 文档对它进行了很好的概述。

因此,在 Java 8 中,像下面这样做即可(格式化当前日期/时间):

LocalDateTime.now()
   .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));

需要注意的是,它是在流行的第三方库joda-time的帮助下开发的。

  

该项目由Joda-Time的作者(Stephen Colebourne)和Oracle共同领导,在JSR 310下完成,并将出现在新的Java SE 8包java.time中。

但是现在,joda-time即将被弃用,并要求用户迁移到新的java.time

  

请注意,从Java SE 8开始,要求用户迁移到java.time(JSR-310)- JDK的核心部分,取代了这个项目。

无论如何,话虽如此,

如果您有一个Calendar实例,可以使用以下代码将其转换为新的java.time

    Calendar calendar = Calendar.getInstance();
    long longValue = calendar.getTimeInMillis();         

    LocalDateTime date =
            LocalDateTime.ofInstant(Instant.ofEpochMilli(longValue), ZoneId.systemDefault());
    String formattedString = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));

    System.out.println(date.toString()); // 2018-03-06T15:56:53.634
    System.out.println(formattedString); // 2018-03-06 15:56:53.634

如果您有一个Date对象,

    Date date = new Date();
    long longValue2 = date.getTime();

    LocalDateTime dateTime =
            LocalDateTime.ofInstant(Instant.ofEpochMilli(longValue2), ZoneId.systemDefault());
    String formattedString = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));

    System.out.println(dateTime.toString()); // 2018-03-06T15:59:30.278
    System.out.println(formattedString);     // 2018-03-06 15:59:30.278

如果您只有时间戳(以毫秒为单位),

LocalDateTime date =
        LocalDateTime.ofInstant(Instant.ofEpochMilli(epochLongValue), ZoneId.systemDefault());

最低API级别为26。 - AbhinayMe

9

我这里有一个简单的示例,可以显示毫秒级的日期和时间......

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class MyClass{

    public static void main(String[]args){
        LocalDateTime myObj = LocalDateTime.now();
        DateTimeFormatter myFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
        String forDate = myObj.format(myFormat);
        System.out.println("The Date and Time are: " + forDate);
    }
}

看起来不错,但它是否比 rsinha的五年前的评论 提供更深入的见解? - greybeard

4

为了补充前面的答案,这里提供一个小的工作示例,演示如何打印当前时间和日期(包括毫秒)的程序。

import java.text.SimpleDateFormat;
import java.util.Date;

public class test {
    public static void main(String argv[]){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        Date now = new Date();
        String strDate = sdf.format(now);
        System.out.println(strDate);
    }
}


3
使用此代码获取指定格式的当前时间
 DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 System.out.print(dateFormat.format(System.currentTimeMillis()));  }

请注意,像java.util.Datejava.util.Calendarjava.text.SimpleDateFormat这样的旧日期时间类现在已经成为遗留系统,被内置于Java 8及更高版本中的java.time类所取代。请参阅Oracle的教程 - Basil Bourque
实际上,我之前在 Android 应用中使用了这个解决方案,但是要在 Android 中使用 Java.time 类,我们需要将 API 设置至少为 27。无论如何,感谢您分享这些信息。 - Abhishek Sengupta
几乎所有的 java.time 功能都被移植到了 ThreeTen-Backport 项目中,以几乎相同的 API 的形式支持 Java 6 和 7。同时在 ThreeTenABP 项目中进行了改进以适用于 Android <26。因此,再也没有理由接触那些可怕的旧日期时间类了。 - Basil Bourque

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