Я использую SimpleDateFormat
, чтобы превратить мои GregorianCalendar
экземпляры в красивые строки. У меня странная проблема, когда в определенных датахвремя строка отключена одним, но не всегда.SimpleDateFormat часовая строка по-одному на определенные * даты *. Как? Зачем?
Обычно, если мой GregorianCalendar
имеет значения, такие как HOUR_OF_DAY=0,MINUTE=11
, тогда я получаю строку типа «1:11 AM». Но затем я меняю YEAR
, MONTH
, или DAY
, и теперь HOUR_OF_DAY=0,MINUTE=11
дает мне строку «2:11».
Это мое время функции форматирования строк (даты и времени является GregorianCalendar
):
public String toTimeString() {
Log.i(TAG, "Datetime: "+ datetime.toString() + "Formatted as: " + SimpleDateFormat.getTimeInstance(SimpleDateFormat.SHORT).format(datetime.getTime()));
return SimpleDateFormat.getTimeInstance(SimpleDateFormat.SHORT).format(datetime.getTime());
}
Это дает мне эти журналы:
Работа хорошо первый:
Datetime: java.util.GregorianCalendar[time=1426637512725,areFieldsSet=true,lenient=true,zone=GMT,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2015,MONTH=2,WEEK_OF_YEAR=12,WEEK_OF_MONTH=3,DAY_OF_MONTH=18,DAY_OF_YEAR=77,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=3,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=11,SECOND=52,MILLISECOND=725,ZONE_OFFSET=0,DST_OFFSET=0]
Formatted as: 1:11 AM
я изменить месяц с марта по апрель (год и день делают то же самое), а теперь это:
Datetime: java.util.GregorianCalendar[time=1429315912725,areFieldsSet=true,lenient=true,zone=GMT,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2015,MONTH=3,WEEK_OF_YEAR=16,WEEK_OF_MONTH=3,DAY_OF_MONTH=18,DAY_OF_YEAR=108,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=3,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=11,SECOND=52,MILLISECOND=725,ZONE_OFFSET=0,DST_OFFSET=0]
Formatted as: 2:11 AM
Как это возможно?
Такое поведение по отдельности происходит только в следующих месяцах, а не в этом месяце или в прошлом. 2015 и 2016 годы прекрасны, но 2017 тоже вызывает проблему. Фактическая дата, похоже, вызывает ее, когда наступает неделя или больше в будущем (независимо от года).
Я могу изменить год, месяц и дату в разных виджетах пользовательского интерфейса, переключая форматирование строки времени от нормального к офлайновому и обратно. Я управляю часом с TimePicker
, который вызывает форматирование строк на TimePicker.OnTimeChangedListener()
. Я не думаю, что это актуально, так как оно работает, когда месяц и день установлены на некоторые значения, но вот этот код на всякий случай. Как вы можете видеть, есть некоторая обработка по отдельности, так как GregorianCalendar
хранит HOUR_OF_DAY
как значение 0-23, а TimePicker
использует значения 1-24, соответствующие фактическому отображению виджета. Я думаю, что я сделал это правильно, но был бы рад узнать, что проблема - ошибка здесь.
private void setUpTimePicker() {
timePicker.setCurrentHour(schedule.getHourOfDay() + 1);
timePicker.setCurrentMinute(schedule.getMinute());
timePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
schedule.setHourOfDay(hourOfDay - 1);
schedule.setMinute(minute);
timeText.setText(schedule.toTimeString());
}
});
}
Время суток отформатированных в строку всегда права (0 = 1 утра, 17 = 5 вечера, и т.д. в течение каждого часа дня) или всегда так (0 = 2 утра, 17 = 6 вечера, ЭСТ для каждого час дня) на основе других полей календаря. Согласованность заставляет меня думать, что это не проблема нити.
Не может быть проблема с часовым поясом как и любой другой подобный вопрос? Я не представляю, как. Мои GregorianCalandar
экземпляры всегда создаются с помощью этой функции:
public static TimeZone TIMEZONE = TimeZone.getTimeZone("GMT");
private static GregorianCalendar makeCalendar(){
GregorianCalendar now = (GregorianCalendar) GregorianCalendar.getInstance(TIMEZONE);
now.setFirstDayOfWeek(Calendar.SUNDAY);
return now;
}
Любые мысли были бы очень признательны! Я исчерпал все, о чем я могу думать, в том числе спать на нем в течение нескольких дней. Спасибо заранее всем, кто отвечает!
UPDATE
Джон нашел проблему, но поскольку изменение кода скрыт в комментариях, я буду копировать его здесь, тоже.
Проблема заключалась в том, что SimpleDateFormat
использует системный часовой пояс, а не часовой пояс данного GregorianCalendar
, как я предполагал. Я это исправил, изменив эту строку:
return SimpleDateFormat.getTimeInstance(SimpleDateFormat.SHORT).format(datetime.getTime());
к этому:
SimpleDateFormat sdf = new SimpleDateFormat("hh:mm a", LOCALE);
sdf.setTimeZone(TIMEZONE);
return sdf.format(datetime.getTime());
Затем я удалил +1
и -1
от TimePicker
и это работает!
я сомневаюсь это, но, возможно, это имеет какое-то отношение к летней экономии? – Felk
Почти наверняка летнее время. Если дата/время конвертируется в ваш язык во время печати, а вы в Великобритании, с ноября по март (более или менее), ваше местное время совпадает с GMT. Но с апреля по октябрь (более или менее) ваше местное время на один час раньше GMT. – jas
@jas и @Felk - Я не в Великобритании, я в Италии. Но да! Я не знал, что мне нужно установить часовой пояс в 'SimpleDateFormat'. Я чувствую себя глупо, потому что не видел этого сейчас (один из раздражающих двух месяцев года, когда США сделали летнее сбережение, но в Италии нет, и это влияет на мой календарь весь месяц). Наверное, мне просто было в голове, что я использую GMT, а timezones/DST - не моя проблема. И я был так уверен * мой вопрос не был другим часовым поясом! Ну что ж! По крайней мере, вы были очень хороши в этом :) –