2015-02-17 4 views
1

Каков наилучший способ определения даты и времени в потоке Java (в Android)?Пересчет datetime в Java Thread

У меня есть следующий фрагмент кода:

public void repeatedlyPrintTheTime() { 
    final Handler handler = new Handler(); 

    mR = new Runnable() { 
     public void run() { 
      System.out.println("Time 1 is " + mCalendar.getTime().toString()); 
      System.out.println("Time 2 is " + GregorianCalendar.getInstance().getTime().toString()); 
      handler.postDelayed(this, 1000); 
     } 
    }; 

    handler.postDelayed(mR, 1000); 
} 

Время 1 раз печатает то же самое время, но время 2 обновления на каждой итерации.

Должен ли я получить новый экземпляр GregorianCalendar каждый раз, когда я хочу проверить, что такое время?

+2

Какое у вас? 'GregorianCalendar.getInstance()' создает 'Calender' с текущим временем и часовым поясом. 'mCalender' уже инициализирован и не инициализируется каждый раз, поэтому он печатает свое время (заданное или созданное время) –

+0

Это или LocalDateTime.now() (только для Java8) См. http://stackoverflow.com/questions/5175728/ как-получить-на-текущем-дату-время-в-java для детального анализа. –

+0

@AdrianLeonhard это Android, поэтому нет Java 8 ... Heck, Android даже не имеет Java 7 – fge

ответ

2

ТЛ; др

Да, вы должны получить дату, время прохождения свежего объекта каждый раз, когда вы хотите, чтобы захватить текущий момент. Нет автоматического обновления существующего экземпляра.

Instant.now() 

Одно мгновение, не обновляется автоматически

GregorianCalendar содержит один момент, и не автоматически обновляется. Если бы он обновлялся автоматически, вы никогда не сможете делать какую-либо бизнес-логику, поскольку значение будет постоянно меняться по мере запуска вашего кода!

Использование java.time

Кроме того, GregorianCalendar и его родственные классы ужасный беспорядок, и его следует избегать. Теперь они устарели, вытесняются классами java.time.

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

Instant instant = Instant.now(); 

instant.toString(): 2017-02-27T14: 48: 58.664Z

Чтобы впоследствии захватить текущее время снова получить другой Instant экземпляр.

Instant instantLater = Instant.now(); 

instantLater.toString(): 2017-02-27T14: 49: 02.164Z

Вы можете даже захватить дельту между ними, как Duration объекта.

Duration duration = Duration.between(instant, instantLater); 

duration.toString(): PT3.5S

Чтобы увидеть тот же самый момент через призму какой-то конкретного региона wall-clock time-х, настроить во временную зону. Примените ZoneId, чтобы получить объект ZonedDateTime.

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

ZoneId z = ZoneId.of("America/Montreal"); 
ZonedDateTime zdt = instant.atZone(z); 

zdt.toString(): 2017-02-27T09: 48: 58.664-05: 00 [Америка/Монреаль]

Смотрите эту code run live at IdeOne.com.

Чтобы представить момент в будущем или в прошлом, укажите ввод для получения OffsetDateTime или ZonedDateTime.

JavaDoc ...

ZonedDateTime.of (интермедиат год, Int месяц, Int DayOfMonth, внутр час, Int минуту, Int второй, внутр nanoOfSecond, ZoneId зоны)

ZonedDateTime zdt = ZonedDateTime.of(2017 , 1 , 23 , 12 , 34 , 56 , 123456789 , ZoneId.of("America/Montreal"); 

О java.time

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

Проект Joda-Time, в настоящее время в maintenance mode, советует перейти на классы java.time.

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

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

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

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

+0

Всеобъемлющее - спасибо! – scubbo

0

Некоторые классы календаря не являются потокобезопасными. Вы можете вставить этот код в synchronized блоке с замком:

private Object calendarLock; --Class attribute 

public void repeatedlyPrintTheTime() { 
    final Handler handler = new Handler(); 

    mR = new Runnable() { 
     public void run() { 
      synchronized(calendarLock) { 
       System.out.println("Time 1 is " + mCalendar.getTime().toString()); 
       System.out.println("Time 2 is " + GregorianCalendar.getInstance().getTime().toString()); 
       handler.postDelayed(this, 1000); 
      } 
     } 
    }; 

    handler.postDelayed(mR, 1000); 
}