2010-10-12T08:50Z
。示例:
String iso8601 = DateFormat.getDateTimeInstance(DateFormat.ISO_8601).format(date);
#1 楼
使用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()
将格式化当前时间。评论
@Joachim这种“标准”方法的缺点是,每次我需要ISO-8601格式的日期时,我的应用程序中都必须有许多“ yyyy-MM-dd'T'HH:mmZ”实例。如我所见,借助JodaTime,我可以使用预定义的格式化程序ISODateTimeFormat,它可以为我完成此工作。
–yegor256
2010-10-12 12:18
@ Joachim,Z是SimpleDateFormat中的有效模式,请执行以下操作:yyyy-MM-dd'T'HH:mm'Z'。
– Buhake Sindi
10-10-12在12:43
-1这将为您提供当前时区中的日期/时间,而不是UTC。卡洛斯的答案包括必要的UTC代码。
–斯科特·里皮(Scott Rippey)
2012年3月30日16:15
我只是解决了时区错误-因为这是公认的答案,所以我认为这是正确的做法。
– BoD
13年8月16日在22:22
Z的引用必须像“ yyyy-MM-dd'T'HH:mm'Z'”
–Kimball Robinson
15年10月13日在22:26
#2 楼
对于默认时区不是UTC的系统:如果经常需要,可以将SimpleDateFormat
实例声明为全局常量,但请注意,此类不是线程-安全。如果由多个线程同时访问,则必须同步。 编辑:如果要进行许多不同的“时间/日期”操作,我希望使用乔达时间...
编辑2:已更正:
setTimeZone
不接受字符串(由保罗更正)评论
在某些内置库中,这种格式不是恒定的吗?
–丹尼尔·卡普兰(Daniel Kaplan)
2014年6月10日22:44
“ DateFormat”有两个不同的包,请记住使用“ import java.text.DateFormat”
–oabarca
2014年6月24日19:12
如果要当前时区,请使用TimeZone tz = TimeZone.getDefault();。代替
–oabarca
2014年6月24日19:15
您不应该在格式中引用“ Z”,因为这在逻辑上不重要。如果如上例中的TimeZone为UTC,则未加引号的Z将仅在输出中导致Z ...但是,如果TimeZone不是UTC,则当时间可能不为Z时,Z仍将输出为字面值表示UTC是。如果使用方系统将Z读取为UTC,但时间不是,则时间将转移。相反,如果解析器使用带引号的Z而不设置TimeZone,它将解析UTC时间为本地时间(再次移位)。如果设置了TZ,则不需要此引号,但如果未设置,则很危险。
–马特·惠普尔
16年6月13日在18:50
@MattWhipple-但是,如果使用不带引号的Z,则结果将类似于2016-06-14T13:56 + 0000-问题是询问诸如2016-06-14T13:56Z
–user85421
16年6月14日14:00
#3 楼
Java 8 Nativejava.time自Java 8起变得简单,而且线程安全。
br />
您可能会喜欢使用较轻的
2015-04-14T11:07:36.639Z
,例如Temporal
或Instant
,,但是它们缺乏格式器支持或时区数据。
只有
LocalDateTime
可以直接使用。 > 通过调整或链接ZonedDateTime和DateTimeFormatter的选项/操作,可以在一定程度上轻松地控制时区和精度:
ZonedDateTime.now( ZoneOffset.UTC ).format( DateTimeFormatter.ISO_INSTANT )
结果:
ZonedDateTime
仍必须通过自定义格式或自定义后期处理来满足已删除的要求,例如删除秒部分。 br />
对于Java 6和7,您可以考虑java.time的反向端口,例如ThreeTen-Backport,它也具有Android端口。乔达的经历-特别是。考虑到java.time是由Joda的作者设计的。
评论
好答案。请注意,明确指定时区而不是隐式依赖JVM当前的默认时区是一个好习惯。如果需要,可以指定一个特定的时区,例如ZoneId.of(“ America / Montreal”)。
–罗勒·布尔克
16-2-17在21:51
Instant只需调用.toString()方法即可将其格式化为ISO 8601格式:return DateTimeFormatter.ISO_INSTANT.format(this);
–VadymVL
17年7月7日14:39
这是最好的,因为您避免使用默认值。
–克里斯托弗·鲁西(Christophe Roussy)
18年4月3日在12:18
警告:使用ISO_INSTANT的Java 8解决方案有一个令人讨厌的怪癖。当毫秒恰好为0时,它们不包含在输出中。根据ISO 8601标准,这是允许的,但是许多其他语言的库和解析器并不那么宽容。如果有必要始终包含零,请改用它:DateTimeFormatter ISO_8601 = ofPattern(“ yyyy-MM-dd'T'HH:mm:ss.SSSX”)。withZone(UTC);
–于尔根
18年7月24日在20:57
从Java 8切换到11之后,我看到DateTimeFormatter.ISO_INSTANT和DateTimeFormatter.ISO_DATE_TIME在秒后使用6位数字,而不是3,Spring的@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)不再使用3位数字。
–DanielM
20-1-23在11:29
#4 楼
Java 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”。评论
好吧,要么您包括一个额外的第三方库作为您项目的依赖项(您可能希望保持最新状态,并随您的应用程序一起交付,嘿,它只是一个额外的3.2 MB),然后执行DateTime dt = new DateTime (); DateTimeFormatter fmt = ISODateTimeFormat.dateTime();字符串str = fmt.print(dt);,或者您封装返回String.format(“%tFT%
–aioobe
10-10-12在12:36
%tFT%
–帕特里克·林斯基(Patrick Linskey)
2012年8月5日,下午1:21
一个非常简洁的解决方案,应该是现在已经被接受的答案:)
–阿卜杜勒·哈迪(AbdelHady)
14年8月21日在16:28
@PatrickLinskey有一个有用的注释,用于将秒和毫秒添加到输出中,但是毫秒模式的错误很小。 Z应该在毫秒后出现,例如%tFT%
– sho222
2014年10月3日20:55
DateTimeFormatter具有常数ISO_DATE_TIME以获取ISO-8601日期格式器,而不是自己显式编写模式。
–nickb
17年1月2日在20:45
#5 楼
从Java 8开始,您只需执行以下操作即可:Instant.now().toString();
从
java.time.Instant
文档: /> public static Instant now()
从系统时钟获取当前时刻。
这将查询系统UTC时钟以获取当前时刻。
toString
public String toString()
使用ISO-表示此瞬时的字符串8601表示形式。
使用的格式与
DateTimeFormatter.ISO_INSTANT
相同。评论
这是正确的答案,而且在所有这些炮制的SimpleDateFormats上,它都没有得到更高的评价,这是一个丑闻。
– David Moles
18年5月7日在15:27
很高兴我阅读了更多答案。我同意,这应该是现在的答案。
– Xan-Kun Clark-Davis
20年1月27日在16:01
而且因为它是toString,所以在很多情况下,您甚至不需要显式调用它。
–kaya3
20-2-25在22:49
警告:在前面的答案中,警告也适用于此:“警告:使用ISO_INSTANT的Java 8解决方案有一个令人讨厌的怪癖。当毫秒为0时,它们不包含在输出中。根据ISO 8601,这是允许的标准,但许多其他语言的库和解析器并不那么宽容。”
–戴夫L。
20-2-26在20:09
#6 楼
使用JodaTimeISO 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());
评论
您将如何生成问题所示格式的String?
–约阿希姆·绍尔(Joachim Sauer)
10-10-12在12:12
我想说的是,不要为这样简单的事情添加库依赖(可以通过两行Java代码来实现)。 (当然,如果需求增加,那就另当别论了。)
– aioobe
2010-10-12 12:14
@aioobe,如果它只是在应用程序的多个部分中使用,则可以默认使用,在其他情况下,jodatime更好。
– jmj
10-10-12在12:15
@aioobe jodatime在任何情况下都更好,因为它具有ISODateTimeFormat-ISO-8601的预定义格式化程序。
–yegor256
10-10-12在12:19
@ org.life.java:仅当您可以正确切换到Jode时间时才有意义。仅使用Joda time的此功能时,您将没有它们。
– Joachim Sauer
2010-10-12 13:29
#7 楼
Apachecommons-lang3
的DateFormatUtils具有有用的常量,例如:DateFormatUtils.ISO_DATETIME_FORMAT
评论
更准确地说,当前时间是UTC:DateFormatUtils.format(new Date(),“ yyyy-MM-dd'T'HH:mm'Z'”,TimeZone.getTimeZone(“ UTC”)));默认时区中的当前时刻:DateFormatUtils.ISO_DATETIME_TIME_ZONE_FORMAT.format(new Date()); @ yegor256感谢您提到DateFormatUtils,在apache commons-lang上有必要使用日期格式。
– babinik
2013年9月18日13:40
#8 楼
如果您不想包括Jodatime(非常好)javax.xml.bind.DatatypeConverter.printDateTime(
Calendar.getInstance(TimeZone.getTimeZone("UTC"))
);
它返回以下字符串: />
,它与原始请求略有不同,但仍为ISO-8601。
#9 楼
ISO 8601可能包含秒数请参见http://en.wikipedia.org/wiki/ISO_8601#Times
,因此代码应为
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
#10 楼
Joda-Time更新:Joda-Time项目现在处于维护模式,团队建议迁移到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.time
对于Java 8和更高版本,Joda-Time继续工作。但是内置的java.time框架取代了Joda-Time。因此,您可以方便地将代码从Joda-Time迁移到java.time。
关于现代解决方案,请参见我的其他答案。 time
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧的旧式日期时间类,例如
java.util.Date
,Calendar
和SimpleDateFormat
。 /> 要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规范是JSR310。
您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要
java.sql.*
类。从哪里获取java.time类?
Java SE 8,Java SE 9,Java SE 10及更高版本
内置。
具有捆绑实现的标准Java API的一部分。
Java 9增加了一些次要功能和修复。
Java SE 6和Java SE 7
java.time的许多功能在ThreeTen-Backport中都反向移植到Java 6和7。 Android
较新版本的java.time类的Android捆绑实现。
对于较早的Android(<26),ThreeTenABP项目改编了ThreeTen-Backport(如上所述)。请参见如何使用ThreeTenABP…。
ThreeTen-Extra项目使用其他类扩展了java.time。该项目是将来可能向java.time添加内容的试验场。您可能会在这里找到一些有用的类,例如
Interval
,YearWeek
,YearQuarter
等。#11 楼
对于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);
#12 楼
tl; dr其他一些答案在推荐java.time类时是正确的,但是为了满足您的特定需求而使用不必要的长度。
/>
2018-01-23T12:34Z
Instant::toString
jav.time.Instant
类表示UTC中的时刻,始终表示UTC。 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.
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() ;
关于java.time
java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧的旧式日期时间类,例如
java.util.Date
,Calendar
和SimpleDateFormat
。 /> 要了解更多信息,请参见Oracle教程。并在Stack Overflow中搜索许多示例和说明。规范是JSR310。
您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC驱动程序。不需要字符串,不需要
java.sql.*
类。从哪里获取java.time类?
Java SE 8,Java SE 9,Java SE 10及更高版本
内置。
具有捆绑实现的标准Java API的一部分。
Java 9增加了一些次要功能和修复。
Java SE 6和Java SE 7
很多Java.time功能在ThreeTen-Backport中都已反向移植到Java 6和7。较新版本的java.time类的Android捆绑实现。
对于较早的Android(<26),ThreeTenABP项目改编了ThreeTen-Backport(如上所述)。请参见如何使用ThreeTenABP…。
ThreeTen-Extra项目使用其他类扩展了java.time。该项目是将来可能向java.time添加内容的试验场。您可能会在这里找到一些有用的类,例如
Interval
,YearWeek
,YearQuarter
等。#13 楼
您可以将Java的SimpleDateFormat与ISO 8601的以下模式yyyy-MM-dd'T'HH:mm:ssXXX
一起使用。示例代码:(列出所有可用时区)
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'
。更多信息可在此处找到。
#14 楼
我确实认为最简单的方法是先进入即时模式,然后再输入类似字符串:br />
评论
如果您需要当前时间,则无需遍历老式的Date对象。只需执行Instant.now()。toString()。如果您是从旧版API获取日期,则您的方法是最好的方法。
– Ole V.V.
17年11月15日在11:45
作为Ole V.V.注释说,麻烦的旧日期时间类(例如java.util.Date,java.util.Calendar和java.text.SimpleDateFormat)现在已成为旧版,由Java 8和更高版本中内置的java.time类取代。请参见Oracle教程。
–罗勒·布尔克
18年4月10日在20:29
#15 楼
这是一个经过优化的整个类,因此,调用“ now()”不会做它必须做的其他事情。评论
将其设置为静态可能会引起麻烦,因为SimpleDateFormat并非线程安全的:“日期格式不同步。建议为每个线程创建单独的格式实例。如果多个线程同时访问一种格式,则必须在外部进行同步。” docs.oracle.com/javase/7/docs/api/java/text / ...
– JuhaPalomäki
13年2月7日在21:10
正如@JuhaPalomäki所说,这不是线程安全的。如果您使用的是Java 8或更高版本,则ThreadLocal.withInitial可以解决此问题。如果您使用的是Java 7或更低版本,请创建一个新的ThreadLocal并通过覆盖ThreadLocal.initialValue提供一个初始值
–马特·斯加拉塔(Matt Sgarlata)
2014-10-16 15:43
@ user393274-如果您使用的是Java 8,则应使用Instant,DateTimeFormat和其他现代线程安全替代品
–user177800
17年9月5日在18:08
我对SimpleDateFormat的问题是不是线程安全的感到困惑。如果两个线程同时执行静态初始化程序,那么我看不到发生什么比SimpleDateFormat构造函数被调用两次,但只有其中一个瞬间(最后一个完成)记录为“ df”的情况更糟了。
– gilbertpilz
18年2月7日在3:09
#16 楼
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());
}
#17 楼
如果您关心性能,则可以创建一个在处理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"));
}
}
#18 楼
尽管如此,joda-time仅支持扩展格式:“ 2015-12-09T00:22:42.930Z”
不支持基本格式:
“ 20151209T002242.930Z”
。 ..我们最好用java SimpleDateFormat测试格式列表。
#19 楼
我在Android中使用Calendar和SimpleDateFormat做到了。以下方法返回带有“ 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的存在。因此,如果调试一个日期,则始终会看到当前时区的日期。
#20 楼
他们应该添加从日期到即时的某种简单方法,以及一种称为toISO8601
的方法,这是很多人正在寻找的方法。符合ISO 8601格式的日期:Instant.ofEpochMilli(date.getTime()).toString();
使用自动完成功能时,它不是真正可见的,但:
java.time.Instant.toString()
: br />使用ISO-8601的此瞬间的字符串表示形式#21 楼
DateTimeFormatter.ISO_DATE_TIME
.withZone(ZoneOffset.UTC)
.format(yourDateObject.toInstant())
评论
尽管此代码可以回答问题,但提供有关此代码为何和/或如何回答问题的其他上下文,可以提高其长期价值。
– Vishal Chhodwani
18年4月27日在5:13
#22 楼
试试这个,SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ");
String date=sdf.format (new Date() );
用于ISO 8601格式
评论
这将使用错误时区中的日期,请参见Carlos的答案。
– Stian Soiland-Reyes
13年3月25日在15:31
评论
svn.apache.org/repos/asf/commons/dormant/feedparser/trunk/src / ...@marcolopes当心,使用私有静态SimpleDateFormat并不是线程安全的。
将符合ISO 8601的字符串转换为java.util.Date的可能重复项
与此其他问题类似,但一个问题将截短至整秒,而该问题将截断至整分钟。