获取当前时刻 UTC 的ISO 8601格式表示的最优雅方式是什么?它应该看起来像:2010-10-12T08:50Z
。
例子:
String iso8601 = DateFormat.getDateTimeInstance(DateFormat.ISO_8601).format(date);
获取当前时刻 UTC 的ISO 8601格式表示的最优雅方式是什么?它应该看起来像:2010-10-12T08:50Z
。
例子:
String iso8601 = DateFormat.getDateTimeInstance(DateFormat.ISO_8601).format(date);
对于默认时区不是 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 更正)
java.time从 Java 8开始就变得简单了。而且线程安全。
ZonedDateTime.now( ZoneOffset.UTC ).format( DateTimeFormatter.ISO_INSTANT )
结果: 2015-04-14T11:07:36.639Z
您可能想使用
Temporal
诸如Instant
或 之类的轻量级工具LocalDateTime
,但它们缺乏格式化程序支持或时区数据。只能ZonedDateTime
开箱即用。
通过调整或链接ZonedDateTime和DateTimeFormatter的选项/操作,您可以在一定程度上轻松控制时区和精度:
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 端口。两者都比 Joda 轻,并且从 Joda 的经验中吸取了教训——尤其是。考虑到 java.time 是由 Joda 的作者设计的。
从 Java 8 开始,您可以简单地执行以下操作:
Instant.now().toString();
现在
public static Instant now()
从系统时钟获取当前时刻。
这将查询系统 UTC 时钟以获取当前时刻。
public String toString()
使用 ISO-8601 表示的此瞬间的字符串表示。
爪哇 8:
thisMoment = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mmX")
.withZone(ZoneOffset.UTC)
.format(Instant.now());
Java 8 之前:
thisMoment = String.format("%tFT%<tRZ",
Calendar.getInstance(TimeZone.getTimeZone("Z")));
从文档:
'R'
24 小时制的时间格式为“%tH:%tM”
'F'
ISO 8601 完整日期格式为“%tY-%tm-%td”。
使用JodaTime
ISO 8601 日历系统是 Joda-Time 中的默认实现
这是 JodaTime Formatter 的文档
编辑:
如果您不想添加或看不到添加上述库的价值,您可以在内置SimpleDateFormat
类中使用将日期格式化为所需的 ISO 格式
正如@Joachim Sauer 所建议的那样
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ");
String nowAsString = df.format(new Date());
来自 Apache 的DateFormatUtilscommons-lang3
有一些有用的常量,例如:DateFormatUtils.ISO_DATETIME_FORMAT
如果您不想包含 Jodatime(尽管它很好)
javax.xml.bind.DatatypeConverter.printDateTime(
Calendar.getInstance(TimeZone.getTimeZone("UTC"))
);
它返回一个字符串:
2012-07-10T16:02:48.440Z
这与原始请求略有不同,但仍然是 ISO-8601。
ISO 8601 可能包含秒见http://en.wikipedia.org/wiki/ISO_8601#Times
所以代码应该是
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
其他一些答案在推荐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
的发音是“祖鲁”和指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和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date
, Calendar
, & SimpleDateFormat
。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*
从哪里获得 java.time 类?
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。
更新:该乔达时间的项目现在处于维护模式,与团队的建议迁移java.time类。对于 Java 6 和 7,请参阅ThreeTen-Backport项目,在ThreeTenABP项目中进一步适用于 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 8 及更高版本,Joda-Time 继续工作。但是内置的java.time框架取代了 Joda-Time。因此,请尽快将您的代码从 Joda-Time 迁移到 java.time。
有关现代解决方案,请参阅我的其他答案。
该java.time框架是建立在Java 8和更高版本。这些类取代了麻烦的旧的遗留日期时间类,例如java.util.Date
, Calendar
, & SimpleDateFormat
。
现在处于维护模式的Joda-Time项目建议迁移到java.time类。
要了解更多信息,请参阅Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范是JSR 310。
您可以直接与您的数据库交换java.time对象。使用符合JDBC 4.2或更高版本的JDBC 驱动程序。不需要字符串,不需要类。java.sql.*
从哪里获得 java.time 类?
该ThreeTen-额外项目与其他类扩展java.time。该项目是未来可能添加到 java.time 的试验场。你可能在这里找到一些有用的类,比如Interval
,YearWeek
,YearQuarter
,和更多。
对于 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);
我确实相信最简单的方法是首先进入 Instant 然后像这样的字符串:
String d = new Date().toInstant().toString();
这将导致:
2017-09-08T12:56:45.331Z
您可以将 Java 的SimpleDateFormat与yyyy-MM-dd'T'HH:mm:ssXXX
ISO 8601的以下模式一起使用。
示例代码:(列出所有可用时区)
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 时区。更多在这里
您可能会注意到几个以 结尾的时区的日期时间'Z'
。这些时区'0'
与 GMT有偏差。
更多信息可以在这里找到。
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());
}
这是一个优化的整个类,因此调用“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());
}
}
尽管如此,joda-time 只支持扩展格式:“2015-12-09T00:22:42.930Z”而不是基本格式:“20151209T002242.930Z”……我们最好用 java SimpleDateFormat 测试格式列表。
我使用 Calendar 和 SimpleDateFormat 在 Android 中做到了。以下方法返回带有“GMT”时区(这是通用时区)的日历。然后,您可以使用 Calendar 类设置不同时区之间的小时,使用 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;
}
记住: Date 类不知道 TimeZone 的存在。因此,如果您调试一个日期,您总是会看到当前时区的日期。
DateTimeFormatter.ISO_DATE_TIME
.withZone(ZoneOffset.UTC)
.format(yourDateObject.toInstant())
如果您关心性能,我创建了一个库,它在处理 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"));
}
}
他们应该添加某种从 Date 到 Instant 的简单方法,以及一种称为 的方法toISO8601
,这是很多人正在寻找的。作为对其他答案的补充,从 java.util.Date 到 ISO 8601 格式:
Instant.ofEpochMilli(date.getTime()).toString();
使用自动完成功能时它并不真正可见,但是
java.time.Instant.toString()
::
使用 ISO-8601 的这一瞬间的字符串表示
尝试这个,
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ");
String date=sdf.format (new Date() );
其为 ISO 8601 格式
使用
SimpleDateFormat
格式化任何Date
你想要的对象:使用
new Date()
如上所示的a将格式化当前时间。