从尊重时区的日历对象中获取格式化字符串的最简单方法是什么?
What is the easiest way to get a formatted string from a calendar object which respects timezone?
当我在网上搜索 "how to convert a Calendar
to a String
" 时,我找到的所有结果都建议先转换为 Date
,然后再将 Date
转换为 String
。
问题是 Date
仅表示自纪元以来的毫秒数 - 它不考虑时区。 Calendar
这种方式更高级。
当然,我可以调用单独的 Calendar.get
方法来创建我自己的格式化字符串,但一定有更简单的方法吗?
为了说明,我写了这段代码:
long currentTime = Calendar.getInstance().getTimeInMillis();
Calendar calendar = new GregorianCalendar();
calendar.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
calendar.setTimeInMillis(currentTime);
System.out.println(calendar.getTime().toString());
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime()));
System.out.println(calendar.get(Calendar.HOUR_OF_DAY));
虽然 运行 此代码来自位于伦敦 (UTC+0) 8:02pm 的机器,但我得到了以下结果:
Wed Nov 18 20:02:26 UTC 2015
2015-11-18 20:02:26
21
最后一行显示根据日历时区(马德里,UTC+1)的实际时间。它在马德里是 9:02pm,但显然本地 Date.toString
和 DateFormat.format
方法都忽略了时区,因为调用 Calendar.getTime
时时区信息被删除(类似 Calendar.getTimeInMillis
).
鉴于此,从符合时区的 Calendar
获取格式化字符串的最佳方法是什么?
在 SimpleDateFormat 对象上设置时区,然后使用 z
..
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
sdf.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
System.out.println(sdf.format(calendar.getTime());
有关如何在 Java 中处理时区的详细信息,请参阅 here。
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
Calendar cal = Calendar.getInstance();
System.out.println(simpleDateFormat.format(cal.getTime()));
java.time
虽然其他答案似乎是正确的,但更好的方法是完全避免使用 java.util.Date/.Calendar。
那些旧的日期时间 类 已被 java.time framework built into Java 8 and later. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Tutorial 取代。
Instant
一个 Instant
表示 UTC 时间轴上的一个时刻。
Instant instant = Instant.now ( ); // Current moment in UTC.
对于在 Java 中添加的给定 Calendar
object, convert to an Instant
using the method toInstant
8.
Instant instant = myCalendar.toInstant();
ZonedDateTime
您可以将时区 (ZoneId
) 分配给 Instant
以获得 ZonedDateTime
。
ZoneId zoneId = ZoneId.of ( "Europe/Madrid" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant, zoneId );
日期时间值的字符串表示
转储到控制台。
System.out.println ( "instant: " + instant + " adjusted into zone: " + zoneId + " is zdt: " + zdt );
java.time 类 使用 ISO 8601 standard formatting by default when parsing/generating String representations of date-time values. By default the ISO 8601 style is extended by appending the name of the time zone in addition to the usual offset-from-UTC.
instant: 2015-11-18T22:23:46.764Z adjusted into zone: Europe/Madrid is zdt: 2015-11-18T23:23:46.764+01:00[Europe/Madrid]
如果您想要 ISO 8601 样式但没有 T
,请对生成的字符串对象调用 .replace( "T" , "" )
或 define your own formatter.
java.time.format package can do the work of determining a localized format appropriate to a particular Locale
.
Locale locale = Locale.forLanguageTag ( "es-ES" );
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.FULL );
String output = zdt.format ( formatter.withLocale ( locale ) );
miércoles 18 de noviembre de 2015 23H38' CET
您可以使用 String.format() 来避免时区问题
http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html
此示例给出了以下格式的结果:"yyyy-MM-dd HH:mm:ss"
Calendar c = Calendar.getInstance();
String s = String.format("%1$tY-%1$tm-%1$td:%1$tM:%1$tS", c);
System.out.println(s);
输出:
2015-11-20:44:55
当我在网上搜索 "how to convert a Calendar
to a String
" 时,我找到的所有结果都建议先转换为 Date
,然后再将 Date
转换为 String
。
问题是 Date
仅表示自纪元以来的毫秒数 - 它不考虑时区。 Calendar
这种方式更高级。
当然,我可以调用单独的 Calendar.get
方法来创建我自己的格式化字符串,但一定有更简单的方法吗?
为了说明,我写了这段代码:
long currentTime = Calendar.getInstance().getTimeInMillis();
Calendar calendar = new GregorianCalendar();
calendar.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
calendar.setTimeInMillis(currentTime);
System.out.println(calendar.getTime().toString());
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime()));
System.out.println(calendar.get(Calendar.HOUR_OF_DAY));
虽然 运行 此代码来自位于伦敦 (UTC+0) 8:02pm 的机器,但我得到了以下结果:
Wed Nov 18 20:02:26 UTC 2015
2015-11-18 20:02:26
21
最后一行显示根据日历时区(马德里,UTC+1)的实际时间。它在马德里是 9:02pm,但显然本地 Date.toString
和 DateFormat.format
方法都忽略了时区,因为调用 Calendar.getTime
时时区信息被删除(类似 Calendar.getTimeInMillis
).
鉴于此,从符合时区的 Calendar
获取格式化字符串的最佳方法是什么?
在 SimpleDateFormat 对象上设置时区,然后使用 z
..
sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
sdf.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
System.out.println(sdf.format(calendar.getTime());
有关如何在 Java 中处理时区的详细信息,请参阅 here。
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
Calendar cal = Calendar.getInstance();
System.out.println(simpleDateFormat.format(cal.getTime()));
java.time
虽然其他答案似乎是正确的,但更好的方法是完全避免使用 java.util.Date/.Calendar。
那些旧的日期时间 类 已被 java.time framework built into Java 8 and later. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Tutorial 取代。
Instant
一个 Instant
表示 UTC 时间轴上的一个时刻。
Instant instant = Instant.now ( ); // Current moment in UTC.
对于在 Java 中添加的给定 Calendar
object, convert to an Instant
using the method toInstant
8.
Instant instant = myCalendar.toInstant();
ZonedDateTime
您可以将时区 (ZoneId
) 分配给 Instant
以获得 ZonedDateTime
。
ZoneId zoneId = ZoneId.of ( "Europe/Madrid" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant, zoneId );
日期时间值的字符串表示
转储到控制台。
System.out.println ( "instant: " + instant + " adjusted into zone: " + zoneId + " is zdt: " + zdt );
java.time 类 使用 ISO 8601 standard formatting by default when parsing/generating String representations of date-time values. By default the ISO 8601 style is extended by appending the name of the time zone in addition to the usual offset-from-UTC.
instant: 2015-11-18T22:23:46.764Z adjusted into zone: Europe/Madrid is zdt: 2015-11-18T23:23:46.764+01:00[Europe/Madrid]
如果您想要 ISO 8601 样式但没有 T
,请对生成的字符串对象调用 .replace( "T" , "" )
或 define your own formatter.
java.time.format package can do the work of determining a localized format appropriate to a particular Locale
.
Locale locale = Locale.forLanguageTag ( "es-ES" );
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime ( FormatStyle.FULL );
String output = zdt.format ( formatter.withLocale ( locale ) );
miércoles 18 de noviembre de 2015 23H38' CET
您可以使用 String.format() 来避免时区问题
http://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html
此示例给出了以下格式的结果:"yyyy-MM-dd HH:mm:ss"
Calendar c = Calendar.getInstance();
String s = String.format("%1$tY-%1$tm-%1$td:%1$tM:%1$tS", c);
System.out.println(s);
输出:
2015-11-20:44:55