我宣布Calendar
和SimpleDateFormat
是这样的:
calendar = Calendar.getInstance(TimeZone.getTimeZone("Malaysia"));
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MMMMM.dd hh:mm aaa");
或:
calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:00"));
然后我称之为:
sdf.format(calendar.getTime());
但结果不在正确的时区(+8小时)。可能是什么问题?
答案 0 :(得分:1)
时区ID应设为Asia/Kuala_Lumpur
。 Date.toString()
始终使用默认时区返回时间字符串。但您的默认时区不同。
Calendar tzCal = Calendar.getInstance(TimeZone.getTimeZone("Asia/Kuala_Lumpur"));
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, tzCal.get(Calendar.YEAR));
cal.set(Calendar.MONTH, tzCal.get(Calendar.MONTH));
cal.set(Calendar.DAY_OF_MONTH, tzCal.get(Calendar.DAY_OF_MONTH));
cal.set(Calendar.HOUR_OF_DAY, tzCal.get(Calendar.HOUR_OF_DAY));
cal.set(Calendar.MINUTE, tzCal.get(Calendar.MINUTE));
cal.set(Calendar.SECOND, tzCal.get(Calendar.SECOND));
cal.set(Calendar.MILLISECOND, tzCal.get(Calendar.MILLISECOND));
System.out.println("Current Time = " + sdf.format(cal.getTime()));
答案 1 :(得分:1)
除非您要执行与日期/时间相关的计算,否则使用给定的TimeZone实例化日历是没有意义的。调用日历的getTime()
方法后,您将收到Date
个对象,无论是哪种方式都是时区(实际上是基于GMT)。
您需要做的是改为为格式化程序设置TimeZone
。并且也不用担心传递自己的格式,已经内置了:
// get current time
// you could just as well use Date now = new Date();
Calendar now = Calendar.getInstance();
// Locale for formatter
Locale malaysianLocale = new Locale("ms", "MY");
// Default date and time format for Malaysia
DateFormat defaultMalaysianFormatter = DateFormat.getDateTimeInstance(
DateFormat.DEFAULT, DateFormat.DEFAULT, malaysianLocale);
// This step is crucial
TimeZone malaysianTimeZone = TimeZone.getTimeZone("Asia/Kuala_Lumpur");
defaultMalaysianFormatter.setTimeZone(malaysianTimeZone);
System.out.println(defaultMalaysianFormatter.format(now.getTime()));
这会打印10 Mei 2011 2:30:05 AM
之类的内容,我相信这是您想要的结果。
答案 2 :(得分:0)
TimeZone.getTimeZone()
来电不正确。您必须传递正确的标识符。
编辑 - 您可以尝试使用getAvailableIDs()并对其进行迭代,以确保您拥有正确的ID。
答案 3 :(得分:0)
如果你仔细阅读了TimeZone的javadoc,那么使用getTimeZone的方法是: TimeZone.getTimeZone( “GMT-8”) 要么 TimeZone.getTimeZone( “GMT + 8”)
答案 4 :(得分:0)
java.time.ZonedDateTime.now(
ZoneId.of( "Asia/Kuala_Lumpur" )
).toString()
2018-01-23T18:48:32.263 + 08:00 [亚洲/吉隆坡]
问题和其他答案使用现在遗留下来的麻烦的旧日期时间类,取而代之的是java.time类。
现代方法使用java.time类。忘记所有关于非常令人困惑的Calendar
类。
首先以UTC格式获取当前时刻。 Instant
类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。
Instant instant = Instant.now() ;
调整到另一个时区。
以continent/region
的格式指定proper time zone name,例如America/Montreal
,Africa/Casablanca
或Pacific/Auckland
。切勿使用诸如EST
或IST
之类的3-4个字母伪区域,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "Asia/Kuala_Lumpur" ) ; // Or "Asia/Kuching", etc.
应用ZoneId
来实例化ZonedDateTime
对象。 ZonedDateTime
和Instant
都代表相同的时刻,即时间轴上的相同点,但是通过不同的挂钟时间来查看。
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, different wall-clock time.
如果您只有offset-from-UTC,例如+08:00
而不是已知的time zone,则可以使用ZoneOffset
获取OffsetDateTime
而不是ISO 8601 {1}}& ZoneId
。但是时区总是优于仅仅偏移。区域是特定地区人民使用的抵消历史。
要生成标准FormatStyle
格式的字符串,请调用ZonedDateTime
方法。
toString
类通过在时方括号中附加时区名称来明智地扩展标准。
ZonedDateTime
本地化为用户的偏好设置。要进行本地化,请指定:
Locale
确定字符串的长度或缩写。code run live at IdeOne.com确定(a)翻译日期名称,月份名称等的人类语言,以及(b)决定缩写,大小写,标点符号,分隔符问题的文化规范等等。
Locale l = Locale.CANADA_FRENCH; DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withLocale(l); String output = zdt.format(f);
转储到控制台。
String output = zdt.toString() ; // YYYY-MM-DDTHH:MM:SS.SSSSSSSSS[tz]
见java.time。请注意,IdeOne.com会覆盖任何System.out.println( "instant.toString(): " + instant ) ;
System.out.println( "output: " + output ) ;
System.out.println( "outputLocalized (always Locale.US on IdeOne.com): " + outputLocalized ) ;
设置,以便始终使用Locale
。
instant.toString():2018-01-23T10:48:32.263Z
输出:2018-01-23T18:48:32.263 + 08:00 [Asia / Kuala_Lumpur]
ooutputLocalized(在IdeOne.com上始终是Locale.US):2018年1月23日星期二下午6:48:32 MYT
legacy框架内置于Java 8及更高版本中。这些类取代了麻烦的旧java.util.Date
日期时间类,例如Calendar
,SimpleDateFormat
和& Joda-Time
现在位于maintenance mode的java.time项目建议迁移到Oracle Tutorial类。
要了解详情,请参阅JSR 310。并搜索Stack Overflow以获取许多示例和解释。规范是Java SE 8。
从哪里获取java.time类?
Interval
项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如YearWeek
,YearQuarter
,more和{{3}}。