如何获得ISO 8601格式的当前时刻,包括日期,小时和分钟?

时间:2010-10-12 12:00:44

标签: java

获得ISO 8601格式化当前时刻UTC的最优雅方式是什么?它看起来应该是:2010-10-12T08:50Z

示例:

String iso8601 = DateFormat.getDateTimeInstance(DateFormat.ISO_8601).format(date);

22 个答案:

答案 0 :(得分:267)

使用SimpleDateFormat格式化您想要的任何Date对象:

TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"); // Quoted "Z" to indicate UTC, no timezone offset
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());

如上所示使用new Date()将格式化当前时间。

答案 1 :(得分:215)

对于默认时区不是UTC的系统:

TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());

如果频繁需要,可以将SimpleDateFormat实例声明为全局常量,但请注意此类不是线程安全的。如果多个线程同时访问它必须同步。

编辑:如果做很多不同的时间/日期操作,我更喜欢Joda Time ... EDIT2:更正:setTimeZone不接受字符串(由Paul更正)

答案 2 :(得分:134)

Java 8 Native

java.time使Java 8变得简单。并且线程安全。

ZonedDateTime.now( ZoneOffset.UTC ).format( DateTimeFormatter.ISO_INSTANT )

结果:2015-04-14T11:07:36.639Z

  

您可能会想要使用TemporalInstant等轻量级LocalDateTime,   但他们缺乏格式化程序支持或时区数据。   只有ZonedDateTime开箱即用。

通过调整或链接ZonedDateTimeDateTimeFormatter的选项/操作,您可以在一定程度上轻松控制timezoneprecision

ZonedDateTime.now( ZoneId.of( "Europe/Paris" ) )
             .truncatedTo( ChronoUnit.MINUTES )
             .format( DateTimeFormatter.ISO_DATE_TIME )

结果:2015-04-14T11:07:00+01:00[Europe/Paris]

精选要求(例如删除秒部分)仍必须由自定义格式或自定义后期处理提供。

.format( DateTimeFormatter.ISO_LOCAL_DATE_TIME ) // 2015-04-14T11:07:00
.format( DateTimeFormatter.ISO_LOCAL_DATE ) // 2015-04-14
.format( DateTimeFormatter.ISO_LOCAL_TIME ) // 11:07:00
.format( DateTimeFormatter.ofPattern( "yyyy-MM-dd HH:mm" ) ) // 2015-04-14 11:07
  

对于Java 6& 7,您可以考虑java.time的后端端口,例如ThreeTen-Backport,它也有Android port。   两者都比Joda轻,并且从Joda的experience中学到了 - 尤其是。考虑到java.time是由Joda的作者设计的。

答案 3 :(得分:122)

Java 8:

thisMoment = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mmX")
                              .withZone(ZoneOffset.UTC)
                              .format(Instant.now());

Pre Java 8:

thisMoment = String.format("%tFT%<tRZ",
                           Calendar.getInstance(TimeZone.getTimeZone("Z")));

来自the docs

  

'R'将24小时制格式化为“%tH:%tM”的时间   'F' ISO 8601完整日期格式为“%tY-%tm-%td”。

答案 4 :(得分:53)

从Java 8开始,您只需执行以下操作:

Instant.now().toString();

来自java.time.Instant文档:

  now            

public static Instant now()

     

从系统时钟获得当前瞬间。

     

这将查询system UTC clock以获取当前时刻。

  toString            

public String toString()

     

使用ISO-8601表示的此瞬间的字符串表示。

     

使用的格式与DateTimeFormatter.ISO_INSTANT相同。

答案 5 :(得分:25)

使用JodaTime

  

ISO 8601日历系统是Joda-Time

中的默认实现

Here是JodaTime Formatter的文档

编辑:

如果您不想添加或者如果您没有看到添加上述库的价值,您可以在构建的SimpleDateFormat类中使用将日期格式化为所需的ISO格式

由@Joachim Sauer建议

DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ");
String nowAsString = df.format(new Date());

答案 6 :(得分:20)

来自Apache commons-lang3

DateFormatUtils具有有用的常量,例如:DateFormatUtils.ISO_DATETIME_FORMAT

答案 7 :(得分:18)

如果你不想包括Jodatime(尽可能好)

javax.xml.bind.DatatypeConverter.printDateTime(
    Calendar.getInstance(TimeZone.getTimeZone("UTC"))
);

返回一个字符串:

2012-07-10T16:02:48.440Z

与原始请求略有不同,但仍然是ISO-8601。

答案 8 :(得分:16)

ISO 8601可能包含秒数 见http://en.wikipedia.org/wiki/ISO_8601#Times

所以代码应该是

DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");

答案 9 :(得分:9)

约达时间

更新: Joda-Time项目现在位于maintenance mode,团队建议迁移到java.time课程。对于Java 6&amp; 7,参见ThreeTen-Backport项目,在ThreeTenABP项目中进一步适用于Android。

使用Joda-Time库...

String output = new DateTime( DateTimeZone.UTC ).toString() ;

这是线程安全的。 Joda-Time创建新的immutable objects而不是更改现有对象。

如果您真的想要一个没有秒的格式,解析为几分钟,那么请使用Joda-Time中的许多其他内置格式化程序之一。

DateTime now = new DateTime( DateTimeZone.UTC ) ;
String output = ISODateTimeFormat.dateHourMinute.print( now ) ;

java.time

对于Java 8及更高版本,Joda-Time继续工作。但是内置的java.time框架取代了Joda-Time。因此,只要方便,就可以将代码从Joda-Time迁移到java.time。

请参阅my other Answer了解现代解决方案。


关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和&amp; SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

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

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 10 :(得分:7)

对于Java版本7

您可以关注Oracle文档: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

X - 用于ISO 8601时区

TimeZone tz = TimeZone.getTimeZone("UTC");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
df.setTimeZone(tz);
String nowAsISO = df.format(new Date());

System.out.println(nowAsISO);

DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
//nowAsISO = "2013-05-31T00:00:00Z";
Date finalResult = df1.parse(nowAsISO);

System.out.println(finalResult);

答案 11 :(得分:5)

对于ISO 8601,您可以使用带有以下格式 yyyy-MM-dd'T'HH:mm:ssXXX 的Java SimpleDateFormat

  

示例代码:(列出所有可用时区)

for (String timeZone : TimeZone.getAvailableIDs())
{
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
    dateFormat.setTimeZone(TimeZone.getTimeZone(timeZone));
    String formatted = dateFormat.format(new Date());
    System.out.print(formatted);

    if (formatted.endsWith("Z"))
    {
        // These time zone's have offset of '0' from GMT.
        System.out.print("\t(" + timeZone + ")");
    }

    System.out.println();
}

您可以使用:

  

TimeZone.getDefault()

表示默认的vm时区。更多here

您可能会注意到以'Z'结尾的几个时区的日期时间。这些时区与GMT的偏差为'0'

可以找到更多信息here

答案 12 :(得分:5)

我相信最简单的方法是首先进入即时,然后再串起来:

String d = new Date().toInstant().toString();

这将导致:

2017-09-08T12:56:45.331Z

答案 13 :(得分:3)

TL;博士

其他一些答案在推荐 java.time 类时是正确的,但是根据您的特定需求使用不必要的长度。

Instant.now()                               // Capture the current moment in UTC with a resolution as fines nanoseconds but usually in microseconds or milliseconds.
       .truncatedTo( ChronoUnit.MINUTES )   // Lop off any seconds or fractional second, to get a value in whole minutes.
       .toString()                          // Generate a String in standard ISO 8601 format where a `T` separates the year-month-day from the hour-minute-second, and the `Z` on the end for “Zulu” means UTC.
  

2018-01-23T12:34Z

Instant::toString

jav.time.Instant类表示UTC时刻,始终为UTC。

Instant instant = Instant.now() ;
  

instant.toString():2018-01-23T12:34:56.123456Z

示例字符串Z末尾的2010-10-12T08:50Z发音为“Zulu”,表示UTC

您所需的格式符合ISO 8601标准。在解析/生成字符串时, java.time 类默认使用这些标准格式。因此无需指定格式化模式。如上所示,只需致电Instant::toString

如果你特别想要没有秒或小数秒的整个分钟,那么就截断。通过ChronoUnit类指定一个时间单位。

Instant instant = Instant.now().truncatedTo( ChronoUnit.MINUTES ) ;
String output = instant.toString();  // Generate a `String` object in standard ISO 8601 format.

关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和&amp; SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

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

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 14 :(得分:2)

这是一个优化的整个类,因此调用“now()”不会做任何更多的事情。

public class Iso8601Util
{
    private static TimeZone tz = TimeZone.getTimeZone("UTC");
    private static DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'");

    static
    {
        df.setTimeZone(tz);
    }

    public static String now()
    {
        return df.format(new Date());
    }
}

答案 15 :(得分:2)

private static String getCurrentDateIso()
{
    // Returns the current date with the same format as Javascript's new Date().toJSON(), ISO 8601
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
    dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    return dateFormat.format(new Date());
}

答案 16 :(得分:1)

如果您关心性能,那么我创建的library在处理ISO8601格式的日期方面要优于标准Java解析器和格式化程序。 DatetimeProcessor实现是线程安全的,可以缓存在并发映射或静态字段中。

<dependency>
  <groupId>com.axibase</groupId>
  <artifactId>date-processor</artifactId>
  <version>1.0.3</version>
</dependency>
import com.axibase.date.DatetimeProcessor;
import com.axibase.date.PatternResolver;
import org.junit.Before;
import org.junit.Test;

import java.time.Clock;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZoneOffset;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;

public class DateFormatTest {
    private Clock clock;

    @Before
    public void prepare() {
        clock = Clock.fixed(Instant.ofEpochMilli(1571285405300L), ZoneId.of("Europe/Berlin"));
    }

    @Test
    public void testIsoMillis(){
        final DatetimeProcessor formatter = PatternResolver.createNewFormatter("iso");
        assertThat(formatter.print(clock.millis(), ZoneOffset.UTC), is("2019-10-17T04:10:05.300Z"));
    }

    @Test
    public void testIsoMillisLocalZone(){
        final DatetimeProcessor formatter = PatternResolver.createNewFormatter("iso");
        assertThat(formatter.print(clock.millis(), clock.getZone()), is("2019-10-17T06:10:05.300+02:00"));
    }

    @Test
    public void testIsoMinutes(){
        final DatetimeProcessor formatter = PatternResolver.createNewFormatter("yyyy-MM-ddTHH:mmXXX");
        assertThat(formatter.print(clock.millis(), ZoneOffset.UTC), is("2019-10-17T04:10Z"));
    }
}

答案 17 :(得分:1)

我使用Calendar和SimpleDateFormat在Android中完成了它。以下方法返回带有&#34; GMT&#34;的日历。 TimeZone(这是通用时区)。然后,您可以使用Calendar类来设置不同时区之间的小时,使用Calendar类的setTimeZone()方法。

>>> ''.join([chr(e) for e in my_string_numpy_array])
'My name is Aman Raparia'

记住: Date类不了解TimeZone的存在。因此,如果您调试一个日期,则始终会看到当前时区的日期。

答案 18 :(得分:1)

尽管如此,joda-time仅支持扩展格式: &#34; 2015-12-09T00:22:42.930Z&#34; 不是基本的: &#34; 20151209T002242.930Z&#34; ...我们可能最好用java SimpleDateFormat测试格式列表。

答案 19 :(得分:0)

他们应该添加一些简单的方法从Date到Instant以及一个名为toISO8601的方法,这是很多人都在寻找的方法。 作为其他答案的补充,从java.util.Date到ISO 8601格式:

Instant.ofEpochMilli(date.getTime()).toString();

使用自动完成时不会显示,但是: java.time.Instant.toString()

  

使用ISO-8601

的此瞬间的字符串表示

答案 20 :(得分:0)

DateTimeFormatter.ISO_DATE_TIME
        .withZone(ZoneOffset.UTC)
        .format(yourDateObject.toInstant())

答案 21 :(得分:-2)

试试这个,

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ");
        String date=sdf.format (new Date() );

适用于ISO 8601格式