2014-12-03 2 views
1

У меня есть экземпляр календаря в григорианском стиле с использованием определенного часового пояса. Я установил дату календаря в 1970-01-01. Когда я получаю год, месяц, день поля, они отличаются от того, что я их установил.Почему класс java.util.Calendar дает неверную дату на Android?

Если я запускаю этот код на андроид устройство печатает «1969-11-31»

Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("America/Bahia_Banderas")); 

    cal.clear(); 
    cal.set(1970, 0, 1); 

    // Should print "1970-0-1" but prints "1969-11-31" 
    android.util.Log.i("date", cal.get(Calendar.YEAR) + "-" + cal.get(Calendar.MONTH) + "-" + cal.get(Calendar.DAY_OF_MONTH)); 

Однако, работает один и тот же код на чистом Java он работает, как ожидалось.

Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("America/Bahia_Banderas")); 
    cal.clear(); 
    cal.set(1970, 0, 1); 

    // Prints "1970-0-1" as expected 
    System.out.println(cal.get(Calendar.YEAR) + "-" + cal.get(Calendar.MONTH) + "-" + cal.get(Calendar.DAY_OF_MONTH)); 

я читал в классе Calendar в bug, который, казалось, связано с моей проблемой. Я попробовал обходное решение, упомянутое в отчете об ошибке, но это не сработало для меня. Самое странное, однако, состоит в том, что один и тот же класс ведет себя по-разному на Android и на чистой Java. Я хочу, чтобы экземпляр календаря вернул правильную дату после того, как я его установил. Вы знаете, как достичь этого?

ответ

3

Calendar.clear() реализация отличается в обычных Java и Android.

В частности, the regular Java implementation устанавливает isTimeSet на значение false. Android implementation нет.

Когда вы создаете свой Calendar, его время устанавливается на текущее время, а isTimeSet имеет значение true. Вызов clear() отключает/нулевает значения полей в обеих реализациях.

Ваш часовой пояс UTC + 6, поэтому 1970-01-01T00: 00: 00 - 1969-12-31T18: 00: 00 в вашей временной зоне. Поскольку флаг isTimeSet по-прежнему установлен в Android, время не пересчитывается при запросе даты и времени.

+0

Упс - реализация Android также очищает флаг 'isTimeSet', это просто на той же строке с другой булевой отметкой флага. У меня нет времени, чтобы заглянуть в это глубже. Во всяком случае, общая идея UTC + 6 сохраняется; просто не объяснение разницы между Android и обычной Java. – laalto

0

Попробуйте это:

TimeZone MyTimezone = TimeZone.getDefault(); 
Calendar calendar = new GregorianCalendar(MyTimezone); 
calendar.set(year, month, day, hour, minute, second); 

String month_name=calendar.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.getDefault());//Locale.US); 
String day_name=calendar.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.SHORT, Locale.getDefault());//Locale.US); 
0

удалить cal.clear();

Я попробовал, и это правильно печатает.

Редактировать: с любопытством. если вы это сделаете:

cal.clear(); 
cal.getTime(); // or any other methods that access the calendar object. 
cal.set(1970, 0, 1); 

он будет печатать правильно.

Я предполагаю, что это что-то делать с объяснением для .clear()

Очищает значения всех полей времени, пометив их все отключенное и назначая им все значение, равное нулю. Фактические значения полей будут определены при следующем доступе к полям.

-1

В андроид вы можете использовать этот путь, чтобы получить информацию: Календарь calendar = Calendar.getInstance(); calendar.set (1970, 0, 1);

System.out.println ("год:" + calendar.get (Calendar.YEAR) + "- месяц:" + calendar.get (Calendar.MONTH) + "- день:" + calendar.get (Calendar.DAY_OF_MONTH));

Результат: Год выпуска: 1970 --month: 0 --day: 1

Смежные вопросы