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

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

例子:

String d = DateFormat.getDateTimeInstance(DateFormat.ISO_8601).format(date);
482333 次浏览

使用JodaTime

ISO 8601日历系统是Joda-Time中的默认实现

在这里是JodaTime Formatter的文档

编辑:

如果你不想添加或如果你不认为添加上面的库有价值,你可以使用内置SimpleDateFormat类将Date格式化为所需的ISO格式

正如@Joachim Sauer所建议的

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

使用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()将格式化当前时间。

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")));

的文档:

< p > 'R' ,,24小时时钟的时间格式为“%tH:%tM”
'F' ,,ISO 8601完整的日期格式为“%tY-%tm-%td”

对于默认时区不是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时间 EDIT2: corrected: setTimeZone不接受字符串(由Paul更正)

试试这个,

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

它的ISO 8601格式

如果您不想包含Jodatime(尽管它很好)

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

返回一个字符串:

2012-07-10T16:02:48.440Z

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

这里优化了整个类,以便调用“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());
}
}

来自Apache commons-lang3DateFormatUtils有一些有用的常量,例如

ISO 8601可能包含秒 看到http://en.wikipedia.org/wiki/ISO_8601#Times < / p >

所以代码应该是

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

适用于Java版本7

你可以参考Oracle文档: http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html < / p >

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);

Joda-Time

更新: Joda-Time项目现在在维护模式中,团队建议迁移到java.time类。Java 6 &7、参见< em > ThreeTen-Backport < / em >项目,在< em > ThreeTenABP < / em >项目中进一步适应Android。

使用Joda-Time库…

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

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

如果您真的想要一种没有秒的格式,解析为分钟,那么使用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。时间越方便越好。

参见我的另一个回答获取现代解决方案。


关于java.time

< em > java.time < / em >框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗产日期-时间类,如java.util.DateCalendar, &SimpleDateFormat

现在在维护模式中的< em > Joda-Time < / em >项目建议迁移到java.time类。

要了解更多信息,请参见< < em >甲骨文教程/ em >。搜索Stack Overflow可以找到很多例子和解释。规格是JSR 310

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

从哪里获取java。时间类?

Java 8原生

自Java 8以来,java.time使它变得简单。线程安全。

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

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

你可能会被诱惑使用较轻的Temporal,如InstantLocalDateTime, 但它们缺乏格式化程序支持或时区数据。 只有ZonedDateTime是开箱即用的

通过调优或链接ZonedDateTimeDateTimeFormatter的选项/操作,你可以在一定程度上轻松控制时区精度:

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

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

细化的要求,如删除秒部分,仍然必须通过自定义格式或自定义post流程提供服务。

.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的后端口。时间,例如ThreeTen-Backport,它也有Android的港口. time。 两者都比Joda轻,并从Joda的经验中学习-特别是考虑到java。

.时间由Joda的作者设计

从Java 8开始,你可以简单地做:

Instant.now().toString();

来自java.time.Instant文档:

now

public static Instant now()

从系统时钟中获取当前时刻。

这将查询系统UTC时钟以获得当前时刻。

,

toString

public String toString()

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

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

对于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 ()

虚拟机默认时区。更多在这里

你可能会注意到一些时区的日期时间以'Z'结尾。这些时区与GMT有'0'的偏移。

更多信息可以找到在这里

不过,joda-time只支持扩展格式: “2015 - 12 - 09 - t00:22:42.930z” 不是最基本的: “20151209 t002242.930z” ...我们最好使用java SimpleDateFormat测试一个格式列表

我在Android中使用Calendar和SimpleDateFormat。下面的方法返回一个带有“GMT”时区的日历(这是通用时区)。然后,您可以使用Calendar类的setTimeZone()方法在不同的时区之间设置小时。

private static final String GMT = "GMT";
private static final String DATE_FORMAT_ISO = "yyyyMMdd'T'HHmmss";


public static Calendar isoToCalendar(final String inputDate) {
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone(GMT));
try {
SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_ISO, Locale.US);
dateFormat.setTimeZone(TimeZone.getTimeZone(GMT));
Date date = dateFormat.parse(inputDate);
calendar.setTime(date);
} catch (ParseException e) {
Log.e("TAG",e.getMessage());
}
return calendar;
}
< p >记住: Date类不知道TimeZone的存在。因此,如果你调试一个日期,你总是会看到当前时区的日期

我相信最简单的方法是先去instant,然后去字符串,比如:

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

这将导致:

2017-09-08T12:56:45.331Z

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());
}
他们应该添加一些简单的方法来从日期到即时,还有一个叫做toISO8601的方法,这是很多人都在寻找的。 作为对其他答案的补充,从java.util.Date到ISO 8601格式:

Instant.ofEpochMilli(date.getTime()).toString();
当使用自动补全时,它是不可见的,但是: java.time.Instant.toString(): < / p >

使用ISO-8601表示该时刻的字符串

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

博士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 - 23 t12:34z

Instant::toString

jav.time.Instant类表示UTC时间,总是UTC时间。

Instant instant = Instant.now() ;

instant.toString (): 2018 - 01 - 23 t12:34:56.123456z

你的例子字符串2010-10-12T08:50Z结尾的Z发音为“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

< em > java.time < / em >框架内置于Java 8及更高版本中。这些类取代了麻烦的旧遗产日期-时间类,如java.util.DateCalendar, &SimpleDateFormat

现在在维护模式中的< em > Joda-Time < / em >项目建议迁移到java.time类。

要了解更多信息,请参见< < em >甲骨文教程/ em >。搜索Stack Overflow可以找到很多例子和解释。规格是JSR 310

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

从哪里获取java。时间类?

如果你关心性能,我创建了一个图书馆,它在处理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"));
}
}


对于那些使用Joda的时间的人,这里有一个一行程序,格式为yyyy-MM-dd' t ' hh:mm:ss' z '

DateTime(timeInMillis, DateTimeZone.UTC).toString(ISODateTimeFormat.dateTimeNoMillis())