繁体   English   中英

面对Android中的DateFormat问题,CDT转换为IST

[英]Facing DateFormat issue in Android, CDT converting into IST

我从Android手机获得的时间是

“使用日期格式SimpleDateFormat(”EEE MMM dd HH:mm:ss zzz yyyy“,Locale.US)解析同一日期之后,”使用日期格式5月9日09:34:13 CD \\ 2016 \\ r \\ n \\ n \\ n“。

解析后给我一个日期

“Mon May 09 20:04:56 IST 2016”。

它清楚地表明,小时数增加了11个小时。

如何解决这个问题,有人可以帮助我吗?

不要忘记Date类是一个完全没有格式的类....

如果你想打印一个日期,你需要使用你创建的对象的格式方法...

例:

public static void main(String[] args) throws ParseException {
    String myDate = "Mon May 9 09:34:13 CDT 2016";
    SimpleDateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
    Date d = dateFormat.parse(myDate);
    System.out.println(d);  // this is not formatted printing Mon May 09 16:34:13 CEST 2016
    System.out.println(dateFormat.format(d)); // this is printed using the same format you use above
}

TL;博士

您的印度时间比芝加哥时间提前10.5小时正确调整。 功能,而不是错误。 (我假设您:56秒是您问题中的拼写错误。)

如果您不想进行此类调整,而是希望将相同的日期和相同的时间分配给不同的时区,请执行以下操作:

ZonedDateTime.parse(
    "Mon May 9 09:34:13 CDT 2016" ,  // If at all possible, avoid using such an awful format for exchanging date-time strings. Always use standard ISO 8601 formats instead.
    DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss z uuuu" )
)                                    // Returns a `ZonedDateTime` object.
.withZoneSameLocal( 
    ZoneId.of( "Asia/Kolkata" ) 
)                                    // Returns a fresh `ZonedDateTime` object, with values based on the original but for the change in assigned zone.
.toString()                          // Generates a String is standard ISO 8601 format, extending the standard by appending the name of the time zone in square brackets.

2016-05-09T09:34:13 + 05:30 [亚/加尔各答]

我们获得相同的日期和相同的时间,但是与UTC的不同偏移意味着这是一个不同的时刻,时间轴上的不同点。

正确的价值观

[注意:我假设:56你在Mon May 09 20:04:56 IST 2016Mon May 09 20:04:56 IST 2016 :56是一个错字,应该是:13 ]

字符串Mon May 9 09:34:13 CDT 2016Mon May 09 20:04:13 IST 2016代表同一时刻。 这是一个功能,而不是一个bug。 如果CDT是指America/Chicago这样的时区,则该日期的值表示 UTC时间 5小时的时间, -05:00 如果按照IST ,你指的是Asia/Kolkata这样的时区,那个日期 UTC 5个半小时,+05 +05:30 将这些偏移量加在一起,我们得到相差十个半小时。 这适合: 09:34:1309:34:1309:34:13加10.5小时是20:04:13

换句话说,如果芝加哥的某个人正在通过电话与加尔各答的某个人交谈,如果他们都在自己的墙上查看时间,那么人们会看到09:34:13,而另一个人看到20:04: 13。

也许你想故意调整时区,但是在相同的时间但是在不同的时区重新创建相同的日期。 不会是同一时刻,这将是时间轴上的不同点。 请参阅下面的代码。

java.time

您正在使用很久以前被现代java.time类取代的麻烦的旧类。

如果可能,请避免操纵字符串作为处理日期时间的方法。 相反,使用智能对象,而不是愚蠢的字符串。

Instant instant = Instant.now() ;  // Capture current moment in UTC.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ; 
ZonedDateTime zdt = instant.atZone( z ) ;  // Same moment, same point on the timeline, but different wall-clock time.

如果必须将日期时间值更改为文本,请使用标准ISO 8601格式,而不是问题中所示的格式。

此外,永远不要使用3-4个字母的伪时区,如CDTIST 这些不是真正的时区,没有标准化,许多不是唯一的(!)。 使用全区域名称是IANA指定的 Continent/Region格式。

但直接对你的问题,解析字符串Mon May 9 09:34:13 CDT 2016 定义要匹配的格式模式。

String input = "Mon May 9 09:34:13 CDT 2016";

DateTimeFormatter f = DateTimeFormatter.ofPattern( "EEE MMM d HH:mm:ss z uuuu" );
ZonedDateTime zdt = ZonedDateTime.parse( input , f );

zdt.toString():2016-05-09T09:34:13-05:00 [美国/芝加哥]

ZonedDateTime::withZoneSameInstant

调整到印度时间。

ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdtKolkata = zdt.withZoneSameInstant( zKolkata );

zdtKolkata.toString():2016-05-09T20:04:13 + 05:30 [亚洲/加尔各答]

与您在遗留类中看到的行为相同。 在09:34:13增加10.5小时,我们得到20:04:13。 同一时刻,时间轴上的相同点,但不同的挂钟时间。

ZonedDateTime::withZoneSameLocal

但是,如果您想要相同的日期和相同的时间,但切换时区怎么办? 这将导致不同的时刻,时间线上的不同点(假设两个区域不共享相同的偏移)。 ZonedDateTime通过ZonedDateTime::withZoneSameLocal​(ZoneId zone)方法支持此操作。

ZonedDateTime zdtSameLocalKolkata = zdt.withZoneSameLocal( zKolkata );

zdtSameLocalKolkata.toString():2016-05-09T09:34:13 + 05:30 [亚洲/加尔各答]

现在我们看到时间不变,仍然是09:34:13。 但偏移从-UTC是比芝加哥不同,所以我们知道这并不代表同一时刻。

您可以通过将两者都调整为UTC来验证它们是不同的时刻。 进行调整的简便方法是提取Instant对象。 根据定义, Instant始终为UTC。

Instant instantOfZdtChicago = zdt.toInstant() ;
Instant instantOfZdtSameLocalKolkata = zdtSameLocalKolkata.toInstant():

instantOfZdtChicago.toString():2016-05-09T14:34:13Z

instantOfZdtSameLocalKolkata.toString():2016-05-09T04:04:13Z


关于java.time

java.time框架内置于Java 8及更高版本中。 这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendarSimpleDateFormat

现在处于维护模式Joda-Time项目建议迁移到java.time类。

要了解更多信息,请参阅Oracle教程 并搜索Stack Overflow以获取许多示例和解释。 规范是JSR 310

您可以直接与数据库交换java.time对象。 使用符合JDBC 4.2或更高版本的JDBC驱动程序 不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM