blob: d728b8c588ec7667bb10b7cdee9409ff9e18fa80 [file] [log] [blame] [raw]
package li.cil.oc.util
import java.util.Calendar
import java.util.GregorianCalendar
import java.util.TimeZone
import scala.collection.mutable
object GameTimeFormatter {
// Locale? What locale? Seriously though, since this would depend on the
// server's locale I think it makes more sense to keep it English always.
private val weekDays = Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")
private val shortWeekDays = Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
private val months = Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December")
private val shortMonths = Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")
private val amPm = Array("AM", "PM")
class DateTime(val year: Int, val month: Int, val day: Int,
val weekDay: Int, val yearDay: Int,
val hour: Int, val minute: Int, val second: Int)
// See http://www.cplusplus.com/reference/ctime/strftime/
private val specifiers: Map[Char, (DateTime) => String] = Map(
'a' -> (t => shortWeekDays(t.weekDay - 1)),
'A' -> (t => weekDays(t.weekDay - 1)),
'b' -> (t => shortMonths(t.month - 1)),
'B' -> (t => months(t.month - 1)),
'c' -> (t => format("%a %b %e %H:%M:%S %Y", t)),
'C' -> (t => f"${t.year / 100}%02d"),
'd' -> (t => f"${t.day}%02d"),
'D' -> (t => format("%m/%d/%y", t)),
'e' -> (t => f"${t.day}%2d"),
'F' -> (t => format("%Y-%m-%d", t)),
//'g' -> (t => ""),
//'G' -> (t => ""),
'h' -> (t => format("%b", t)),
'H' -> (t => f"${t.hour}%02d"),
'I' -> (t => f"${(t.hour + 11) % 12 + 1}%02d"),
'j' -> (t => f"${t.yearDay}%03d"),
'm' -> (t => f"${t.month}%02d"),
'M' -> (t => f"${t.minute}%02d"),
'n' -> (t => "\n"),
'p' -> (t => amPm(if (t.hour < 12) 0 else 1)),
'r' -> (t => format("%I:%M:%S %p", t)),
'R' -> (t => format("%H:%M", t)),
'S' -> (t => f"${t.second}%02d"),
't' -> (t => "\t"),
'T' -> (t => format("%H:%M:%S", t)),
//'u' -> (t => ""),
//'U' -> (t => ""),
//'V' -> (t => ""),
'w' -> (t => s"${t.weekDay - 1}"),
//'W' -> (t => ""),
'x' -> (t => format("%D", t)),
'X' -> (t => format("%T", t)),
'y' -> (t => f"${t.year % 100}%02d"),
'Y' -> (t => f"${t.year}%04d"),
//'z' -> (t => ""),
//'Z' -> (t => ""),
'%' -> (t => "%")
)
def parse(time: Double) = {
val calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"))
calendar.setTimeInMillis((time * 1000).toLong)
new DateTime(
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH) + 1,
calendar.get(Calendar.DAY_OF_MONTH),
calendar.get(Calendar.DAY_OF_WEEK),
calendar.get(Calendar.DAY_OF_YEAR),
calendar.get(Calendar.HOUR_OF_DAY),
calendar.get(Calendar.MINUTE),
calendar.get(Calendar.SECOND))
}
def format(format: String, time: DateTime) = {
val result = new mutable.StringBuilder()
val iterator = format.iterator
while (iterator.hasNext) {
iterator.next() match {
case '%' if iterator.hasNext =>
specifiers.get(iterator.next()) match {
case Some(specifier) => result.append(specifier(time))
case _ =>
}
case c => result.append(c)
}
}
result.toString()
}
def mktime(year: Int, mon: Int, mday: Int, hour: Int, min: Int, sec: Int): Option[Int] = {
val calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"))
calendar.set(Calendar.YEAR, year)
calendar.set(Calendar.MONTH, mon - 1)
calendar.set(Calendar.DAY_OF_MONTH, mday)
calendar.set(Calendar.HOUR_OF_DAY, hour)
calendar.set(Calendar.MINUTE, min)
calendar.set(Calendar.SECOND, sec)
Option((calendar.getTimeInMillis / 1000).toInt)
}
}