Java od wersji 5.0 zawiera możliwość definiowania typów wyliczeniowych. Jednym z praktycznych przykładów zastosowania tego mechanizmu jest TimeUnit. Enum ten służy do konwertowania jednostek czasu pomiędzy różnymi wielkościami - na przykład z minut na sekundy.

[sourcecode lang=“java”] import java.util.concurrent.TimeUnit; // … TimeUnit.MINUTES.toSeconds(55); [/sourcecode]

Fajna sprawa - jeśli mamy do czynienia z konwersjami. Inny pożyteczny przykład to przekazywanie czasu jako argumentu: [sourcecode lang=“java”] package org.code_house.concurrent;

import java.util.Date; import java.util.concurrent.TimeUnit;

public class Lock { void lock(TimeUnit unit, long value) throws InterruptedException { Thread.sleep(unit.toMillis(value)); }

public static void main(String[] args) throws Exception { System.out.println(“before " + new Date());

new Lock().lock(TimeUnit.SECONDS, 30);

System.out.println(“after " + new Date()); }

} [/sourcecode] Programista, który używa takiej klasy nie musi się więc przejmować konwertowaniem jednostek na milisekundy, które są podstawą do wywołania metody Thread.sleep.

TimeUnit obsługuje następujące wielkości:

  • nanosekundy
  • mikrosekundy
  • milisekundy
  • sekundy
  • minuty
  • godziny
  • dni

Posługując się kodem z Javy postanowiłem sobie przypomnieć nieco PHP i napisałem wersję tego typu wyliczeniowego dla PHP: [sourcecode lang=“php”]<?php // namespace org\code_house\util; /\\ \* A simple class for converting between time units. \* \* @author Łukasz Dywicki luke@code-house.org */ class TimeUnit {

/\\ \* Nanoseconds. */ const NANOS = 0;

/\\ \* Microseconds. */ const MICROS = 1;

/\\ \* Milliseconds */ const MILLIS = 2;

/\\ \* Seconds. */ const SECONDS = 3;

/\\ \* Minutes. */ const MINUTES = 4;

/\\ \* Hours. */ const HOURS = 5;

/\\ \* Days. */ const DAYS = 6;

/\\ \* Conversion table between time units. \* @var array */ private static $modifiers = array( self::NANOS => 0.000000001, self::MICROS => 0.000001, self::MILLIS => 0.001, self::SECONDS => 1, self::MINUTES => 60, self::HOURS => 3600, self::DAYS => 86400, );

/\\ \* Constructs new time unit. \* \* @param $type TimeUnit Time unit base. */ public function __construct($type) { if ($type < TimeUnit::NANOS || $type > TimeUnit::DAYS) { throw new RuntimeException(‘Time unit base is out of range’); } $this->type = $type; }

public function toNanos($value) { return TimeUnit::convert($this->type, $value, TimeUnit::NANOS); }

public function toMicros($value) { return TimeUnit::convert($this->type, $value, TimeUnit::MICROS); }

public function toMilis($value) { return TimeUnit::convert($this->type, $value, TimeUnit::MILLIS); }

public function toSeconds($value) { return TimeUnit::convert($this->type, $value, TimeUnit::SECONDS); }

public function toMinutes($value) { return TimeUnit::convert($this->type, $value, TimeUnit::MINUTES); }

public function toHours($value) { return TimeUnit::convert($this->type, $value, TimeUnit::HOURS); }

public function toDays($value) { return TimeUnit::convert($this->type, $value, TimeUnit::DAYS); }

/\\ \* Convert method. \* \* @param $from Time unit \* @param $value Number of values. \* @param $to Time unit \* @return decimal */ private final static function convert($from, $value, $to) { if ($from === $to) { return $value; }

$value *= self::$modifiers[$from]; return $value / self::$modifiers[$to]; } }

// przykład użycia $unit = new TimeUnit(TimeUnit::SECONDS); echo $unit->toMinutes(60) .”\n”;

$unit = new TimeUnit(TimeUnit::HOURS); echo $unit->toMinutes(1) ."\n";

?>[/sourcecode]

Niestety brak pól z modyfikatorami public static final w PHP uniemożliwił zastosowanie choćby czegoś podobnego do typu wyliczeniowego.. Kod klasy dla PHP jest wolnodostępny. :-)