简体   繁体   English

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

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

The time I am getting from Android phone is 我从Android手机获得的时间是

"Mon May 9 09:34:13 CDT 2016\\r\\r\\n" but after parsing the same date using date format SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy",Locale.US); “使用日期格式SimpleDateFormat(”EEE MMM dd HH:mm:ss zzz yyyy“,Locale.US)解析同一日期之后,”使用日期格式5月9日09:34:13 CD \\ 2016 \\ r \\ n \\ n \\ n“。

After parsing it gives me a date into the 解析后给我一个日期

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

It clearly shows that the hours is increase by 11 hours. 它清楚地表明,小时数增加了11个小时。

How to address this issue, Could anybody help me? 如何解决这个问题,有人可以帮助我吗?

Don't forget Date class is a class with no format at all.... 不要忘记Date类是一个完全没有格式的类....

if you want to print a date you need to use the format method of the intenace you created... 如果你想打印一个日期,你需要使用你创建的对象的格式方法...

example: 例:

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;dr TL;博士

Your India time is correctly adjusted 10.5 hours ahead of Chicago time. 您的印度时间比芝加哥时间提前10.5小时正确调整。 Feature, not a bug. 功能,而不是错误。 (I am assuming your :56 seconds was a typo in your Question.) (我假设您:56秒是您问题中的拼写错误。)

If you want no such adjustment, but instead want the same date and same time-of-day assigned to a different time zone, then do this: 如果您不想进行此类调整,而是希望将相同的日期和相同的时间分配给不同的时区,请执行以下操作:

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[Asia/Kolkata] 2016-05-09T09:34:13 + 05:30 [亚/加尔各答]

We get the same date and same time-of-day, but a different offset-from-UTC means this is a different moment, a different point on the timeline. 我们获得相同的日期和相同的时间,但是与UTC的不同偏移意味着这是一个不同的时刻,时间轴上的不同点。

Correct values 正确的价值观

[Note: I am assuming the :56 in your Mon May 09 20:04:56 IST 2016 was a typo, and should have been :13 . [注意:我假设:56你在Mon May 09 20:04:56 IST 2016Mon May 09 20:04:56 IST 2016 :56是一个错字,应该是:13 ] ]

The strings Mon May 9 09:34:13 CDT 2016 and Mon May 09 20:04:13 IST 2016 represent the same moment. 字符串Mon May 9 09:34:13 CDT 2016Mon May 09 20:04:13 IST 2016代表同一时刻。 This is a feature, not a bug. 这是一个功能,而不是一个bug。 If by CDT you mean a time zone such as America/Chicago , that value on that date represents a moment five hours behind UTC, -05:00 . 如果CDT是指America/Chicago这样的时区,则该日期的值表示 UTC时间 5小时的时间, -05:00 If by IST , you mean a time zone such as Asia/Kolkata , India on that date is five and a half hours ahead of UTC, +05:30 . 如果按照IST ,你指的是Asia/Kolkata这样的时区,那个日期 UTC 5个半小时,+05 +05:30 Add those offsets together, and we get a difference of ten and a half hours. 将这些偏移量加在一起,我们得到相差十个半小时。 This fits: 09:34:13 plus 10.5 hours is 20:04:13 . 这适合: 09:34:1309:34:1309:34:13加10.5小时是20:04:13

In other words, if someone in Chicago is talking to someone in Kolkata on the telephone, if they both look up at the time on the clock on their own wall, one will see 09:34:13 while the other sees 20:04:13. 换句话说,如果芝加哥的某个人正在通过电话与加尔各答的某个人交谈,如果他们都在自己的墙上查看时间,那么人们会看到09:34:13,而另一个人看到20:04: 13。

Perhaps you wanted to purposely not adjust for time zone, but re-create the same date with the same time-of-day but in a different time zone. 也许你想故意调整时区,但是在相同的时间但是在不同的时区重新创建相同的日期。 This would not be the same moment, this would a different point on the timeline. 不会是同一时刻,这将是时间轴上的不同点。 See below for such code. 请参阅下面的代码。

java.time java.time

You are using troublesome old classes that were supplanted long ago by the modern java.time classes. 您正在使用很久以前被现代java.time类取代的麻烦的旧类。

When possible, avoid manipulating strings as a way of handling date-time. 如果可能,请避免操纵字符串作为处理日期时间的方法。 Instead, use smart objects, not dumb strings. 相反,使用智能对象,而不是愚蠢的字符串。

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.

If you must exchange date-time values as text, use standard ISO 8601 formats rather than formats such as seen in your Question. 如果必须将日期时间值更改为文本,请使用标准ISO 8601格式,而不是问题中所示的格式。

Also, never use the 3-4 letter pseudo-time-zones such as CDT or IST . 此外,永远不要使用3-4个字母的伪时区,如CDTIST These are not true time zones, are not standardized, and many are not unique(!). 这些不是真正的时区,没有标准化,许多不是唯一的(!)。 Use full time zone names is the IANA-specified Continent/Region format. 使用全区域名称是IANA指定的 Continent/Region格式。

But to your Question directly, parsing the string Mon May 9 09:34:13 CDT 2016 . 但直接对你的问题,解析字符串Mon May 9 09:34:13 CDT 2016 Define a formatting pattern to match. 定义要匹配的格式模式。

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[America/Chicago] zdt.toString():2016-05-09T09:34:13-05:00 [美国/芝加哥]

ZonedDateTime::withZoneSameInstant

Adjust into India time. 调整到印度时间。

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

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

Same behavior as you saw with the legacy classes. 与您在遗留类中看到的行为相同。 Adding 10.5 hours to 09:34:13 gets us 20:04:13. 在09:34:13增加10.5小时,我们得到20:04:13。 Same moment, same point on the timeline, but different wall-clock time. 同一时刻,时间轴上的相同点,但不同的挂钟时间。

ZonedDateTime::withZoneSameLocal

But what if you want the same date and same time-of-day, but switch out the time zone? 但是,如果您想要相同的日期和相同的时间,但切换时区怎么办? This would result in a different moment, different points on the timeline (assuming the two zones don't share the same offset). 这将导致不同的时刻,时间线上的不同点(假设两个区域不共享相同的偏移)。 The ZonedDateTime does support this manipulation via the ZonedDateTime::withZoneSameLocal​(ZoneId zone) method. ZonedDateTime通过ZonedDateTime::withZoneSameLocal​(ZoneId zone)方法支持此操作。

ZonedDateTime zdtSameLocalKolkata = zdt.withZoneSameLocal( zKolkata );

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

Now we see the time-of-day unchanged, still 09:34:13. 现在我们看到时间不变,仍然是09:34:13。 But the offset-from-UTC is different than Chicago, so we know this does not represent the same moment. 但偏移从-UTC是比芝加哥不同,所以我们知道这并不代表同一时刻。

You can verify the fact they are different moments by adjusting both into UTC. 您可以通过将两者都调整为UTC来验证它们是不同的时刻。 The easy way to make that adjustment is to extract Instant object. 进行调整的简便方法是提取Instant对象。 An Instant is always in UTC by definition. 根据定义, Instant始终为UTC。

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

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

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


About java.time 关于java.time

The java.time framework is built into Java 8 and later. java.time框架内置于Java 8及更高版本中。 These classes supplant the troublesome old legacy date-time classes such as java.util.Date , Calendar , & SimpleDateFormat . 这些类取代了麻烦的旧遗留日期时间类,如java.util.DateCalendarSimpleDateFormat

The Joda-Time project, now in maintenance mode , advises migration to the java.time classes. 现在处于维护模式Joda-Time项目建议迁移到java.time类。

To learn more, see the Oracle Tutorial . 要了解更多信息,请参阅Oracle教程 And search Stack Overflow for many examples and explanations. 并搜索Stack Overflow以获取许多示例和解释。 Specification is JSR 310 . 规范是JSR 310

You may exchange java.time objects directly with your database. 您可以直接与数据库交换java.time对象。 Use a JDBC driver compliant with JDBC 4.2 or later. 使用符合JDBC 4.2或更高版本的JDBC驱动程序 No need for strings, no need for java.sql.* classes. 不需要字符串,不需要java.sql.*类。

Where to obtain the java.time classes? 从哪里获取java.time类?

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

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