java日历函数的问题

时间:2011-05-09 03:06:06

标签: java internationalization calendar timezone date-format

我宣布CalendarSimpleDateFormat是这样的:

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小时)。可能是什么问题?

5 个答案:

答案 0 :(得分:1)

时区ID应设为Asia/Kuala_LumpurDate.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)

TL;博士

java.time.ZonedDateTime.now(
    ZoneId.of( "Asia/Kuala_Lumpur" ) 
).toString() 
  

2018-01-23T18:48:32.263 + 08:00 [亚洲/吉隆坡]

避免遗留类

问题和其他答案使用现在遗留下来的麻烦的旧日期时间类,取而代之的是java.time类。

java.time

现代方法使用java.time类。忘记所有关于非常令人困惑的Calendar类。

当前时刻

首先以UTC格式获取当前时刻。 Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。

Instant instant = Instant.now() ;

时区

调整到另一个时区。

continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用诸如ESTIST之类的3-4个字母伪区域,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "Asia/Kuala_Lumpur" ) ; // Or "Asia/Kuching", etc.

应用ZoneId来实例化ZonedDateTime对象。 ZonedDateTimeInstant都代表相同的时刻,即时间轴上的相同点,但是通过不同的挂钟时间来查看。

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

关于java.time

legacy框架内置于Java 8及更高版本中。这些类取代了麻烦的旧java.util.Date日期时间类,例如CalendarSimpleDateFormat和& Joda-Time

现在位于maintenance modejava.time项目建议迁移到Oracle Tutorial类。

要了解详情,请参阅JSR 310。并搜索Stack Overflow以获取许多示例和解释。规范是Java SE 8

从哪里获取java.time类?

Interval项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如YearWeekYearQuartermore和{{3}}。