在Java中获取当前时间戳

52

我需要使用Java获取当前时间戳,并以MM/DD/YYYY h:mm:ss AM/PM的格式显示。

例如:06/01/2000 10:01:50 AM

我需要它是线程安全的。

我可以使用类似这样的东西吗?

java.util.Date date = new java.util.Date();
System.out.println(new Timestamp(date.getTime()));

或者在这个链接这里讨论的示例。


2
如果您在方法的范围内创建SimpleDateFormat,它将是线程安全的... - willcodejavaforfood
感谢您的输入并澄清了这一点。 - user717236
11个回答

73
SimpleDateFormat 的线程不安全问题只会在你将其作为静态方法或类实例变量并在多个方法中被多个线程调用时才会暴露出来。如果你只是在使用它的同一方法块内创建它,则不应该成为问题。因此,你可以在同一方法块内安全地重复使用相同的 SimpleDateFormat 实例,因为它仅会被当前线程访问。
同时,你正在使用的 java.sql.Timestamp 类应该避免滥用,因为它专门用于 JDBC API,以便能够在 SQL 数据库中存储或检索 TIMESTAMP/DATETIME 列类型并将其转换为/自 java.util.Date
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy h:mm:ss a");
String formattedDate = sdf.format(date);
System.out.println(formattedDate); // 12/01/2011 4:48:16 PM

1
谢谢你的帮助。这个方法有效,谢谢!我很感激你对SimpleDateFormat线程安全性的详细而简洁的解释。你认为Timestamp只用于SQL是正确的。这非常有道理。感谢你的智慧。 - user717236
1
只是想说你在第二行忘了加冒号。这是个非常小的错误,只是会让复制和粘贴稍微有些不便。 - deinocheirus
@user:这是一个分号。我已经修复了。 - BalusC

19
使用java.sql.Timestamp在Java中打印时间戳。
import java.sql.Timestamp;
import java.util.Date;
 
public class GetCurrentTimeStamp {
    public static void main( String[] args ){
        java.util.Date date= new java.util.Date();
        System.out.println(new Timestamp(date.getTime()));
    }
}

这将打印:

2014-08-07 17:34:16.664

使用SimpleDateFormat在一行代码中打印Java中的时间戳。
import java.util.Date;
import java.text.SimpleDateFormat;

class Runner{
    public static void main(String[] args){

        System.out.println(
            new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(new Date()));

    }

}

输出:

08/14/2014 14:10:38

Java日期格式图例:

G Era designation      Text               AD
y Year                 Year               1996; 96
M Month in year        Month              July; Jul; 07
w Week in year         Number             27
W Week in month        Number             2
D Day in year          Number             189
d Day in month         Number             10
F Day of week in month Number             2
E Day in week          Text               Tuesday; Tue
a Am/pm marker         Text               PM
H Hour in day (0-23)   Number             0
k Hour in day (1-24)   Number             24
K Hour in am/pm (0-11) Number             0
h Hour in am/pm (1-12) Number             12
m Minute in hour       Number             30
s Second in minute     Number             55
S Millisecond          Number             978
z Time zone            General time zone  Pacific Standard Time; PST; GMT-08:00
Z Time zone            RFC 822 time zone  -0800

9
尝试这个单行解决方案: ```

尝试这个单行解决方案:

```
import java.util.Date;
String timestamp = 
    new java.text.SimpleDateFormat("MM/dd/yyyy h:mm:ss a").format(new Date());

这个可行。对于现代语言来说,写超过一行来做这样的事情似乎是荒谬的。 - Andrew Cowenhoven
@AndrewCowenhoven 这不止一行。 :D - Andrew

8
< p > SimpleDateFormat 不是线程安全的,但这并不意味着你不能使用它。这只意味着你不能使用单个(潜在的,但不一定是static)实例,该实例被多个线程同时访问。

相反,确保为每个线程创建一个新的SimpleDateFormat即可。在方法内作为局部变量创建的实例根据定义是安全的,因为它们无法从任何并发线程中访问。

你可以考虑使用ThreadLocal类,但我建议在需要时仅创建一个新实例。当然,你可以将格式定义定义为static final String DATE_FORMAT_PATTERN = "...";,并在每个新实例中使用它。


我希望我也能给你一个勾号,因为你也值得拥有。你对这个主题的知识对我和其他阅读这个问题的人来说都是非常宝贵的。非常感谢你的时间和帮助。 - user717236

5

java.time

自Java 8+以来,您可以使用java.time包。具体而言,请使用DateTimeFormatterBuilderDateTimeFormatter格式化模式和文字。

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .appendPattern("MM").appendLiteral("/")
        .appendPattern("dd").appendLiteral("/")
        .appendPattern("yyyy").appendLiteral(" ")
        .appendPattern("hh").appendLiteral(":")
        .appendPattern("mm").appendLiteral(":")
        .appendPattern("ss").appendLiteral(" ")
        .appendPattern("a")
        .toFormatter();
System.out.println(LocalDateTime.now().format(formatter));

The output ...

06/22/2015 11:59:14 AM

或者,如果您需要不同的时区...

// system default
System.out.println(formatter.withZone(ZoneId.systemDefault()).format(Instant.now()));
// Chicago
System.out.println(formatter.withZone(ZoneId.of("America/Chicago")).format(Instant.now()));
// Kathmandu
System.out.println(formatter.withZone(ZoneId.of("Asia/Kathmandu")).format(Instant.now()));

The output ...

06/22/2015 12:38:42 PM
06/22/2015 02:08:42 AM
06/22/2015 12:53:42 PM

我们也可以使用 DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a") 来获取 DateTimeFormatter 的实例 :) - Arkantos
它比必要的更冗长。您可以只使用 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm:ss a");。或者,如果您想非常明确地表达文字是字面量:DateTimeFormatter.ofPattern("MM'/'dd'/'yyyy' 'hh':'mm':'ss' 'a")- 无论您使用哪个版本,我认为使用 java.time 是一个绝妙的主意。 - Ole V.V.

3

你可以使用 java.util.Date 和直接的日期字符串格式:

String timeStamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());

2

Joda-Time

这里是同样类型的代码,但使用了第三方库Joda-Time 2.3。

在现实生活中,我会指定一个时区,因为依赖默认时区通常是不好的做法。但这里为了简单起见省略了。

org.joda.time.DateTime now = new DateTime();
org.joda.time.format.DateTimeFormatter formatter = DateTimeFormat.forPattern( "MM/dd/yyyy h:mm:ss a" );
String nowAsString = formatter.print( now );

System.out.println( "nowAsString: " + nowAsString );

When run…

nowAsString: 11/28/2013 11:28:15 PM

2

当我想要一个时间戳时,我会像这样做

    String timeStamp = new SimpleDateFormat("yyyyMMddHHmmss").format(Calendar.getInstance().getTime());

希望能帮到您 :) 作为新手,我认为这很容易理解。
我认为您还需要导入java.text.SimpleDateFormat;头才能使其正常工作 :))

2

java.time

接受的答案使用了遗留的API(java.util Date-Time API和它们的格式化API,SimpleDateFormat),在回答时是正确的选择。然而,Java-8引入了现代的Date-Time API,取代了过时且容易出错的遗留日期时间API和它们的格式化API。自那时以来,强烈建议切换到现代API。
此外,下面引用了来自Joda-Time的首页的通知:

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

请注意,java.time类型是线程安全的。
使用现代的日期时间API java.time 来解决问题:使用所需的格式,使用DateTimeFormatter 格式化 LocalDateTime#now
LocalDateTime.now()
             .format(
                 DateTimeFormatter.ofPattern(
                     "MM/dd/uuuu hh:mm:ss a", Locale.ENGLISH));

注意:

  1. 在这里,你可以使用y代替u,但是我更喜欢u而不是y
  2. 始终使用Locale指定SimpleDateFormatDateTimeFormatter的自定义格式。请注意预定义格式化程序不接受Locale(即它们使用系统的Locale)。

演示:

public class Main {
    public static void main(String[] args) {
        // Get the current date-time in your system's time-zone
        // Note: if you want to get the current date-time in a specific time-zone,
        // use LocalDateTime.now(ZoneId)
        LocalDateTime now = LocalDateTime.now();
        // Default format
        System.out.println(now);

        // Custom format
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/uuuu hh:mm:ss a", Locale.ENGLISH);
        String dtInCustomFormat = now.format(formatter);
        System.out.println(dtInCustomFormat);
    }
}

一个示例运行的输出:

2023-11-13T20:54:51.573121
11/13/2023 08:54:51 PM

在线演示

教程:日期时间了解更多关于现代日期时间 API 的信息。


2
一如既往,回答很好。"永远不要使用DateTimeFormatter来自定义格式,也不要使用没有Locale的SimpleDateFormat"这句话的措辞似乎有些别扭。也许可以改成"在你的格式化器上始终指定一个Locale"。(a)积极的表达(始终与从不)似乎更简单。(b)我们不仅应该在自定义格式化器上指定Locale,而是在所有格式化器上都应该指定Locale吧?或者我理解错了你的意思。 - undefined
谢谢,@BasilBourque,感谢您宝贵的建议!我打算重新表达那个句子。关于自定义格式的Locale:我之所以提到自定义格式是因为预定义格式化程序不接受Locale(即它们使用系统的Locale)。 - undefined
是的,那是一个重要的观点!我建议你在你的回答中明确提到这一点。 - undefined

0
String.format("{0:dddd, MMMM d, yyyy hh:mm tt}", dt);

非常感谢您的帮助。不幸的是,这并没有起作用。我得到了“该方法Format(String,Date)未定义类型为String”的错误。它需要对象类型,而不是日期类型。 - user717236
3
尝试将String.format(...)中的"f"改为小写。Java中的方法名称通常以小写字母开头。 - Ogre Psalm33
2
非常感谢。我尝试了String str = String.format("{0:dddd, MMMM d, yyyy hh:mm tt}", new Date()); 然后str取得了{0:dddd, MMMM d, yyyy hh:mm tt}的值。也就是说,它没有起作用。 - user717236

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