Why the time of AWST and CCT are not the same?
I have write a static class named"DateUtils" and here is a static method named "parseDate(String)" it will use some patterns to convert the string to a date. the default timeZone is Asia/Shanghai (I'am in China)
public static final TimeZone SHA = TimeZone.getTimeZone("Asia/Shanghai");
and it will be passed to the method TimeZone.setDefault(timeZone); And Using SimpleDateFormat to concert the String. The matched pattern should be "EEE, dd MMM yyyy HH:mm:ss zzz" And Here are three Test of it.
//this one is ok.
@Test
public void testParseGMTDate() throws Exception {
Date date = DateUtils.parseDate("Thu, 02 Aug 2016 08:12:34 GMT");
assertNotNull(date);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
log.debug(DateUtils.format(cal.getTime()));
assertEquals(cal.get(Calendar.YEAR), 2016);
assertEquals(cal.get(Calendar.MONTH), 8 - 1);
assertEquals(cal.get(Calendar.DATE), 2);
assertEquals(cal.get(Calendar.HOUR_OF_DAY), 8 + 8);
assertEquals(cal.get(Calendar.MINUTE), 12);
assertEquals(cal.get(Calendar.SECOND), 34);
assertEquals(DateUtils.format(cal.getTime()), "2016-08-02 16:12:34");
}
// AWST is GMS+8:00 time so this one is ok.
@Test
public void testParseWSTDate() throws Exception {
Date date = DateUtils.parseDate("Thu, 02 Aug 2016 08:12:34 AWST");
assertNotNull(date);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
log.debug(DateUtils.format(cal.getTime()));
assertEquals(cal.get(Calendar.YEAR), 2016);
assertEquals(cal.get(Calendar.MONTH), 8 - 1);
assertEquals(cal.get(Calendar.DATE), 2);
assertEquals(cal.get(Calendar.HOUR_OF_DAY), 8);
assertEquals(cal.get(Calendar.MINUTE), 12);
assertEquals(cal.get(Calendar.SECOND), 34);
}
// junit.framework.AssertionFailedError:
// Expected :9
// Actual :8
@Test
public void testParseDateCCT() throws Exception {
Date date = DateUtils.parseDate("Thu, 02 Aug 2016 08:12:34 CCT");
assertNotNull(date);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
log.debug(DateUtils.format(cal.getTime()));
assertEquals(cal.get(Calendar.YEAR), 2016);
assertEquals(cal.get(Calendar.MONTH), 8 - 1);
assertEquals(cal.get(Calendar.DATE), 2);
assertEquals(cal.get(Calendar.HOUR_OF_DAY), 8); //Expected: 9
assertEquals(cal.get(Calendar.MINUTE), 12);
assertEquals(cal.get(Calendar.SECOND), 34);
}
And here are some code snippet of DateUtils.
public static final TimeZone SHA = TimeZone.getTimeZone("Asia/Shanghai");
static {
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(SHA);
calendar.set(2000, 0, 1, 0, 0, 0);
calendar.set(MILLISECOND, 0);
TWO_DIGIT_START = calendar.getTime();
}
public static Date parseDate(String dateValue) {
return parseDate(dateValue, null, null, SHA);
}
public static Date parseDate(String dateValue, String[] dateFormats, Date startDate, TimeZone timeZone) {
TimeZone.setDefault(timeZone);
String[] localDateFormats = dateFormats != null ? dateFormats : DEFAULT_PATTERNS;
Date localStartDate = startDate != null ? startDate : TWO_DIGIT_START;
String v = dateValue;
if (dateValue.length() > 1 && dateValue.startsWith("'") && dateValue.endsWith("'")) {
v = dateValue.substring(1, dateValue.length() - 1);
}
String[] arr = localDateFormats;
int len = localDateFormats.length;
for (String dateFormat : DEFAULT_PATTERNS) {
// String dateFormat = arr[i];
SimpleDateFormat dateParser = DateUtils.DateFormatHolder.formatFor(dateFormat);
dateParser.set2DigitYearStart(localStartDate);
ParsePosition pos = new ParsePosition(0);
Date result = dateParser.parse(v, pos);
if (pos.getIndex() != 0) {
_LOG.debug("Date parsed using: {}", dateFormat);
return result;
}
}
_LOG.error("Can't parse data: {data:{}, formats:{}, startDate:{},tz:{}}",
dateValue, localDateFormats, localStartDate, TimeZone.getDefault());
return null;
}
My Question is: According to document on the internet, CCT & AWST are both the GMT+8:00 time zone, why in my test it seem like that the CCT Time is GMT+9:00.
tl;dr
You have made three mistakes:
Instead, use proper time zone names in the format of continent/region
. Study the documented meaning of those zones rather than assume/guess. Use only java.time classes for date-time work.
All these are common errors made by many programmers, as evidenced by the many Questions here on Stack Overflow.
Use proper time zone names
CST
is also Central Standard Time
in North America. One example of why you should never use these 3-4 letter abbreviations. They are not true time zones, not standardized, and not even unique(!). Use proper IANA time zone names. These are in the format of continent/region
.
java.time
You are using old troublesome date-time classes. Avoid them.
The java.time framework is built into Java 8 and later. These classes supplant the old troublesome date-time classes such as java.util.Date
, .Calendar
, & java.text.SimpleDateFormat
. The Joda-Time team also advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
Instant
The Instant
class is a moment on the timeline in UTC (GMT) with a resolution up to nanoseconds.
Instant instant = Instant.parse ( "2016-08-02T08:12:34Z" ); // 02 Aug 2016 08:12:34
ZonedDateTime
The ZonedDateTime
represents an Instant
adjusted into a time zone.
I assume you meant Australian western standard time by AWST
, officiall named Australia/Perth
.
ZoneId zoneId_Perth = ZoneId.of ( "Australia/Perth" );
ZonedDateTime zdt_Perth = instant.atZone ( zoneId_Perth );
For China, you intended Asia/Shanghai
.
ZoneId zoneId_Shanghai = ZoneId.of ( "Asia/Shanghai" );
ZonedDateTime zdt_Shanghai = zdt_Perth.withZoneSameInstant ( zoneId_Shanghai );
I am not sure what your or the old date-time classes meant by CCT
. This page says it is “Cocos Islands Time”, six and a half hours ahead of UTC year-round (no Daylight Saving Time, DST). Again, this is an example of why you should never use the 3-4 letter abbreviations.
ZoneId zoneId_Cocos = ZoneId.of ( "Indian/Cocos" );
ZonedDateTime zdt_Cocos = zdt_Perth.withZoneSameInstant ( zoneId_Cocos );
You may have meant Beijing time, according to a comment. If so, know that Beijing time is covered by the Asia/Shanghai
time zone according to this list in Wikipedia.
Dump to console. You can see that both Perth and Shanghai are eight hours ahead of UTC in August this year for an hour-of-day of 16 versus 8 ( 16:12:34
versus 08:12:34
). The Cocos Islands is in between, at 14:42:34
for 6.5 hours ahead of UTC.
System.out.println ( "instant: " + instant + " | zdt_Perth: " + zdt_Perth + " | zdt_Shanghai: " + zdt_Shanghai + " | zdt_Cocos: " + zdt_Cocos );
instant: 2016-08-02T08:12:34Z | zdt_Perth: 2016-08-02T16:12:34+08:00[Australia/Perth] | zdt_Shanghai: 2016-08-02T16:12:34+08:00[Asia/Shanghai] | zdt_Cocos: 2016-08-02T14:42:34+06:30[Indian/Cocos]
DateTimeFormatter
To generate strings in formats other than the standard ISO 8601 formats shown here, use DateTimeFormatter
class.
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL );
f = f.withLocale( Locale.CHINA );
String output = zdt_Shanghai.format( f );
链接地址: http://www.djcxy.com/p/952.html
上一篇: 从Java传递日期值的字符
下一篇: 为什么AWST和CCT的时间不一样?