从遵循时区的日历对象获取格式化字符串的最简单方法是什么



当我在网上搜索"如何将Calendar转换为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));

在晚上 8:02 从位于伦敦 (UTC+0( 的机器运行此代码时,我得到了以下结果:

Wed Nov 18 20:02:26 UTC 2015
2015-11-18 20:02:26
21

最后一行根据日历的时区(马德里是 UTC+1(显示实际小时。现在是马德里晚上 9:02,但显然本机Date.toStringDateFormat.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 中处理时区的详细信息,请参阅此处。

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/。完全是日历。

这些旧的日期时间类已被 Java 8 及更高版本中内置的 java.time 框架所取代。新类的灵感来自非常成功的Joda-Time框架,该框架旨在作为其继任者,概念相似但重新架构。由 JSR 310 定义。由ThreeTen-Extra项目扩展。请参阅教程。

Instant

Instant表示时间轴上的时刻(以 UTC 表示

(。
Instant instant = Instant.now ( ); // Current moment in UTC.

对于给定的Calendar对象,使用 Java 8 中添加的方法转换为Instant toInstant

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 标准格式。默认情况下,除了通常的 UTC 偏移量外,还通过附加时区名称来扩展 ISO 8601 样式。

即时: 2015-11-18T22:23:46.764Z

调整为区域: 欧洲/马德里是 zdt: 2015-11-18T23:23:46.764+01:00[欧洲/马德里]

如果需要 ISO 8601 样式但没有T,请对生成的 String 对象调用 .replace( "T" , "" ) 或定义自己的格式化程序。

java.time.format 包可以完成确定适合特定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

相关内容

  • 没有找到相关文章

最新更新