проблема с функцией календаря Java - PullRequest
2 голосов
/ 09 мая 2011

Я объявил 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 часов).В чем может быть проблема?

Ответы [ 5 ]

1 голос
/ 09 мая 2011

Если вы не собираетесь выполнять вычисления, связанные с датой / временем, нет смысла создавать экземпляр Calendar с заданным 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, что, я полагаю, является вашим желаемым результатом.

1 голос
/ 09 мая 2011

Идентификатор часового пояса должен быть установлен как 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()));
0 голосов
/ 23 января 2018

tl; др

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

2018-01-23T18: 48: 32.263 + 08:00*

В Вопросе и других ответах используются проблемные старые классы даты и времени, которые теперь унаследованы и заменены классами java.time.

java.time

Современный подход использует java.время занятий.Забудьте все о ужасно запутанном классе Calendar.

Текущий момент

Сначала получите текущий момент в UTC.Класс Instant представляет момент на временной шкале в UTC с разрешением наносекунд (до девяти (9) цифр десятичной дроби).

Instant instant = Instant.now() ;

Часовой пояс

Настройка на другой часовой пояс.

Укажите правильное имя часового пояса в формате continent/region, например America/Montreal, Africa/Casablanca или Pacific/Auckland.Никогда не используйте 3-4-буквенные псевдозоны, такие как EST или IST, поскольку они не истинных часовых поясов, не стандартизированы и даже не уникальны (!)

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

Применение ZoneId для создания экземпляра объекта ZonedDateTimeZonedDateTime, и Instant представляют один и тот же момент, одну и ту же точку на временной шкале, но просматриваются через другое время настенных часов.

ZonedDateTime zdt = instant.atZone( z ) ;  // Same moment, different wall-clock time.

Смещение

Еслиу вас было только смещение от UTC , такое как +08:00, а не известный часовой пояс , вы бы использовали ZoneOffset, чтобы получить OffsetDateTime вместо ZoneId & ZonedDateTime.Но часовой пояс всегда предпочтительнее простого смещения.Зона - это история смещений, используемых людьми определенного региона.

Строки

Чтобы сгенерировать строку в стандартном формате ISO 8601 , вызовите метод toString.

Класс ZonedDateTime разумно расширяет стандарт, добавляя имя часового пояса в квадратных скобках.

String output = zdt.toString() ;  // YYYY-MM-DDTHH:MM:SS.SSSSSSSSS[tz]

Локализуйте в соответствии с предпочтениями пользователя.Для локализации укажите:

  • FormatStyle, чтобы определить, какой длины или сокращенной должна быть строка.
  • Locale определить (а) человеческий язык для перевода названия дня, названия месяца и т. Д. И (б) культурных норм, решающих вопросы сокращения, использования заглавных букв, пунктуации, разделителей и т. Д.

    Locale l = Locale.CANADA_FRENCH;DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime (FormatStyle.FULL) .withLocale (l);Вывод строки = zdt.format (f);

Дамп на консоль.

System.out.println( "instant.toString(): " + instant ) ;
System.out.println( "output: " + output ) ;
System.out.println( "outputLocalized (always Locale.US on IdeOne.com): " + outputLocalized ) ;

См. Этот код, запущенный в режиме реального времени на IdeOne.com ,Обратите внимание, что IdeOne.com переопределяет любой параметр Locale, чтобы всегда использовать Locale.US.

instant.toString (): 2018-01-23T10: 48: 32.263Z

выход: 2018-01-23T18: 48: 32.263 + 08: 00 [Asia / Kuala_Lumpur]

ooutputLocalized (всегда Locale.US на IdeOne.com): вторник, 23 января 2018 г. 18:48:32 PM MYT


О java.time

Фреймворк java.time встроен в Java 8 и более поздние версии.Эти классы вытесняют проблемные старые устаревшие классы даты и времени, такие как java.util.Date, Calendar, & SimpleDateFormat.

Проект Joda-Time , теперь в режиме обслуживания , рекомендует перейти на классы java.time .

Чтобы узнать больше, см. Oracle Tutorial .И поиск переполнения стека для многих примеров и объяснений.Спецификация: JSR 310 .

Где получить классы java.time?

  • Java SE 8 , Java SE 9 , а позже
    • Встроенный-в.
    • Часть стандартного Java API с встроенной реализацией.
    • Java 9 добавляет некоторые незначительные функции и исправления.
  • Java SE 6 и Java SE 7
    • Большая часть функций java.time перенесена на Java 6 & 7 в ThreeTen-Backport .
  • Android
    • Более поздние версии Android связывают реализации классов java.time.
    • Для более ранних версий Android проект ThreeTenABP адаптируется ThreeTen-Backport (упоминалось выше). См. Как использовать ThreeTenABP… .

Проект ThreeTen-Extra расширяет java.time дополнительными классами. Этот проект является полигоном для возможных будущих дополнений к java.time. Здесь вы можете найти некоторые полезные классы, такие как Interval, YearWeek, YearQuarter и more .

0 голосов
/ 09 мая 2011

Если вы внимательно прочитали javadoc TimeZone, способ использовать getTimeZone: TimeZone.getTimeZone ( "GMT-8") или же TimeZone.getTimeZone ( "GMT + 8")

0 голосов
/ 09 мая 2011

Вызов TimeZone.getTimeZone() неправильный. Вы должны передать правильный идентификатор.

РЕДАКТИРОВАТЬ - Вы можете попробовать getAvailableIDs () и выполнить их итерацию, чтобы убедиться, что у вас есть правильный идентификатор.

...