获得ISO 8601格式化当前时刻UTC的最优雅方式是什么?它看起来应该是:2010-10-12T08:50Z
。
示例:
String iso8601 = DateFormat.getDateTimeInstance(DateFormat.ISO_8601).format(date);
答案 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
实例声明为全局常量,但请注意此类不是线程安全的。如果多个线程同时访问它必须同步。
setTimeZone
不接受字符串(由Paul更正)
答案 2 :(得分:134)
java.time使Java 8变得简单。并且线程安全。
ZonedDateTime.now( ZoneOffset.UTC ).format( DateTimeFormatter.ISO_INSTANT )
结果:2015-04-14T11:07:36.639Z
您可能会想要使用
Temporal
或Instant
等轻量级LocalDateTime
, 但他们缺乏格式化程序支持或时区数据。 只有ZonedDateTime
开箱即用。
通过调整或链接ZonedDateTime和DateTimeFormatter的选项/操作,您可以在一定程度上轻松控制timezone和precision:
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)
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 8及更高版本,Joda-Time继续工作。但是内置的java.time框架取代了Joda-Time。因此,只要方便,就可以将代码从Joda-Time迁移到java.time。
请参阅my other Answer了解现代解决方案。
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和&amp; SimpleDateFormat
现在位于Joda-Time的maintenance 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的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 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)
其他一些答案在推荐 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 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.Date
,Calendar
和&amp; SimpleDateFormat
现在位于Joda-Time的maintenance 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的试验场。您可以在此处找到一些有用的课程,例如Interval
,YearWeek
,YearQuarter
和more。
答案 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格式